Create a gist now

Instantly share code, notes, and snippets.

The update.pl script for updating multiple git repositories.
#!/usr/bin/perl
use Cwd;
use Time::Local;
use Getopt::Std;
getopts('s:f:a:h');
if( $opt_h ) {
die( "skip: -s\n"
. "from: -f\n"
. "after: -a\n" );
}
my $start;
unless( $opt_f ) {
$start = "";
} else {
$start = $opt_f;
}
my $skip = 0;
if( $opt_s ) {
$skip = $opt_s;
}
if( $opt_a ) {
$start = $opt_a;
$skip = $opt_a;
}
$start =~ s#/##g;
$skip =~ s#/##g;
my $home=getcwd();
# projects=`find . -maxdepth 2 -name .svn -type d | sed -e 's#./##' | sed -e 's#/.svn##'`
$svn="/usr/bin/svn";
$svn_projects="";
# projects=`find . -maxdepth 2 -name .git -type d | sed -e 's#./##' | sed -e 's#/.git##'`
$git="/usr/local/bin/git";
while(<DATA>) {
chomp;
if( $_ =~ /^#/ ) {
next;
}
$git_projects .= $_ . " ";
}
#
# Do your thing..
#
print "\n] svn\n";
@dirs = skip(split(" ", $svn_projects));
foreach $dir (@dirs) {
if( ! chdir "$home/$dir" ) {
die "Directory $home/$dir does NOT exist!\n\n";
}
print "\n";
my $pid = open( INFO, "$svn info |" )
|| die "Unable to execute '$svn info': $!\n\n";
my $branch = "";
my $root = "";
while(<INFO>) {
chomp;
if( $_ =~ /^Repository Root/ ) {
$root = $_;
$root =~ s/Repository Root: //;
next;
}
if( $_ =~ /^URL/ ) {
$branch = $_;
$branch =~ s/URL: //;
next;
}
if( $root && $branch ) {
last;
}
}
$branch =~ s#$root/##;
if( $branch =~ /trunk/ ) {
$branch = "trunk";
} elsif( $branch =~ m#(tags/[^\/]+)# ) {
$branch = $1;
}
print "[$branch] : $dir\n";
print "-------------------------------------------------------------\n";
open( STATUS, "$svn status |" )
|| die "Unable to execute '$svn status': $!\n\n";
my $changes = 0;
while(<STATUS>) {
unless( m/(\.(classpath|project|settings))|target$/ ) {
++$changes;
}
}
if( $changes < 4 ) {
print "! (Changes)\n";
} else {
die "!!! Too many changes [$changes] present!\n\n";
}
open(UPDATE, "$svn update |")
|| die "Unable to execute '$svn update': $!\n\n";
while(<UPDATE>) {
print $_;
}
print "-- cleanup --\n";
sleep 1;
system("$svn cleanup");
if( ($err = $?) != 0 ) {
die "!!! Cleanup threw error: $err\n\n";
}
waitUp(5);
close(INFO);
close(STATUS);
close(UPDATE);
}
print "\n] git\n";
@dirs = skip(split(" ", $git_projects));
foreach $dir (@dirs) {
if( ! chdir "$home/$dir" ) {
die "Directory $home/$dir does NOT exist!\n\n";
}
print "\n";
open(BRANCH, "$git branch |" )
|| die "Unable to execute '$git branch': $!\n\n";
my $branch = "";
while(<BRANCH>) {
if( /^\* (\S.+)/ ) {
$branch = $1;
}
}
print "[$branch] : $dir\n";
call("$git remote update");
print "-------------------------------------------------------------\n";
if( $branch !~ /^master$/ ) {
die "!!! $branch\n\n";
}
open( CHANGE , "$git status -s |" )
|| die "Unable to open '$git status -s': $!\n\n";
my $changes = 0;
while(<CHANGE>) {
print "[modified!] $_";
++$changes;
}
if( $changes ) {
die "!!! Please stash changes first.\n\n";;
}
call("$git merge --ff origin/master");
open(STATUS, "$git status |")
|| die "Unable to open '$git status': $!\n\n";
while(<STATUS>) {
print;
}
print "-- GC --\n";
sleep 1;
call("$git prune");
call("$git gc");
waitUp(5);
close(BRANCH);
close(CHANGE);
close(STATUS);
}
sub skip {
my @dirs = @_;
unless( $start ) {
return @dirs;
}
while( @dirs > 0 ) {
$dir = shift @dirs;
if( $dir =~ m#^$start/?$# ) {
$start="";
unshift( @dirs, $dir );
last;
} else {
print "Skipping $dir\n";
}
}
if( $skip ) {
foreach $skip (split(", *", $skip)) {
for( $i = 0; $i < $#dirs; ++$i ) {
if( $dirs[$i] =~ m/^$skip$/ ) {
splice( @dirs, $i, 1 );
print "Intentionally skipping $skip\n";
}
}
}
}
print "---\n";
return @dirs;
}
sub waitUp {
print "===\n";
my $wait = shift(@_);
unless( $wait ) {
$wait = 30;
}
my @in5 = (localtime(time+$wait))[0..2];
for( $i = 0; $i < 3; ++$i ) {
if( $in5[$i] < 10 ) {
$in5[$i] = "0" . $in5[$i];
}
}
print "-> $in5[2]:$in5[1]:$in5[0]\n";
sleep $wait;
}
sub call {
my $cmd = join(" ", @_);
system($cmd);
if( $? != 0 ) {
die "Unable to call '$cmd': $?\n\n";
}
}
# In order to have a repository skipped, put a "#" character in front of it, like this:
# __DATA__
# fluming
# #old-fluming
# goobel-pah
# The "old-fluming" repo will be skipped
__DATA__
# -- drools/jbpm/kie core
jbpm
drools
droolsjbpm-build-bootstrap
droolsjbpm-integration
droolsjbpm-knowledge
jbpm-simulation
jbpm-examples
kie-commons
product
PFP
#
# -- dashboard/bam/designer/console/form-builder
uberfire
dashboard-builder
jbpm-console-ng
jbpm-designer
drools-wb
kie-wb-common
kie-wb-distributions
#
# -- arquillian
arquillian-container-glassfish
arquillian-container-tomcat
arquillian-container-was
arquillian-examples
arquillian-showcase
#
# -- other
camel
camel-cdi-examples
hibernate-orm
hornetq
hornetq-version-tests
jboss-as-quickstart
resteasy
wildfly
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment