From 6d2a5e604d689b33586c653d8a04473e33973ac6 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 11 Apr 2014 21:08:50 +0000 Subject: config: support multiple addresses for a inbox This makes it possible to gradually migrate to new address in case of list name changes, and is one step closer to operating in "stealth hijack mode" :) --- examples/public-inbox-config | 4 +++- lib/PublicInbox/Config.pm | 40 +++++++++++++++++++++++++++++++++------- t/config.t | 10 ++++++++++ 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/examples/public-inbox-config b/examples/public-inbox-config index fd97600f..000cf2c3 100644 --- a/examples/public-inbox-config +++ b/examples/public-inbox-config @@ -1,9 +1,11 @@ # this usually in ~/.public-inbox/config and parseable with git-config(1) # update t/config.t if changing this, that test relies on this [publicinbox "test"] + address = try@public-inbox.org + address = sandbox@public-inbox.org address = test@public-inbox.org mainrepo = /home/pi/test-main.git - description = test repo, occasionally reset + description = test/sandbox area, occasionally reset url = http://example.com/test [publicinbox "bugs"] address = bugs@public-inbox.org diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm index 300dd88b..c8f2a8d8 100644 --- a/lib/PublicInbox/Config.pm +++ b/lib/PublicInbox/Config.pm @@ -6,6 +6,7 @@ use warnings; use File::Path::Expand qw/expand_filename/; # returns key-value pairs of config directives in a hash +# if keys may be multi-value, the value is an array ref containing all values sub new { my ($class, $file) = @_; @@ -14,7 +15,21 @@ sub new { my @cfg = `git config -l`; $? == 0 or die "git config -l failed: $?\n"; chomp @cfg; - my %rv = map { split(/=/, $_, 2) } @cfg; + my %rv; + foreach my $line (@cfg) { + my ($k, $v) = split(/=/, $line, 2); + my $cur = $rv{$k}; + + if (defined $cur) { + if (ref($cur) eq "ARRAY") { + push @$cur, $v; + } else { + $rv{$k} = [ $cur, $v ]; + } + } else { + $rv{$k} = $v; + } + } bless \%rv, $class; } @@ -25,16 +40,27 @@ sub lookup { foreach my $k (keys %$self) { $k =~ /\A(publicinbox\.[A-Z0-9a-z-]+)\.address\z/ or next; - (lc($self->{$k}) eq $addr) or next; - $pfx = $1; - last; + my $v = $self->{$k}; + if (ref($v) eq "ARRAY") { + foreach my $alias (@$v) { + (lc($alias) eq $addr) or next; + $pfx = $1; + last; + } + } else { + (lc($v) eq $addr) or next; + $pfx = $1; + last; + } } defined $pfx or return; - my %rv = map { - $_ => $self->{"$pfx.$_"} - } (qw(mainrepo description address)); + my %rv; + foreach my $k (qw(mainrepo description address)) { + my $v = $self->{"$pfx.$k"}; + $rv{$k} = $v if defined $v; + } my $listname = $pfx; $listname =~ s/\Apublicinbox\.//; $rv{listname} = $listname; diff --git a/t/config.t b/t/config.t index 44e051f2..cd61fe09 100644 --- a/t/config.t +++ b/t/config.t @@ -34,6 +34,16 @@ my $tmpdir = tempdir(CLEANUP => 1); is($cfg->lookup('blah@example.com'), undef, "non-existent lookup returns undef"); + + my $test = $cfg->lookup('test@public-inbox.org'); + is_deeply($test, { + 'address' => ['try@public-inbox.org', + 'sandbox@public-inbox.org', + 'test@public-inbox.org'], + 'mainrepo' => '/home/pi/test-main.git', + 'description' => 'test/sandbox area, occasionally reset', + 'listname' => 'test', + }, "lookup matches expected output for test"); } done_testing(); -- cgit v1.2.3-24-ge0c7