Changeset 3707 for lang/perl/Archer
- Timestamp:
- 12/28/07 11:23:49 (11 months ago)
- Location:
- lang/perl/Archer
- Files:
-
- 2 added
- 5 modified
-
archer.pl (modified) (2 diffs)
-
assets/kwalify/schema.yaml (modified) (1 diff)
-
assets/recipe (added)
-
assets/recipe/Deploy (added)
-
lib/Archer.pm (modified) (6 diffs)
-
lib/Archer/Plugin.pm (modified) (3 diffs)
-
lib/Archer/Plugin/Exec.pm (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
lang/perl/Archer/archer.pl
r3683 r3707 7 7 use FindBin (); 8 8 use Path::Class; 9 use File::Util; 10 use Cwd; 9 11 10 use lib dir( $FindBin::RealBin, 'lib')->stringify;12 use lib dir( $FindBin::RealBin, 'lib' )->stringify; 11 13 12 14 use Archer; … … 14 16 my $argv_str = "@ARGV"; 15 17 my $fork_num = 1; 16 my $config = file($FindBin::RealBin, 'config.yaml')->stringify;18 my $config = file( $FindBin::RealBin, 'config.yaml' )->stringify; 17 19 Getopt::Long::GetOptions( 18 '--para=i' => \$fork_num, 19 '--dry-run' => \my $dry_run_fg, 20 '--skip=s' => \my $skips, 21 '--shell', => \my $shell, 22 '--man' => \my $man, 23 '--config=s' => \$config, 24 ) 25 or pod2usage(2); 26 Getopt::Long::Configure("bundling"); # allows -p 27 pod2usage(-verbose => 2) if $man; 28 pod2usage(2) unless @ARGV; 20 '--para=i' => \$fork_num, 21 '--dry-run' => \my $dry_run_fg, 22 '--skip=s' => \my $skips, 23 '--shell', => \my $shell, 24 '--man' => \my $man, 25 '--config=s' => \$config, 26 '--write-config' => \my $wc, 27 ) or pod2usage( 2 ); 28 Getopt::Long::Configure( "bundling" ); # allows -p 29 pod2usage( -verbose => 2 ) if $man; 29 30 30 for my $proj (@ARGV) { 31 if ( !@ARGV ) { 32 33 # name of the current dir, will be the project name 34 my $dir = getcwd; 35 my $f = File::Util->new; 36 my $project = $f->strip_path( $dir ); 37 $config = '.archer.yaml'; 38 if ( $f->existent( $config ) ) { 39 Archer->new( 40 { project => $project, 41 dry_run_fg => $dry_run_fg, 42 parallel_num => $fork_num, 43 skips => +{ map { $_ => 1 } split /,/, ( $skips || '' ) }, 44 config_yaml => $config, 45 argv_str => $argv_str, 46 shell => $shell, 47 } 48 )->run; 49 exit; 50 } 51 else { 52 Archer->new( 53 { project => $project, 54 dry_run_fg => $dry_run_fg, 55 config_yaml => $config, 56 write_config => $wc, 57 } 58 )->run; 59 exit; 60 } 61 pod2usage( 2 ) unless @ARGV; 62 } 63 64 for my $proj ( @ARGV ) { 31 65 Archer->new( 32 { 33 project => $proj,34 dry_run_fg => $dry_run_fg,35 parallel_num => $fork_num,36 skips => +{ map { $_ => 1 } split /,/, ($skips || '')},37 config_yaml => $config,38 argv_str => $argv_str,39 shell => $shell,66 { project => $proj, 67 dry_run_fg => $dry_run_fg, 68 parallel_num => $fork_num, 69 skips => +{ map { $_ => 1 } split /,/, ( $skips || '' ) }, 70 config_yaml => $config, 71 argv_str => $argv_str, 72 shell => $shell, 73 write_config => $wc, 40 74 } 41 75 )->run; -
lang/perl/Archer/assets/kwalify/schema.yaml
r3696 r3707 15 15 name: dest_dir 16 16 desc: dest. directory 17 type: str 18 "recipe": 19 name: recipe 20 desc: additional recipe path 17 21 type: str 18 22 "log": -
lang/perl/Archer/lib/Archer.pm
r3706 r3707 11 11 my $context; 12 12 sub context { $context } 13 13 14 sub set_context { 14 my ( $class, $c) = @_;15 my ( $class, $c ) = @_; 15 16 $context = $c; 16 17 } 17 18 18 19 sub new { 19 my ( $class, $opts) = @_;20 my $self = bless { %$opts}, $class;20 my ( $class, $opts ) = @_; 21 my $self = bless { %$opts }, $class; 21 22 22 my $config_loader = Archer::ConfigLoader->new; 23 $self->{config} = $config_loader->load($opts->{config_yaml}); 24 $self->{config}->{global}->{log} ||= { level => 'debug' }; 23 if ( !$$opts{ write_config } ) { 24 my $config_loader = Archer::ConfigLoader->new; 25 $self->{ config } = $config_loader->load( $opts->{ config_yaml } ); 26 } 27 $self->{ config }->{ global }->{ log } ||= { level => 'debug' }; 25 28 26 Archer->set_context( $self);29 Archer->set_context( $self ); 27 30 28 31 return $self; … … 30 33 31 34 sub run { 32 my ( $self, ) = @_;35 my ( $self, ) = @_; 33 36 34 if ($self->{shell}) { 37 if ( $self->{ shell } ) { 38 35 39 # TODO: role support 36 40 require Archer::Shell; 37 my @servers = map { @{$_} } values %{ $context->{config}->{projects}->{$self->{project}} }; 41 my @servers 42 = map { @{ $_ } } 43 values 44 %{ $context->{ config }->{ projects }->{ $self->{ project } } }; 38 45 my $shell = Archer::Shell->new( 39 46 { context => $self, 40 config => $self->{ config},47 config => $self->{ config }, 41 48 servers => \@servers, 42 49 } … … 44 51 45 52 $shell->run_loop; 46 } else { 47 $self->run_hook('init'); 53 } 54 elsif ( $self->{ write_config } ) { 55 require Archer::Util; 56 my $util = Archer::Util->new; 57 $util->templatize( $self ); 58 } 59 else { 60 $self->run_hook( 'init' ); 48 61 49 62 $self->run_process; 50 63 51 $self->run_hook( 'finalize');64 $self->run_hook( 'finalize' ); 52 65 } 53 66 } 54 67 55 68 sub run_hook { 56 my ( $self, $hook, $args) = @_;69 my ( $self, $hook, $args ) = @_; 57 70 $args ||= {}; 58 71 59 $self->log( 'info' => "run hook $hook");60 for my $plugin ( @{ $self->{config}->{tasks}->{$hook} }) {61 if ( $self->{skips}->{$plugin->{name}}) {62 $self->log( info => "skipped: $plugin->{name}");72 $self->log( 'info' => "run hook $hook" ); 73 for my $plugin ( @{ $self->{ config }->{ tasks }->{ $hook } } ) { 74 if ( $self->{ skips }->{ $plugin->{ name } } ) { 75 $self->log( info => "skipped: $plugin->{name}" ); 63 76 next; 64 77 } 65 78 66 if ( $plugin->{role} && $plugin->{role} ne $args->{role} ) { 67 $self->log(debug => "skip $args->{server}. because $plugin->{role} ne $args->{role}"); 79 if ( $plugin->{ role } && $plugin->{ role } ne $args->{ role } ) { 80 $self->log( debug => 81 "skip $args->{server}. because $plugin->{role} ne $args->{role}" 82 ); 68 83 next; 69 84 } 70 85 71 86 my $class = "Archer::Plugin::$plugin->{module}"; 72 $self->log( 'debug' => "load $class");87 $self->log( 'debug' => "load $class" ); 73 88 $class->use or die $@; 74 89 75 $self->log( 'info' => "run $class");90 $self->log( 'info' => "run $class" ); 76 91 $class->new( 77 { config => $plugin->{config}, project => $self->{project}, %$args } ) 78 ->run( $self, $args ); 92 { config => $plugin->{ config }, 93 project => $self->{ project }, 94 %$args 95 } 96 )->run( $self, $args ); 79 97 80 print "\n\n"; # for debug.98 print "\n\n"; # for debug. 81 99 } 82 100 } 83 101 84 102 sub run_process { 85 my ( $self) = @_;103 my ( $self ) = @_; 86 104 87 my $parallel = $self->{config}->{global}->{parallel} || 'Archer::Parallel::ForkManager'; 105 my $parallel = $self->{ config }->{ global }->{ parallel } 106 || 'Archer::Parallel::ForkManager'; 88 107 $parallel->use or die $@; 89 108 90 109 # construct elements 91 my $server_tree = $self->{config}->{projects}->{$self->{project}}; 110 # this one doesn't work for me 111 # my $server_tree = $self->{config}->{projects}->{$self->{project}}; 112 # but this one do 113 my $server_tree = $self->{ config }->{ projects }; 114 92 115 my @elems; 93 while ( my ($role, $servers) = each %$server_tree) {94 for my $server ( @$servers) {95 push @elems, { server => $server, role => $role};116 while ( my ( $role, $servers ) = each %$server_tree ) { 117 for my $server ( @$servers ) { 118 push @elems, { server => $server, role => $role }; 96 119 } 97 120 } 98 99 $self->log(debug => "run parallel : $self->{parallel_num}"); 121 $self->log( debug => "run parallel : $self->{parallel_num}" ); 100 122 my $manager = $parallel->new; 101 123 $manager->run( 102 { elems => \@elems,124 { elems => \@elems, 103 125 callback => sub { 104 126 my $args = shift; 105 127 $self->run_hook( 'process', $args ); 106 },107 num => $self->{ parallel_num},128 }, 129 num => $self->{ parallel_num }, 108 130 } 109 131 ); … … 111 133 112 134 sub bootstrap { 113 my ( $class, $opts) = @_;135 my ( $class, $opts ) = @_; 114 136 115 my $self = $class->new( $opts);137 my $self = $class->new( $opts ); 116 138 $self->run; 117 139 return $self; … … 122 144 my ( $self, $level, $msg, %opt ) = @_; 123 145 124 return unless $self->should_log( $level);146 return unless $self->should_log( $level ); 125 147 126 148 # hack to get the original caller as Plugin or Rule 127 149 # from plagger. 128 my $caller = $opt{ caller};129 unless ( $caller) {150 my $caller = $opt{ caller }; 151 unless ( $caller ) { 130 152 my $i = 0; 131 while ( my $c = caller($i++)) {153 while ( my $c = caller( $i++ ) ) { 132 154 last if $c !~ /Plugin|Rule/; 133 155 $caller = $c; 134 156 } 135 $caller ||= caller( 0);157 $caller ||= caller( 0 ); 136 158 } 137 159 … … 147 169 148 170 sub should_log { 149 my ($self, $level) = @_;171 my ( $self, $level ) = @_; 150 172 151 $levels{$level} >= $levels{ $self->{config}->{global}->{log}->{level} }; 173 $levels{ $level } 174 >= $levels{ $self->{ config }->{ global }->{ log }->{ level } }; 152 175 } 153 176 -
lang/perl/Archer/lib/Archer/Plugin.pm
r3700 r3707 9 9 10 10 sub new { 11 my ( $class, $args) = @_;12 bless { %$args}, $class;11 my ( $class, $args ) = @_; 12 bless { %$args }, $class; 13 13 } 14 14 15 15 sub log { 16 16 my $self = shift; 17 Archer->context->log( @_);17 Archer->context->log( @_ ); 18 18 } 19 19 20 20 sub templatize { 21 my ( $self, $cmd) = @_;21 my ( $self, $cmd ) = @_; 22 22 23 23 my $vars = { 24 config => $self->{config},25 project => $self->{project},24 config => $self->{ config }, 25 project => $self->{ project }, 26 26 l_project => $self->l_project, 27 work_dir => Archer->context->{config}->{global}->{work_dir},28 dest_dir => Archer->context->{config}->{global}->{dest_dir},29 server => $self->{server},30 user => $ENV{USER},27 work_dir => Archer->context->{ config }->{ global }->{ work_dir }, 28 dest_dir => Archer->context->{ config }->{ global }->{ dest_dir }, 29 server => $self->{ server }, 30 user => $ENV{ USER }, 31 31 }; 32 32 33 33 my $tt = Template->new; 34 $tt->process( \$cmd, $vars, \my $out ) or $self->log('error' => 'Tmplate Error: ' . $tt->error); 34 $tt->process( \$cmd, $vars, \my $out ) 35 or $self->log( 'error' => 'Template Error: ' . $tt->error ); 35 36 36 37 $out; … … 38 39 39 40 sub detach { 40 my ( $self, $msg) = @_;41 my ( $self, $msg ) = @_; 41 42 42 43 croak "$msg\n"; … … 45 46 # FIXME: so bad...following method... 46 47 sub l_project { 47 my ( $self, ) = @_;48 my ( $self, ) = @_; 48 49 49 my $work_dir = Archer->context->{ config}->{global}->{work_dir};50 my $work_dir = Archer->context->{ config }->{ global }->{ work_dir }; 50 51 51 my $lc = String::CamelCase::decamelize( $self->{project} ); 52 if ( -e file( $work_dir, $self->{project}, $lc ) 53 ->stringify ) 54 { 52 my $lc = String::CamelCase::decamelize( $self->{ project } ); 53 if ( -e file( $work_dir, $self->{ project }, $lc )->stringify ) { 55 54 return $lc; 56 55 } 57 56 else { 58 return lc Archer->context->{ project};57 return lc Archer->context->{ project }; 59 58 } 60 59 } 61 60 61 sub check_recipe { 62 my ( $self, $recipe_name, $altern_path ) = @_; 63 my ( $f, $path ); 64 65 $f = File::Util->new; 66 $path = File::Spec->catfile( $FindBin::Bin, 'assets', 'recipe', 67 $recipe_name ); 68 69 # check first in assets 70 if ( $f->existent( $path ) ) { 71 return $f->load_file( $path ); 72 } 73 74 # if there is another path for recipe in the config, check this one 75 $path = File::Spec->catfile( $altern_path, $recipe_name ); 76 if ( $f->existent( $path ) ) { 77 return $f->load_file( $path ); 78 } 79 80 # fail 81 return undef; 82 } 83 62 84 1; -
lang/perl/Archer/lib/Archer/Plugin/Exec.pm
r3682 r3707 7 7 8 8 sub run { 9 my ($self, $context, $args) = @_; 9 my ( $self, $context, $args ) = @_; 10 my $cmd; 10 11 11 my $cmd = $self->{config}->{command}; 12 $self->log(debug => "template: $cmd"); 12 if ( $self->{ config }->{ command } ) { 13 $cmd = $self->{ config }->{ command }; 14 $self->log( debug => "template: $cmd" ); 13 15 14 $cmd = $self->templatize($cmd); 15 $self->log(info => "* execute " . colored($cmd, 'red')); 16 $cmd = $self->templatize( $cmd ); 17 $self->log( info => "* execute " . colored( $cmd, 'red' ) ); 18 } 19 elsif ( $self->{ config }->{ recipe } ) { 20 require Archer::Util; 21 $cmd = $self > check_recipe( $self->{ config }->{ recipe }, 22 $context->{ config }->{ global }->{ recipe } ); 16 23 17 if ($context->{dry_run_fg}) { 18 $self->log(debug => "dry-run"); 24 if ( !defined $cmd ) { 25 $self->log( 26 'warn' => 'The recipe ' 27 . $self->{ config }->{ recipe } . ' 28 can\'t be found' 29 ); 30 return; 31 } 32 $cmd = $self->templatize( $cmd ); 33 warn $cmd; 34 } 35 36 if ( $context->{ dry_run_fg } ) { 37 $self->log( debug => "dry-run" ); 19 38 } 20 39 else { 21 $self->log(debug => "run!"); 22 23 $self->_execute($_) for grep !/^\s*$/, split /\n/, $cmd; 40 $self->log( debug => "run!" ); 41 if ( $cmd ) { 42 $self->_execute( $_ ) for grep !/^\s*$/, split /\n/, $cmd; 43 } 24 44 } 25 45 }
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)