]> Sergey Matveev's repositories - public-inbox.git/blob - script/public-inbox-index
git: use built-in spawn implementation for vfork
[public-inbox.git] / script / public-inbox-index
1 #!/usr/bin/perl -w
2 # Copyright (C) 2015 all contributors <meta@public-inbox.org>
3 # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
4 # Basic tool to create a Xapian search index for a git repository
5 # configured for public-inbox.
6 # Usage with libeatmydata <https://www.flamingspork.com/projects/libeatmydata/>
7 # highly recommended: eatmydata public-inbox-index GIT_DIR
8
9 use strict;
10 use warnings;
11 my $usage = "public-inbox-index GIT_DIR";
12 use PublicInbox::Config;
13 eval { require PublicInbox::SearchIdx };
14 if ($@) {
15         print STDERR "Search::Xapian required for $0\n";
16         exit 1;
17 }
18 my @dirs;
19
20 sub resolve_git_dir {
21         my ($cd) = @_;
22         my @cmd = qw(git rev-parse --git-dir);
23         my $cmd = join(' ', @cmd);
24         my $pid = open my $fh, '-|';
25         defined $pid or die "forking $cmd failed: $!\n";
26         if ($pid == 0) {
27                 if (defined $cd) {
28                         chdir $cd or die "chdir $cd failed: $!\n";
29                 }
30                 exec @cmd;
31                 die "Failed to exec $cmd: $!\n";
32         } else {
33                 my $dir = eval {
34                         local $/;
35                         <$fh>;
36                 };
37                 close $fh or die "error in $cmd: $!\n";
38                 chomp $dir;
39                 return $cd if ($dir eq '.' && defined $cd);
40                 $dir;
41         }
42 }
43
44 if (@ARGV) {
45         @dirs = map { resolve_git_dir($_) } @ARGV;
46 } else {
47         @dirs = (resolve_git_dir());
48 }
49
50 sub usage { print STDERR "Usage: $usage\n"; exit 1 }
51 usage() unless @dirs;
52
53 foreach my $dir (@dirs) {
54         index_dir($dir);
55 }
56
57 sub index_dir {
58         my ($git_dir) = @_;
59         -d $git_dir or die "$git_dir does not appear to be a git repository\n";
60
61         system('git', "--git-dir=$git_dir", 'update-server-info') and
62                 die "git update-server-info failed for $git_dir";
63         my $s = PublicInbox::SearchIdx->new($git_dir, 1);
64         $s->index_sync;
65 }