]> Sergey Matveev's repositories - public-inbox.git/commitdiff
config: support ->urlmatch method for -watch
authorEric Wong <e@yhbt.net>
Sat, 27 Jun 2020 10:03:41 +0000 (10:03 +0000)
committerEric Wong <e@yhbt.net>
Sun, 28 Jun 2020 22:27:18 +0000 (22:27 +0000)
Since we have IMAP client support in -watch; make sure per-URL
settings are familiar to git users by taking advantage of git's
URL matching abilities.

This requires git 1.8.5+, which most users ought to have
(though base CentOS 7 is on 1.8.3).

lib/PublicInbox/Config.pm
lib/PublicInbox/TestCommon.pm
lib/PublicInbox/WatchMaildir.pm
t/config.t
t/imapd.t

index 19535beb97385a52a27f6650795d8c0d508c6653..c0e2cc575ec640ff1532edcc16d501660e5e4f28 100644 (file)
@@ -9,7 +9,7 @@
 
 package PublicInbox::Config;
 use strict;
-use warnings;
+use v5.10.1;
 use PublicInbox::Inbox;
 use PublicInbox::Spawn qw(popen_rd);
 
@@ -462,4 +462,23 @@ sub _fill {
        $ibx
 }
 
+sub urlmatch {
+       my ($self, $key, $url) = @_;
+       state $urlmatch_broken; # requires git 1.8.5
+       return if $urlmatch_broken;
+       my $file = default_file();
+       my $cmd = [qw/git config -z --includes --get-urlmatch/,
+               "--file=$file", $key, $url ];
+       my $fh = popen_rd($cmd);
+       local $/ = "\0";
+       my $val = <$fh>;
+       if (close($fh)) {
+               chomp($val);
+               $val;
+       } else {
+               $urlmatch_broken = 1 if (($? >> 8) != 1);
+               undef;
+       }
+}
+
 1;
index 14ebba10563fc3abd5e22146b89b64fd3e5978e0..7b4da8b5f09a7599c18ee5f8686627c37d37c56a 100644 (file)
@@ -55,15 +55,16 @@ sub tcp_connect {
 
 sub require_git ($;$) {
        my ($req, $maybe) = @_;
-       my ($req_maj, $req_min) = split(/\./, $req);
-       my ($cur_maj, $cur_min) = (`git --version` =~ /version (\d+)\.(\d+)/);
+       my ($req_maj, $req_min, $req_sub) = split(/\./, $req);
+       my ($cur_maj, $cur_min, $cur_sub) = (xqx([qw(git --version)])
+                       =~ /version (\d+)\.(\d+)(?:\.(\d+))?/);
 
-       my $req_int = ($req_maj << 24) | ($req_min << 16);
-       my $cur_int = ($cur_maj << 24) | ($cur_min << 16);
+       my $req_int = ($req_maj << 24) | ($req_min << 16) | ($req_sub // 0);
+       my $cur_int = ($cur_maj << 24) | ($cur_min << 16) | ($cur_sub // 0);
        if ($cur_int < $req_int) {
                return 0 if $maybe;
                Test::More::plan(skip_all =>
-                               "git $req+ required, have $cur_maj.$cur_min");
+                       "git $req+ required, have $cur_maj.$cur_min.$cur_sub");
        }
        1;
 }
index ac980d9b0f131325ddccbf7cb61dd7466dadea78..494fe7a8f212848c00d4480561a0d7ca381a4ce7 100644 (file)
@@ -235,9 +235,11 @@ sub imap_section ($) {
        $uri->scheme . '://' . $uri->authority;
 }
 
-sub cfg_intvl ($$) {
-       my ($cfg, $key) = @_;
-       defined(my $v = $cfg->{lc($key)}) or return;
+sub cfg_intvl ($$$$$) {
+       my ($cfg, $cfg_section, $cfg_key, $imap_section, $url) = @_;
+       my $key = "$cfg_section.$imap_section.$cfg_key";
+       my $v = $cfg->{lc($key)} //
+               $cfg->urlmatch("$cfg_section.$cfg_key", $url) // return;
        $v =~ /\A[0-9]+(?:\.[0-9]+)?\z/s and return $v + 0;
        if (ref($v) eq 'ARRAY') {
                $v = join(', ', @$v);
@@ -257,7 +259,8 @@ sub imap_common_init ($) {
                my $sec = imap_section($uri);
                for my $k (qw(Starttls Debug Compress)) {
                        my $key = lc("imap.$sec.$k");
-                       defined(my $orig = $cfg->{$key}) or next;
+                       my $orig = $cfg->{$key} //
+                               $cfg->urlmatch("imap.$k", $url) // next;
                        my $v = PublicInbox::Config::_git_config_bool($orig);
                        if (defined($v)) {
                                $mic_args->{$sec}->{$k} = $v;
@@ -265,11 +268,11 @@ sub imap_common_init ($) {
                                warn "W: $key=$orig is not boolean\n";
                        }
                }
-               my $to = cfg_intvl($cfg, "imap.$sec.Timeout");
+               my $to = cfg_intvl($cfg, 'imap', 'Timeout', $sec, $url);
                $mic_args->{$sec}->{Timeout} = $to if $to;
-               $to = cfg_intvl($cfg, "imap.$sec.PollInterval");
+               $to = cfg_intvl($cfg, 'imap', 'PollInterval', $sec, $url);
                $self->{imap_opt}->{$sec}->{poll_intvl} = $to if $to;
-               $to = cfg_intvl($cfg, "imap.$sec.IdleInterval");
+               $to = cfg_intvl($cfg, 'imap', 'IdleInterval', $sec, $url);
                $self->{imap_opt}->{$sec}->{idle_intvl} = $to if $to;
        }
        $mic_args;
index 3f41c0042a9e962b0628b01c05af8b2dfcc9c6ba..ad543ad3638c0c0c78022502bfef812fdf2492bd 100644 (file)
@@ -225,4 +225,22 @@ EOF
                'bogus is undef');
 }
 
+SKIP: {
+       require_git('1.8.5', 2) or
+               skip 'git 1.8.5+ required for --url-match', 2;
+       my $f = "$tmpdir/urlmatch";
+       open my $fh, '>', $f or BAIL_OUT $!;
+       print $fh <<EOF or BAIL_OUT $!;
+[imap "imap://*.example.com"]
+       pollInterval = 9
+EOF
+       close $fh or BAIL_OUT;
+       local $ENV{PI_CONFIG} = $f;
+       my $cfg = PublicInbox::Config->new;
+       my $url = 'imap://mail.example.com/INBOX';
+       is($cfg->urlmatch('imap.pollInterval', $url), 9, 'urlmatch hit');
+       is($cfg->urlmatch('imap.idleInterval', $url), undef, 'urlmatch miss');
+};
+
+
 done_testing();
index ee3a3b267671f549b30de54c53aba1f5a28f87d9..5626d24765fd79312fc841288a816c06fbe30f6c 100644 (file)
--- a/t/imapd.t
+++ b/t/imapd.t
@@ -486,7 +486,7 @@ ok($mic->logout, 'logged out');
 
        # try again with polling
        xsys(qw(git config), "--file=$home/.public-inbox/config",
-               "imap.imap://$ihost:$iport.PollInterval", 0.11) == 0
+               'imap.PollInterval', 0.11) == 0
                or BAIL_OUT "git config $?";
        $w->kill('HUP');
        diag 'waiting for -watch reload + initial fetch';