]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/Config.pm
distinguish error messages intended for users vs developers
[public-inbox.git] / lib / PublicInbox / Config.pm
1 # Copyright (C) 2014-2015 all contributors <meta@public-inbox.org>
2 # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
3 #
4 # Used throughout the project for reading configuration
5 package PublicInbox::Config;
6 use strict;
7 use warnings;
8 use base qw/Exporter/;
9 our @EXPORT_OK = qw/try_cat/;
10 use File::Path::Expand qw/expand_filename/;
11
12 # returns key-value pairs of config directives in a hash
13 # if keys may be multi-value, the value is an array ref containing all values
14 sub new {
15         my ($class, $file) = @_;
16         $file = default_file() unless defined($file);
17         bless git_config_dump($file), $class;
18 }
19
20 sub lookup {
21         my ($self, $recipient) = @_;
22         my $addr = lc($recipient);
23         my $pfx;
24
25         foreach my $k (keys %$self) {
26                 $k =~ /\A(publicinbox\.[\w-]+)\.address\z/ or next;
27                 my $v = $self->{$k};
28                 if (ref($v) eq "ARRAY") {
29                         foreach my $alias (@$v) {
30                                 (lc($alias) eq $addr) or next;
31                                 $pfx = $1;
32                                 last;
33                         }
34                 } else {
35                         (lc($v) eq $addr) or next;
36                         $pfx = $1;
37                         last;
38                 }
39         }
40
41         defined $pfx or return;
42
43         my %rv;
44         foreach my $k (qw(mainrepo address filter)) {
45                 my $v = $self->{"$pfx.$k"};
46                 $rv{$k} = $v if defined $v;
47         }
48         my $listname = $pfx;
49         $listname =~ s/\Apublicinbox\.//;
50         $rv{listname} = $listname;
51         my $v = $rv{address};
52         $rv{-primary_address} = ref($v) eq 'ARRAY' ? $v->[0] : $v;
53         \%rv;
54 }
55
56 sub get {
57         my ($self, $listname, $key) = @_;
58
59         $self->{"publicinbox.$listname.$key"};
60 }
61
62 sub config_dir { $ENV{PI_DIR} || expand_filename('~/.public-inbox') }
63
64 sub default_file {
65         my $f = $ENV{PI_CONFIG};
66         return $f if defined $f;
67         config_dir() . '/config';
68 }
69
70 sub git_config_dump {
71         my ($file) = @_;
72         my ($in, $out);
73         my @cmd = (qw/git config/, "--file=$file", '-l');
74         my $cmd = join(' ', @cmd);
75         my $pid = open(my $fh, '-|', @cmd);
76         defined $pid or die "$cmd failed: $!";
77         my %rv;
78         foreach my $line (<$fh>) {
79                 chomp $line;
80                 my ($k, $v) = split(/=/, $line, 2);
81                 my $cur = $rv{$k};
82
83                 if (defined $cur) {
84                         if (ref($cur) eq "ARRAY") {
85                                 push @$cur, $v;
86                         } else {
87                                 $rv{$k} = [ $cur, $v ];
88                         }
89                 } else {
90                         $rv{$k} = $v;
91                 }
92         }
93         close $fh or die "failed to close ($cmd) pipe: $!";
94         $? and warn "$$ $cmd exited with: ($pid) $?";
95         \%rv;
96 }
97
98 sub try_cat {
99         my ($path) = @_;
100         my $rv;
101         if (open(my $fh, '<', $path)) {
102                 local $/;
103                 $rv = <$fh>;
104         }
105         $rv;
106 }
107
108 1;