X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FLeiMirror.pm;h=ec2b56dfeb89331c647e9ca35c4c53798d4a2d35;hb=7b654d175cf2e31b4354929ea678563f534947e5;hp=5952ed52ec7300ab60ef5455eee56ed90ac843f7;hpb=6efe57a87e6a7da471adf31c037844add788a61a;p=public-inbox.git diff --git a/lib/PublicInbox/LeiMirror.pm b/lib/PublicInbox/LeiMirror.pm index 5952ed52..ec2b56df 100644 --- a/lib/PublicInbox/LeiMirror.pm +++ b/lib/PublicInbox/LeiMirror.pm @@ -18,21 +18,21 @@ use PublicInbox::Config; use PublicInbox::Inbox; use PublicInbox::LeiCurl; use PublicInbox::OnDestroy; -use Digest::SHA qw(sha256_hex sha1_hex); +use PublicInbox::SHA qw(sha256_hex sha1_hex); use POSIX qw(strftime); our $LIVE; # pid => callback our $FGRP_TODO; # objstore -> [ fgrp mirror objects ] our $TODO; # reference => [ non-fgrp mirror objects ] +our @PUH; # post-update hooks sub keep_going ($) { $LIVE && (!$_[0]->{lei}->{child_error} || $_[0]->{lei}->{opt}->{'keep-going'}); } -sub _wq_done_wait { # dwaitpid callback (via wq_eof) - my ($arg, $pid) = @_; - my ($mrr, $lei) = @$arg; +sub _wq_done_wait { # awaitpid cb (via wq_eof) + my ($pid, $mrr, $lei) = @_; if ($?) { $lei->child_error($?); } elsif (!$lei->{child_error}) { @@ -235,7 +235,7 @@ sub index_cloned_inbox { my ($k) = ($sw =~ /\A([\w-]+)/); $opt->{$k} = $lei->{opt}->{$k}; } - # force synchronous dwaitpid for v2: + # force synchronous awaitpid for v2: local $PublicInbox::DS::in_loop = 0; my $cfg = PublicInbox::Config->new(undef, $lei->{2}); my $env = PublicInbox::Admin::index_prepare($opt, $cfg); @@ -299,7 +299,7 @@ sub fgrp_update { my $cmd = [ 'git', "--git-dir=$fgrp->{cur_dst}", qw(update-ref --stdin -z) ]; my $lei = $fgrp->{lei}; - my $pack = PublicInbox::OnDestroy->new($$, \&pack_dst, $fgrp); + my $pack = PublicInbox::OnDestroy->new($$, \&satellite_done, $fgrp); start_cmd($fgrp, $cmd, { 0 => $r, 2 => $lei->{2} }, $pack); close $r or die "close(r): $!"; return if $fgrp->{dry_run}; @@ -319,9 +319,10 @@ sub fgrp_update { close($w) or warn "E: close(update-ref --stdin): $! (need git 1.8.5+)\n"; } -sub pack_dst { # packs lightweight satellite repos +sub satellite_done { my ($fgrp) = @_; pack_refs($fgrp, $fgrp->{cur_dst}); + run_puh($fgrp); } sub pack_refs { @@ -493,7 +494,6 @@ sub cmp_fp_do { $self->{-show_ref} = $opt->{1}; do_reap($self); $self->{lei}->qerr("# @$cmd"); - return if $self->{dry_run}; $LIVE->{spawn($cmd, undef, $opt)} = [ \&fp_done, $self, $cmd, $cb, @arg ]; } @@ -514,7 +514,9 @@ sub resume_fetch { my $cmd = [ @{$self->{-torsocks}}, @git, fetch_args($self->{lei}, $opt), $rn ]; push @$cmd, '-P' if $self->{lei}->{prune}; # --prune-tags implied - start_cmd($self, $cmd, $opt, $fini); + my $run_puh = PublicInbox::OnDestroy->new($$, \&run_puh, $self, $fini); + ++$self->{chg}->{nr_chg}; + start_cmd($self, $cmd, $opt, $run_puh); } sub fgrp_enqueue { @@ -531,6 +533,7 @@ sub fgrp_enqueue { $fgrp->{dry_run} ? $fgrp->{lei}->qerr("# @cmd @kv") : run_die([@cmd, @kv], undef, $opt); } + ++$fgrp->{chg}->{nr_chg}; push @{$FGRP_TODO->{$fgrp->{-osdir}}}, $fgrp; } @@ -563,7 +566,9 @@ sub clone_v1 { "$self->{dst}$ref"; } } - start_cmd($self, $cmd, $opt, $fini); + ++$self->{chg}->{nr_chg}; + start_cmd($self, $cmd, $opt, PublicInbox::OnDestroy->new($$, + \&run_puh, $self, $fini)); } if (!$self->{-is_epoch} && $lei->{opt}->{'inbox-config'} =~ /\A(?:always|v1)\z/s) { @@ -684,17 +689,17 @@ sub atomic_write ($$$) { sub run_next_puh { my ($self) = @_; - my $puh = shift @{$self->{-puh_todo}} // return; + my $puh = shift @{$self->{-puh_todo}} // return delete($self->{-fini}); my $fini = PublicInbox::OnDestroy->new($$, \&run_next_puh, $self); my $cmd = [ @$puh, ($self->{cur_dst} // $self->{dst}) ]; my $opt = +{ map { $_ => $self->{lei}->{$_} } (0..2) }; start_cmd($self, $cmd, undef, $opt, $fini); } -sub run_post_update_hooks { - my ($self) = @_; - my $puh = $self->{-puh} // return; - @{$self->{-puh_todo}} = @$puh; +sub run_puh { + my ($self, $fini) = @_; + $self->{-fini} = $fini; + @{$self->{-puh_todo}} = @PUH; run_next_puh($self); } @@ -747,6 +752,7 @@ sub update_ent { } } symlink($tgt, $ln) or die "symlink($tgt, $ln): $!"; + ++$self->{chg}->{nr_chg}; } } if (defined(my $t = $self->{-ent}->{modified})) { @@ -789,7 +795,6 @@ sub v1_done { # called via OnDestroy } eval { set_description($self) }; warn $@ if $@; - run_post_update_hooks($self); return if ($self->{-is_epoch} || $self->{lei}->{opt}->{'inbox-config'} ne 'always'); write_makefile($dst, 1); @@ -1049,7 +1054,9 @@ EOM warn "\t", $_, "\n" for @local; my (undef, $dn, $bn) = File::Spec->splitpath($f); - atomic_write($dn, $bn, join("\n", @list, '')); + $self->{chg}->{nr_chg} += scalar(@remote) + scalar(@local); + my $new = join("\n", @list, ''); + atomic_write($dn, $bn, $new) if $new ne $old; } # FIXME: this gets confused by single inbox instance w/ global manifest.js.gz @@ -1080,7 +1087,10 @@ sub try_manifest { } # bail out if curl -z/--timecond hit 304 Not Modified, $ft will be empty - return $lei->qerr("# $manifest unchanged") if -f $manifest && !-s $ft; + if (-f $manifest && !-s $ft) { + $lei->child_error(127 << 8) if $lei->{opt}->{'exit-code'}; + return $lei->qerr("# $manifest unchanged"); + } my $m = eval { decode_manifest($ft, $ft, $uri) }; if ($@) { @@ -1168,6 +1178,8 @@ W: The following exist and have not been converted to symlinks EOM dump_project_list($self, $m); ft_rename($ft, $manifest, 0666); + !$self->{chg}->{nr_chg} && $lei->{opt}->{'exit-code'} and + $lei->child_error(127 << 8); } sub start_clone_url { @@ -1182,12 +1194,10 @@ sub do_mirror { # via wq_io_do or public-inbox-clone $self->{dry_run} = 1 if $lei->{opt}->{'dry-run'}; umask($lei->{client_umask}) if defined $lei->{client_umask}; $self->{-initial_clone} = 1 if !-d $self->{dst}; + local @PUH; if (defined(my $puh = $lei->{opt}->{'post-update-hook'})) { require Text::ParseWords; - for (@$puh) { - my $pfx = [ Text::ParseWords::shellwords($_) ]; - push @{$self->{-puh}}, $pfx; - } + @PUH = map { [ Text::ParseWords::shellwords($_) ] } @$puh; } eval { my $ic = $lei->{opt}->{'inbox-config'} //= 'always';