about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-01-31 21:08:48 +0000
committerEric Wong <e@80x24.org>2019-01-31 21:08:48 +0000
commit65323f060a3db731bb9fafa004336eeb4bbb8f00 (patch)
treeceaff52229c942314524f4bcac650e1db175c773 /lib
parentce4fe8f5144f7555ddd42b6a94ec602e042c6e43 (diff)
parent440b0feaa209e12e4bcb8ef16a95041fce71e7dc (diff)
downloadpublic-inbox-65323f060a3db731bb9fafa004336eeb4bbb8f00.tar.gz
* origin/purge:
  implement public-inbox-purge tool
  v2writable: read epoch on purge
  v2writable: cleanup processes when done
  v2writable: purge ignores non-existent git epoch directories
  v2writable: ->purge returns undef on no-op
  import: purge: reap fast-export process
  hoist out resolve_repo_dir from -index
Diffstat (limited to 'lib')
-rw-r--r--lib/PublicInbox/Admin.pm44
-rw-r--r--lib/PublicInbox/Import.pm3
-rw-r--r--lib/PublicInbox/V2Writable.pm16
3 files changed, 59 insertions, 4 deletions
diff --git a/lib/PublicInbox/Admin.pm b/lib/PublicInbox/Admin.pm
new file mode 100644
index 00000000..d0a8dd00
--- /dev/null
+++ b/lib/PublicInbox/Admin.pm
@@ -0,0 +1,44 @@
+# Copyright (C) 2019 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+
+# common stuff for administrative command-line tools
+# Unstable internal API
+package PublicInbox::Admin;
+use strict;
+use warnings;
+use Cwd 'abs_path';
+use base qw(Exporter);
+our @EXPORT_OK = qw(resolve_repo_dir);
+
+sub resolve_repo_dir {
+        my ($cd, $ver) = @_;
+        my $prefix = defined $cd ? $cd : './';
+        if (-d $prefix && -f "$prefix/inbox.lock") { # v2
+                $$ver = 2 if $ver;
+                return abs_path($prefix);
+        }
+
+        my @cmd = qw(git rev-parse --git-dir);
+        my $cmd = join(' ', @cmd);
+        my $pid = open my $fh, '-|';
+        defined $pid or die "forking $cmd failed: $!\n";
+        if ($pid == 0) {
+                if (defined $cd) {
+                        chdir $cd or die "chdir $cd failed: $!\n";
+                }
+                exec @cmd;
+                die "Failed to exec $cmd: $!\n";
+        } else {
+                my $dir = eval {
+                        local $/;
+                        <$fh>;
+                };
+                close $fh or die "error in $cmd: $!\n";
+                chomp $dir;
+                $$ver = 1 if $ver;
+                return abs_path($cd) if ($dir eq '.' && defined $cd);
+                abs_path($dir);
+        }
+}
+
+1;
diff --git a/lib/PublicInbox/Import.pm b/lib/PublicInbox/Import.pm
index fd4255cf..7e596abc 100644
--- a/lib/PublicInbox/Import.pm
+++ b/lib/PublicInbox/Import.pm
@@ -495,7 +495,7 @@ sub purge_oids {
         my $old = $self->{'ref'};
         my $git = $self->{git};
         my @export = (qw(fast-export --no-data --use-done-feature), $old);
-        my ($rd, $pid) = $git->popen(@export);
+        my $rd = $git->popen(@export);
         my ($r, $w) = $self->gfi_start;
         my @buf;
         my $npurge = 0;
@@ -550,6 +550,7 @@ sub purge_oids {
                         push @buf, $_;
                 }
         }
+        close $rd or die "close fast-export failed: $?";
         if (@buf) {
                 $w->print(@buf) or wfail;
         }
diff --git a/lib/PublicInbox/V2Writable.pm b/lib/PublicInbox/V2Writable.pm
index 222df5c2..1f17fe21 100644
--- a/lib/PublicInbox/V2Writable.pm
+++ b/lib/PublicInbox/V2Writable.pm
@@ -285,10 +285,19 @@ sub purge_oids {
         $self->done;
         my $pfx = "$self->{-inbox}->{mainrepo}/git";
         my $purges = [];
-        foreach my $i (0..$self->{epoch_max}) {
-                my $git = PublicInbox::Git->new("$pfx/$i.git");
+        my $max = $self->{epoch_max};
+
+        unless (defined($max)) {
+                defined(my $latest = git_dir_latest($self, \$max)) or return;
+                $self->{epoch_max} = $max;
+        }
+        foreach my $i (0..$max) {
+                my $git_dir = "$pfx/$i.git";
+                -d $git_dir or next;
+                my $git = PublicInbox::Git->new($git_dir);
                 my $im = $self->import_init($git, 0, 1);
                 $purges->[$i] = $im->purge_oids($purge);
+                $im->done;
         }
         $purges;
 }
@@ -390,7 +399,7 @@ sub purge {
         my ($self, $mime) = @_;
         my $purges = $self->{-inbox}->with_umask(sub {
                 remove_internal($self, $mime, undef, {});
-        });
+        }) or return;
         $self->idx_init if @$purges; # ->done is called on purges
         for my $i (0..$#$purges) {
                 defined(my $cmt = $purges->[$i]) or next;
@@ -497,6 +506,7 @@ sub done {
         delete $self->{bnote};
         $self->{transact_bytes} = 0;
         $self->lock_release if $parts;
+        $self->{-inbox}->git->cleanup;
 }
 
 sub git_init {