X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FConfig.pm;h=b7e03af37e652b9e758a2b0646ed2fdab530c3c7;hb=1317fb7b4ace03f6d9dfb1a42ee5f9371a1bf913;hp=ef277c40a55e14c9719a07ecf9546e9c94edd4ef;hpb=41a555ebab603d492440e97c8ddd889617cc51f0;p=public-inbox.git diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm index ef277c40..b7e03af3 100644 --- a/lib/PublicInbox/Config.pm +++ b/lib/PublicInbox/Config.pm @@ -20,11 +20,17 @@ sub _array ($) { ref($_[0]) eq 'ARRAY' ? $_[0] : [ $_[0] ] } sub new { my ($class, $file) = @_; $file = default_file() unless defined($file); - $file = ref $file ? $file : git_config_dump($file); - my $self = bless $file, $class; - + my $self; + if (ref($file) eq 'SCALAR') { # used by some tests + open my $fh, '<', $file or die; # PerlIO::scalar + $self = config_fh_parse($fh, "\n", '='); + } else { + $self = git_config_dump($file); + } + bless $self, $class; # caches $self->{-by_addr} ||= {}; + $self->{-by_list_id} ||= {}; $self->{-by_name} ||= {}; $self->{-by_newsgroup} ||= {}; $self->{-no_obfuscate} ||= {}; @@ -84,6 +90,33 @@ sub lookup { _fill($self, $pfx); } +sub lookup_list_id { + my ($self, $list_id) = @_; + $list_id = lc($list_id); + my $ibx = $self->{-by_list_id}->{$list_id}; + return $ibx if $ibx; + + my $pfx; + + foreach my $k (keys %$self) { + $k =~ /\A(publicinbox\.[\w-]+)\.listid\z/ or next; + my $v = $self->{$k}; + if (ref($v) eq "ARRAY") { + foreach my $alias (@$v) { + (lc($alias) eq $list_id) or next; + $pfx = $1; + last; + } + } else { + (lc($v) eq $list_id) or next; + $pfx = $1; + last; + } + } + defined $pfx or return; + _fill($self, $pfx); +} + sub lookup_name ($$) { my ($self, $name) = @_; $self->{-by_name}->{$name} || _fill($self, "publicinbox.$name"); @@ -91,22 +124,12 @@ sub lookup_name ($$) { sub each_inbox { my ($self, $cb) = @_; - if (my $section_order = $self->{-section_order}) { - foreach my $section (@$section_order) { - next if $section !~ m!\Apublicinbox\.([^/]+)\z!; - $self->{"publicinbox.$1.mainrepo"} or next; - my $ibx = lookup_name($self, $1) or next; - $cb->($ibx); - } - } else { - my %seen; - foreach my $k (keys %$self) { - $k =~ m!\Apublicinbox\.([^/]+)\.mainrepo\z! or next; - next if $seen{$1}; - $seen{$1} = 1; - my $ibx = lookup_name($self, $1) or next; - $cb->($ibx); - } + # may auto-vivify if config file is non-existent: + foreach my $section (@{$self->{-section_order}}) { + next if $section !~ m!\Apublicinbox\.([^/]+)\z!; + $self->{"publicinbox.$1.mainrepo"} or next; + my $ibx = lookup_name($self, $1) or next; + $cb->($ibx); } } @@ -147,19 +170,14 @@ sub default_file { config_dir() . '/config'; } -sub git_config_dump { - my ($file) = @_; - my (%section_seen, @section_order); - return {} unless -e $file; - my @cmd = (qw/git config/, "--file=$file", '-l'); - my $cmd = join(' ', @cmd); - my $fh = popen_rd(\@cmd) or die "popen_rd failed for $file: $!\n"; +sub config_fh_parse ($$$) { + my ($fh, $rs, $fs) = @_; my %rv; - local $/ = "\n"; + my (%section_seen, @section_order); + local $/ = $rs; while (defined(my $line = <$fh>)) { chomp $line; - my ($k, $v) = split(/=/, $line, 2); - + my ($k, $v) = split($fs, $line, 2); my ($section) = ($k =~ /\A(\S+)\.[^\.]+\z/); unless (defined $section_seen{$section}) { $section_seen{$section} = 1; @@ -177,12 +195,22 @@ sub git_config_dump { $rv{$k} = $v; } } - close $fh or die "failed to close ($cmd) pipe: $?"; $rv{-section_order} = \@section_order; \%rv; } +sub git_config_dump { + my ($file) = @_; + return {} unless -e $file; + my @cmd = (qw/git config -z -l/, "--file=$file"); + my $cmd = join(' ', @cmd); + my $fh = popen_rd(\@cmd) or die "popen_rd failed for $file: $!\n"; + my $rv = config_fh_parse($fh, "\0", "\n"); + close $fh or die "failed to close ($cmd) pipe: $?"; + $rv; +} + sub valid_inbox_name ($) { my ($name) = @_; @@ -398,7 +426,7 @@ sub _fill { } # TODO: more arrays, we should support multi-value for # more things to encourage decentralization - foreach my $k (qw(address altid nntpmirror coderepo hide)) { + foreach my $k (qw(address altid nntpmirror coderepo hide listid)) { if (defined(my $v = $self->{"$pfx.$k"})) { $ibx->{$k} = _array($v); } @@ -421,6 +449,11 @@ sub _fill { $self->{-by_addr}->{$lc_addr} = $ibx; $self->{-no_obfuscate}->{$lc_addr} = 1; } + if (my $listids = $ibx->{listid}) { + foreach my $list_id (@$listids) { + $self->{-by_list_id}->{$list_id} = $ibx; + } + } if (my $ng = $ibx->{newsgroup}) { $self->{-by_newsgroup}->{$ng} = $ibx; }