lib/PublicInbox/AltId.pm
lib/PublicInbox/Aspawn.pm
lib/PublicInbox/AutoReap.pm
+lib/PublicInbox/CfgWr.pm
lib/PublicInbox/Cgit.pm
lib/PublicInbox/CidxComm.pm
lib/PublicInbox/CidxLogP.pm
--- /dev/null
+# Copyright (C) all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+
+# config writer, may use libgit2 in the future
+package PublicInbox::CfgWr;
+use v5.12;
+use PublicInbox::Git qw(git_exe);
+use PublicInbox::Spawn qw(run_die run_wait);
+
+sub new {
+ my ($cls, $f) = @_;
+ bless { -f => $f }, $cls;
+}
+
+sub set {
+ my ($self, $k, $v) = @_;
+ push @{$self->{todo}}, [ $k, $v ];
+ $self;
+}
+
+sub add {
+ my ($self, $k, $v) = @_;
+ push @{$self->{todo}}, [ '--add', $k, $v ];
+ $self;
+}
+
+sub replace_all {
+ my ($self, $k, $v, $re) = @_;
+ push @{$self->{todo}}, [ '--replace-all', $k, $v, $re ];
+ $self;
+}
+
+sub unset_all {
+ my ($self, $k) = @_;
+ push @{$self->{todo}}, [ '--unset-all', $k ];
+ $self;
+}
+
+sub commit {
+ my ($self, $opt) = @_;
+ my @x = (git_exe, 'config', '-f', $self->{-f});
+ for my $c (@{delete $self->{todo} // []}) {
+ unshift @$c, @x;
+ if ($c->[scalar(@x)] eq '--unset-all') {
+ run_wait $c, undef, $opt;
+ # ignore ret=5 if no matches (see git-config(1))
+ die "E: @$c \$?=$?" if ($? && ($? >> 8) != 5);
+ } else {
+ run_die $c, undef, $opt;
+ }
+ }
+}
+
+1;
use PublicInbox::Inbox;
use PublicInbox::LeiCurl;
use PublicInbox::OnDestroy;
+use PublicInbox::CfgWr;
use PublicInbox::SHA qw(sha256_hex sha_all);
use POSIX qw(strftime);
use PublicInbox::Admin qw(fmt_localtime);
my ($old, $new) = @$fgrp_old_new;
@$old = sort { $b->{-sort} <=> $a->{-sort} } @$old;
# $new is ordered by {references}
- my $cmd = [ git_exe, "--git-dir=$osdir", qw(config -f), $f ];
+ my $cfgwr = PublicInbox::CfgWr->new($f);
# clobber settings from previous run atomically
for ("remotes.$grp", 'fetch.hideRefs') {
- my $c = [ @$cmd, '--unset-all', $_ ];
- $self->{lei}->qerr("# @$c");
- next if $self->{dry_run};
- run_wait($c, undef, $opt);
- die "E: @$c \$?=$?" if ($? && ($? >> 8) != 5);
+ $cfgwr->unset_all($_) if !$self->{dry_run};
}
+ $cfgwr->commit($opt);
# permanent configs:
my $cfg = PublicInbox::Config->git_config_dump($f);
my ($k, $v) = split(/=/, $_, 2);
$k = "remote.$rn.$k";
next if ($cfg->{$k} // '') eq $v;
- my $c = [@$cmd, $k, $v];
- $fgrp->{lei}->qerr("# @$c");
- next if $fgrp->{dry_run};
- run_die($c, undef, $opt);
+ $cfgwr->set($k, $v) if !$fgrp->{dry_run};
}
}
+ $cfgwr->commit($opt);
if (!$self->{dry_run}) {
# update the config atomically via O_APPEND while
write_file '>>', $f, @buf;
unlink("$f.lock");
}
- $cmd = [ @git, "--git-dir=$osdir", @fetch, $grp ];
+ my $cmd = [ @git, "--git-dir=$osdir", @fetch, $grp ];
push @$old, @$new;
my $end = on_destroy \&fgrpv_done, $old;
start_cmd($self, $cmd, $opt, $end);
$cur = $self->{-local_manifest}->{$key}->{owner} // "\0";
return if $cur eq $new;
utf8::encode($new); # to octets
- my $cmd = [ git_exe, qw(config -f), "$dst/config",
- 'gitweb.owner', $new ];
- start_cmd($self, $cmd, { 2 => $self->{lei}->{2} });
+ PublicInbox::CfgWr->new(
+ "$dst/config")->set('gitweb.owner', $new)->commit;
}
sub v1_done { # called via OnDestroy
use PublicInbox::OverIdx;
use PublicInbox::LeiSearch;
use PublicInbox::Config;
+use PublicInbox::CfgWr;
use PublicInbox::Spawn qw(run_die);
use PublicInbox::ContentHash qw(git_sha);
use PublicInbox::MID qw(mids_for_index);
sub description { $_[0]->{qstr} } # for WWW
sub cfg_set { # called by LeiXSearch
- my ($self, @args) = @_;
+ my ($self, $k, $v) = @_;
my $lk = $self->lock_for_scope; # git-config doesn't wait
- run_die([git_exe, qw(config -f), $self->{'-f'}, @args]);
+ PublicInbox::CfgWr->new($self->{-f})->set($k, $v)->commit;
}
# drop-in for LeiDedupe API
use v5.10.1;
use PublicInbox::Spawn qw(run_die run_qx);
use PublicInbox::Import;
+use PublicInbox::CfgWr;
use PublicInbox::Git qw(git_exe);
use File::Temp 0.19;
use List::Util qw(max);
chomp(my $x = run_qx(\@cmd));
return if $x eq $v;
}
- run_die [@cmd, $v];
+ PublicInbox::CfgWr->new($f)->set('include.path', $v)->commit;
}
sub add_epoch {
close($fh);
my $pfx = "publicinbox.$name";
-my @x = (qw/git config/, "--file=$pi_config_tmp");
+require PublicInbox::CfgWr;
+my $cfgwr = PublicInbox::CfgWr->new($pi_config_tmp);
$inboxdir = PublicInbox::Config::rel2abs_collapsed($inboxdir);
die "`\\n' not allowed in `$inboxdir'\n" if index($inboxdir, "\n") >= 0;
PublicInbox::Spawn->import(qw(run_die));
for my $addr (grep { !$seen{lc $_} } @address) {
- run_die([@x, "--add", "$pfx.address", $addr]);
+ $cfgwr->add("$pfx.address", $addr);
}
-run_die([@x, "$pfx.url", $http_url]) if
+$cfgwr->set("$pfx.url", $http_url) if
(!$old_ibx || !grep(/\Q$http_url\E/, @{$old_ibx->{url} // []}));
-run_die([@x, "$pfx.inboxdir", $inboxdir]) if
+$cfgwr->set("$pfx.inboxdir", $inboxdir) if
(!$old_ibx || ($old_ibx->{inboxdir} ne $inboxdir));
-run_die([@x, "$pfx.indexlevel", $indexlevel]) if defined($indexlevel) &&
+$cfgwr->set("$pfx.indexlevel", $indexlevel) if defined($indexlevel) &&
(!$old_ibx || (($old_ibx->{indexlevel} // '') ne $indexlevel));
-run_die([@x, "$pfx.newsgroup", $ng]) if $ng ne '' &&
+$cfgwr->set("$pfx.newsgroup", $ng) if $ng ne '' &&
(!$old_ibx || (($old_ibx->{newsgroup} // '') ne $ng));
for my $kv (@c_extra) {
# but that's too new to depend on in 2021. Perl quotemeta
# seems compatible enough for POSIX ERE which git uses
my $re = '^'.quotemeta($v).'$';
- run_die([@x, qw(--replace-all), "$pfx.$k", $v, $re]);
+ $cfgwr->replace_all("$pfx.$k", $v, $re);
}
+$cfgwr->commit;
# needed for git prior to v2.1.0
chmod($perm & 07777, $pi_config_tmp);