Mercurial > pub > Impl
diff Lib/Deployment/Batch.pm @ 0:03e58a454b20
Создан репозитарий
author | Sergey |
---|---|
date | Tue, 14 Jul 2009 12:54:37 +0400 |
parents | |
children | 16ada169ca75 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/Deployment/Batch.pm Tue Jul 14 12:54:37 2009 +0400 @@ -0,0 +1,129 @@ +use strict; + +package Deployment::Batch; + +require URI::file; + +my %Provider; +our $AUTOLOAD; + +our %Dirs; +our %Context; + +$Context{DieOnError} = 1; # dies by default if the action fails to run + +our @history; + +# make all inc absolute; +@INC = map { URI::file->new_abs($_)->dir } @INC; + +sub AUTOLOAD { + my $method = $AUTOLOAD; + + shift if $_[0] eq __PACKAGE__; + + my $class = "$method"; + + if (not $Provider{$method}) { + (my $file = "$class.pm") =~ s/::/\//g; + require $file; + $Provider{$method} = 1; + } + + my $action = $class->new(@_); + + push @history,$action; + if ($Context{Immediate}) { + $action->_Run or ($Context{DieOnError} ? die $_->LastError : return 0); + } + + return 1; +} + +sub SetDir { + shift if $_[0] eq __PACKAGE__; + my ($name,$dir) = @_; + + $Dirs{$name} = URI::file->new_abs($dir); +} + +sub Rollback { + return 1 if not @history; + + $_->_Rollback or $_->Log('Rollback: ',$_->LastError) foreach reverse grep { $_->isProcessed } @history; + undef @history; + return 1; +} + +sub Commit { + return 1 if not @history; + + # during commit we are in the immediate mode + local $Context{Immediate} = 1; + + $_->_Run or $_->Log('Run: ',$_->LastError) and Rollback() and last foreach grep { not $_->isProcessed } @history; + return 0 if not @history; + undef @history; + return 1; +} + +sub DoPackage { + shift if $_[0] eq __PACKAGE__; + my ($package,$inline) = @_; + + Log( "The package is required" ) and return 0 if not $package; + Log( "Processing $package" ); + my $t0 = [Time::HiRes::gettimeofday]; + + if ($inline and $inline eq 'inline') { + $inline = 1; + } else { + $inline = 0; + } + + if (not $inline) { + my %copy = %Context; + local %Context = %copy; + local @history = (); + $Context{Package} = $Context{PackageDir} ? URI::file->new($package)->abs($Context{PackageDir}) : URI::file->new_abs($package); + $Context{PackageDir} = URI::file->new('./')->abs($Context{Package}); + + undef $@; + do $package or Log("$package: ". ($@ || $!)) and Rollback() and Log("Rollback completed in ",Time::HiRes::tv_interval($t0)," s") and return 0; + + Log("Commiting"); + Commit or Log("Commit failed in ",Time::HiRes::tv_interval($t0)) and return 0; + Log("Commit successful in ",Time::HiRes::tv_interval($t0),' s'); + return 1; + } else { + local $Context{Package} = $Context{PackageDir} ? URI::file->new($package)->abs($Context{PackageDir}) : URI::file->new_abs($package); + local $Context{PackageDir} = URI::file->new('./')->abs($Context{Package}); + + do $package or Log("$package: ". ($@ || $!)) and Rollback() and Log("Rollback completed in ",Time::HiRes::tv_interval($t0),' s') and return 0; + + return 1; + } +} + +sub Dir { + shift if $_[0] eq __PACKAGE__; + my $uriDir = $Dirs{$_[0]} or die "No such directory entry $_[0]"; + shift; + return $uriDir->dir.join('/',@_); +} + +sub PackageDir { + shift if $_[0] eq __PACKAGE__; + return $Context{PackageDir}->dir.join('/',@_); +} + +sub Log { + shift if $_[0] eq __PACKAGE__; + + if (my $hout = $Context{LogOutput}) { + print $hout 'DoPackage: ',@_,"\n"; + } + 1; +} + +1; \ No newline at end of file