]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/LeiAddExternal.pm
ds: inline set_cloexec
[public-inbox.git] / lib / PublicInbox / LeiAddExternal.pm
1 # Copyright (C) all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
3
4 # "lei add-external" command
5 package PublicInbox::LeiAddExternal;
6 use strict;
7 use v5.10.1;
8
9 sub _finish_add_external {
10         my ($lei, $location) = @_;
11         my $new_boost = $lei->{opt}->{boost} // 0;
12         my $key = "external.$location.boost";
13         my $cur_boost = $lei->_lei_cfg(1)->{$key};
14         return if defined($cur_boost) && $cur_boost == $new_boost; # idempotent
15         $lei->_config($key, $new_boost);
16 }
17
18 sub lei_add_external {
19         my ($lei, $location) = @_;
20         my $mirror = $lei->{opt}->{mirror} // do {
21                 my @fail;
22                 for my $sw ($lei->index_opt, $lei->curl_opt,
23                                 qw(no-torsocks torsocks inbox-version)) {
24                         my ($f) = (split(/|/, $sw, 2))[0];
25                         next unless defined $lei->{opt}->{$f};
26                         $f = length($f) == 1 ? "-$f" : "--$f";
27                         push @fail, $f;
28                 }
29                 if (scalar(@fail) == 1) {
30                         return $lei->("@fail requires --mirror");
31                 } elsif (@fail) {
32                         my $last = pop @fail;
33                         my $fail = join(', ', @fail);
34                         return $lei->("@fail and $last require --mirror");
35                 }
36                 undef;
37         };
38         $location = $lei->ext_canonicalize($location);
39         if (defined($mirror) && -d $location) {
40                 $lei->fail(<<""); # TODO: did you mean "update-external?"
41 --mirror destination `$location' already exists
42
43         } elsif (-d $location) {
44                 index($location, "\n") >= 0 and
45                         return $lei->fail("`\\n' not allowed in `$location'");
46         }
47         if ($location !~ m!\Ahttps?://! && !-d $location) {
48                 $mirror // return $lei->fail("$location not a directory");
49                 index($location, "\n") >= 0 and
50                         return $lei->fail("`\\n' not allowed in `$location'");
51                 $mirror = $lei->ext_canonicalize($mirror);
52                 require PublicInbox::LeiMirror;
53                 PublicInbox::LeiMirror->start($lei, $mirror => $location);
54         } else {
55                 _finish_add_external($lei, $location);
56         }
57 }
58
59 sub _complete_add_external { # for bash, this relies on "compopt -o nospace"
60         my ($lei, @argv) = @_;
61         my $cfg = $lei->_lei_cfg or return ();
62         my $match_cb = $lei->complete_url_prepare(\@argv);
63         require URI;
64         map {
65                 my $u = URI->new(substr($_, length('external.')));
66                 my ($base) = ($u->path =~ m!((?:/?.*)?/)[^/]+/?\z!);
67                 $u->path($base);
68                 $match_cb->($u->as_string);
69         } grep(m!\Aexternal\.https?://!, @{$cfg->{-section_order}});
70 }
71
72 1;