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 | 21 ++++++++++++++++++++-
lib/PublicInbox/TestCommon.pm | 11 ++++++-----
lib/PublicInbox/WatchMaildir.pm | 17 ++++++++++-------
t/config.t | 18 ++++++++++++++++++
t/imapd.t | 2 +-
5 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm
index 19535beb973..c0e2cc575ec 100644
--- a/lib/PublicInbox/Config.pm
+++ b/lib/PublicInbox/Config.pm
@@ -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;
diff --git a/lib/PublicInbox/TestCommon.pm b/lib/PublicInbox/TestCommon.pm
index 14ebba10563..7b4da8b5f09 100644
--- a/lib/PublicInbox/TestCommon.pm
+++ b/lib/PublicInbox/TestCommon.pm
@@ -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;
}
diff --git a/lib/PublicInbox/WatchMaildir.pm b/lib/PublicInbox/WatchMaildir.pm
index ac980d9b0f1..494fe7a8f21 100644
--- a/lib/PublicInbox/WatchMaildir.pm
+++ b/lib/PublicInbox/WatchMaildir.pm
@@ -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;
diff --git a/t/config.t b/t/config.t
index 3f41c0042a9..ad543ad3638 100644
--- a/t/config.t
+++ b/t/config.t
@@ -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();
diff --git a/t/imapd.t b/t/imapd.t
index ee3a3b26767..5626d24765f 100644
--- 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';
--
unsubscribe: one-click, see List-Unsubscribe header
archive: https://public-inbox.org/meta/