Skip to content

Commit

Permalink
Item10188: post-commit hook was a stupid idea. It is way too long. Re…
Browse files Browse the repository at this point in the history
…-write using a cron job, a state file and Git::Repository and Net::GitHub

git-svn-id: http://svn.foswiki.org/trunk@11841 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
OlivierRaginel authored and OlivierRaginel committed Jun 4, 2011
1 parent 800b07f commit 8b91f84
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 33 deletions.
164 changes: 133 additions & 31 deletions core/tools/develop/hooks/git-svn-split.pl
@@ -1,57 +1,159 @@
#!/usr/bin/perl -wT
#!/usr/bin/perl -w
# --
# send latest Subversion commit to github, split per module
# --
# Ugly... should use some git perl module at least...

use strict;
use warnings;
use Git::Repository;

my $verbose = 1; # 1 for debug
my $repository = shift || '/home/svn/nextwiki';
my $statefile = '/home/git/last-git-split';
my $lastrev = shift;
chomp( $lastrev = `/usr/local/bin/svnlook youngest $repository` )
unless $lastrev;

my $repository = shift;
my $revision = shift;
# Read up to where has already been processed
sub getLastProcessedRev {
my $firstrev = 11813;
if ( -f $statefile ) {
open( my $state, '<', $statefile ) or die "Can't open $statefile: $!";
chomp( $firstrev = <$state> );
close $state;
}
return $firstrev;
}

open( my $svnlook, '-|',
"/usr/local/bin/svnlook dirs-changed -r $revision $repository" )
or die "Can't open svn look pipe: $!";
# Update the state file with the latest processed revision
sub setLastProcessedRev {
my $lastrev = shift or return;
open( my $state, '>', $statefile ) or die "Can't open $statefile: $!";
print $state $lastrev . "\n";
close $state;
}

my %modifiedPlugin;
# Build modified plugins per branch
sub buildModifiedList {
my $revision = shift;
my $modifiedPlugin = shift; # hash ref built recursively
return unless $revision;
open( my $svnlook, '-|',
"/usr/local/bin/svnlook dirs-changed -r $revision $repository" )
or die "Can't open svn look pipe: $!";

while (<$svnlook>) {
if ( m#^(trunk)/([^/]*)/# || m#^(?:branches|tags)/([^/]*)/([^/]*)/# ) {
my $branch = $1;
$modifiedPlugin{$2}++;
while (<$svnlook>) {
if ( m#^(trunk)/([^/]*)/# || m#^(?:branches|tags)/([^/]*)/([^/]*)/# ) {
my $plugin = $2;
my $branch = $1 || 'master';
for ($branch) {
s/trunk/master/;
}
$modifiedPlugin->{$plugin}->{$branch}++;
}
}
close $svnlook;
}
close $svnlook;

chdir "/usr/home/git/_allDeveloper";
for my $module ( keys %modifiedPlugin ) {
unless ( -d $module ) {
system "git submodule add git\@github.com:foswiki/$module.git $module";
}
unless ( -d "$module/.git/svn" ) {
open( my $gitconfig, '<', "$module/.git/config" )
or die "Can't open $module .git/config";
sub getGitHubToken {
my $secfile = '/home/git/.token';
open( my $tokenfh, '<', $secfile )
or die "Cannot get GitHub token from $secfile: $!";
chomp( my $token = <$tokenfh> );
die "Invalid token: $token" unless $token =~ /[0-9a-f]/i;
return $token;
}

# Create the submodule on GitHub, and add it in the master repo
sub createSubModule {
my $masterRepo = shift;
my $module = shift;

warn "Creating github module $module..." if $verbose;
require Net::GitHub;
my $token = getGitHubToken;
my $github = Net::GitHub->new(
owner => 'foswiki',
repo => $module,
login => 'foswiki',
token => $token,
);
$github->repos->create(
$module,
"Foswiki module $module",
"http://foswiki.org/Extensions/$module", 1
);
warn
"\tAdding: git submodule add git\@github.com:foswiki/$module.git $module"
if $verbose;

# Cannot use Git::Repository here because submodule add doesn't like overriding GIT_WORK_TREE
# BooK provided a fix, which I will test tomorrow:
# https://github.com/book/System-Command/commit/1aa35fef43a2178e36d2f46cc3385d5b345ab237
system( 'cd '
. $masterRepo->work_tree()
. " && git submodule add git\@github.com:foswiki/$module.git $module"
);
}

# Create the subversion links from one submodule to foswiki.org
sub getSubModule {
my $masterRepo = shift;
my $module = shift;

my $moduleDir = $masterRepo->work_tree() . '/' . $module;
my $submodule = eval { Git::Repository->new( work_tree => $moduleDir ) };
createSubModule( $masterRepo, $module ) unless $submodule;
$submodule = Git::Repository->new( work_tree => $moduleDir );

# Ensute subversion configuration is consistent
unless ( eval { $submodule->run( svn => "log" ) } ) {
my $gitconfig = $submodule->git_dir() . '/config';
open( my $config, '<', $gitconfig )
or die "Can't open $module .git/config ($gitconfig): $!";
my $gitsvn = 0;
while (<$gitconfig>) {
while (<$config>) {
$gitsvn++ if /svn-remote/;
}
close $config;
unless ($gitsvn) {
open( my $gitconfig, '>>', "$module/.git/config" )
or die "Can't open $module .git/config";
print $gitconfig <<"END_CONFIG";
open( my $config, '>>', $gitconfig )
or die "Can't open $module .git/config ($gitconfig): $!";
print $config <<"END_CONFIG";
[svn-remote "svn"]
url = http://svn.foswiki.org
fetch = trunk/$module:refs/remotes/trunk
branches = branches/*/$module:refs/remotes/*
tags = tags/*/$module:refs/remotes/tags/*
END_CONFIG
system(
"cd $module && git update-ref refs/remotes/trunk origin/master && git svn fetch"
);
$submodule->run( svn => 'fetch' );
}
}
system("cd $module && git svn rebase && git push --all");
return $submodule;
}

my %modifiedPlugin;
my $startrev = getLastProcessedRev() + 1;
warn "F:$startrev L:$lastrev" if $verbose;
for my $revision ( $startrev .. $lastrev ) {
buildModifiedList( $revision, \%modifiedPlugin );
}

exit unless keys %modifiedPlugin;

#my $masterRepo = Git::Repository->new( work_tree => "/usr/home/git/_allDeveloper" );
my $masterRepo =
Git::Repository->new( git_dir => "/usr/home/git/_allDeveloper/.git" );
for my $module ( sort keys %modifiedPlugin ) {
my $submodule = getSubModule( $masterRepo, $module );
for my $branch ( sort keys %{ $modifiedPlugin{$module} } ) {
warn "Updating module $module, branch $branch" if $verbose;
$submodule->run( checkout => $branch );
$submodule->run( svn => 'rebase' );
}
$submodule->run( push => '--all' );
}

system("git commit -am 'Pushed latest revision' && git push --all");
$masterRepo->run( commit => '-am', "Pushed latest revision $lastrev" );
$masterRepo->run( push => '--all' );

setLastProcessedRev($lastrev);
2 changes: 0 additions & 2 deletions core/tools/develop/hooks/post-commit
Expand Up @@ -12,8 +12,6 @@ author=`/usr/local/bin/svnlook author -r $REV $REPOS`

# First send out the commit email
./commit-email.pl --from svn@foswiki.org -s "[SVN] $author" "$REPOS" "$REV" foswiki-svn@lists.sourceforge.net
# Then push changes to git, per split repo (global is cron'ed every 15 min)
sudo -u git /home/svn/supportscripts/git-svn-split.pl "$REPOS" "$REV" &
# Tweet about the commit - is this still useful?
/home/svn/supportscripts/twitter.pl
# Update the RSS feed about the subversion history
Expand Down

0 comments on commit 8b91f84

Please sign in to comment.