]> Sergey Matveev's repositories - public-inbox.git/commitdiff
search: respect core.sharedRepository in for Xapian DB
authorEric Wong <e@80x24.org>
Sun, 23 Aug 2015 18:14:04 +0000 (18:14 +0000)
committerEric Wong <e@80x24.org>
Sun, 23 Aug 2015 18:14:13 +0000 (18:14 +0000)
Extend the purpose of core.sharedRepository to apply to
the $GIT_DIR/public-inbox/xapian* directory.

lib/PublicInbox/SearchIdx.pm
public-inbox-learn
public-inbox-mda
t/search.t

index 408b21fdad6d96fb86af4e8a618e208f1792f154..5664c385017a621afb9bd5bd410974938d38f775 100644 (file)
@@ -8,6 +8,14 @@ use base qw(PublicInbox::Search);
 use PublicInbox::MID qw/mid_clean mid_compressed/;
 *xpfx = *PublicInbox::Search::xpfx;
 
+use constant {
+       PERM_UMASK => 0,
+       OLD_PERM_GROUP => 1,
+       OLD_PERM_EVERYBODY => 2,
+       PERM_GROUP => 0660,
+       PERM_EVERYBODY => 0664,
+};
+
 sub new {
        my ($class, $git_dir, $writable) = @_;
        my $dir = $class->xdir($git_dir);
@@ -18,8 +26,15 @@ sub new {
                File::Path::mkpath($dir);
                $flag = Search::Xapian::DB_CREATE_OR_OPEN;
        }
-       my $db = Search::Xapian::WritableDatabase->new($dir, $flag);
-       bless { xdb => $db, git_dir => $git_dir }, $class;
+       my $self = bless { git_dir => $git_dir }, $class;
+       my $umask = _umask_for($self->_git_config_perm);
+       my $old_umask = umask $umask;
+       my $db = eval { Search::Xapian::WritableDatabase->new($dir, $flag) };
+       my $err = $@;
+       umask $old_umask;
+       die $err if $err;
+       $self->{xdb} = $db;
+       $self;
 }
 
 sub add_message {
@@ -360,4 +375,52 @@ sub merge_threads {
        }
 }
 
+sub _read_git_config_perm {
+       my ($self) = @_;
+       my @cmd = ('git', "--git-dir=$self->{git_dir}",
+                  qw(config core.sharedRepository));
+       my $pid = open(my $fh, '-|', @cmd) or
+               die('open `'.join(' ', @cmd) . " pipe failed: $!\n");
+       my $perm = <$fh>;
+       close $fh;
+       chomp $perm if defined $perm;
+       $perm;
+}
+
+sub _git_config_perm {
+       my $self = shift;
+       my $perm = scalar @_ ? $_[0] : _read_git_config_perm($self);
+       return PERM_GROUP if (!defined($perm) || !length($perm));
+       return PERM_UMASK if ($perm eq 'umask');
+       return PERM_GROUP if ($perm eq 'group');
+       if ($perm =~ /\A(?:all|world|everybody)\z/) {
+               return PERM_EVERYBODY;
+       }
+       return PERM_GROUP if ($perm =~ /\A(?:true|yes|on|1)\z/);
+       return PERM_UMASK if ($perm =~ /\A(?:false|no|off|0)\z/);
+
+       my $i = oct($perm);
+       return PERM_UMASK if ($i == PERM_UMASK);
+       return PERM_GROUP if ($i == OLD_PERM_GROUP);
+       return PERM_EVERYBODY if ($i == OLD_PERM_EVERYBODY);
+
+       if (($i & 0600) != 0600) {
+               die "core.sharedRepository mode invalid: ".
+                   sprintf('%.3o', $i) . "\nOwner must have permissions\n";
+       }
+       ($i & 0666);
+}
+
+sub _umask_for {
+       my ($perm) = @_; # _git_config_perm return value
+       my $rv = $perm;
+       return umask if $rv == 0;
+
+       # set +x bit if +r or +w were set
+       $rv |= 0100 if ($rv & 0600);
+       $rv |= 0010 if ($rv & 0060);
+       $rv |= 0001 if ($rv & 0006);
+       (~$rv & 0777);
+}
+
 1;
index c89ffb54c2b9bd3f3e6de3f459dd9aab4f2b12c7..f0bbd421e58c04d50b7f8e7763333a7db559f4b7 100755 (executable)
@@ -79,9 +79,7 @@ foreach my $recipient (keys %dests) {
 
        $err or eval {
                require PublicInbox::SearchIdx;
-               umask 0022; # XXX FIXME use git config core.sharedRepository
-               my $s = PublicInbox::SearchIdx->new($git_dir, 2);
-               $s->index_sync;
+               PublicInbox::SearchIdx->new($git_dir, 2)->index_sync;
        };
 }
 
index 630ffcb937f9a5f23a4b54f1e94d940204e94f17..8e98d6ebe2a89c901895be1836fd3c6d7c1a476c 100755 (executable)
@@ -89,8 +89,6 @@ sub search_index_sync {
        my ($git_dir) = @_;
        eval {
                require PublicInbox::Search;
-               umask 0022; # XXX FIXME use git config core.sharedRepository
-               my $s = PublicInbox::SearchIdx->new($git_dir, 2);
-               $s->index_sync;
+               PublicInbox::SearchIdx->new($git_dir, 2)->index_sync;
        };
 }
index be39410fc079dcbba8fd406041f356b077f18053..17e9eaf43aea8e764de4e618539d7108e0947e43 100644 (file)
@@ -23,6 +23,31 @@ my $rw_commit = sub {
        $rw = PublicInbox::SearchIdx->new($git_dir, 1);
 };
 
+{
+       # git repository perms
+       is(PublicInbox::SearchIdx->_git_config_perm(undef),
+          &PublicInbox::SearchIdx::PERM_GROUP,
+          "undefined permission is group");
+       is(PublicInbox::SearchIdx::_umask_for(
+            PublicInbox::SearchIdx->_git_config_perm('0644')),
+          0022, "644 => umask(0022)");
+       is(PublicInbox::SearchIdx::_umask_for(
+            PublicInbox::SearchIdx->_git_config_perm('0600')),
+          0077, "600 => umask(0077)");
+       is(PublicInbox::SearchIdx::_umask_for(
+            PublicInbox::SearchIdx->_git_config_perm('0640')),
+          0027, "640 => umask(0027)");
+       is(PublicInbox::SearchIdx::_umask_for(
+            PublicInbox::SearchIdx->_git_config_perm('group')),
+          0007, 'group => umask(0007)');
+       is(PublicInbox::SearchIdx::_umask_for(
+            PublicInbox::SearchIdx->_git_config_perm('everybody')),
+          0002, 'everybody => umask(0002)');
+       is(PublicInbox::SearchIdx::_umask_for(
+            PublicInbox::SearchIdx->_git_config_perm('umask')),
+          umask, 'umask => existing umask');
+}
+
 {
        my $root = Email::MIME->create(
                header_str => [