# abs_path resolves symlinks in parent iff all parents exist
sub abs_path { Cwd::abs_path($_[1]) // rel2abs(@_) }
+sub canonpath_harder {
+ my $p = $_[-1]; # $_[0] may be self
+ $p = File::Spec->canonpath($p);
+ $p =~ m!(?:/*|\A)\.\.(?:/*|\z)! && -e $p ? Cwd::abs_path($p) : $p;
+}
+
sub share_path ($) { # $HOME/.local/share/lei/$FOO
my ($self) = @_;
rel2abs($self, ($self->{env}->{XDG_DATA_HOME} //
my $cfg = PublicInbox::Config->git_config_dump($f);
$cfg->{-st} = $cur_st;
$cfg->{'-f'} = $f;
- if ($sto && File::Spec->canonpath($sto_dir // store_path($self))
- eq File::Spec->canonpath($cfg->{'leistore.dir'} //
+ if ($sto && canonpath_harder($sto_dir // store_path($self))
+ eq canonpath_harder($cfg->{'leistore.dir'} //
store_path($self))) {
$cfg->{-lei_store} = $sto;
$cfg->{-lei_note_event} = $lne;
next;
}
if ($url =~ /\Amaildir:(.+)/i) {
- my $d = File::Spec->canonpath($1);
+ my $d = canonpath_harder($1);
if ($state eq 'pause') {
cancel_maildir_watch($d, $cfg_f);
} elsif (!exists($MDIR2CFGPATH->{$d}->{$cfg_f})) {
next if exists $seen{$url};
delete $old->{$url};
if ($url =~ /\Amaildir:(.+)/i) {
- my $d = File::Spec->canonpath($1);
+ my $d = canonpath_harder($1);
cancel_maildir_watch($d, $cfg_f);
} else { # TODO: imap/nntp/jmap
$lei->child_error(1, "E: watch $url TODO");
for my $loc ($lei->externals_each) { # locals only
$lxs->prepare_external($loc) if -d $loc;
}
- $self->refresh_externals($lxs);
+ $self->refresh_externals($lxs, $lei);
$self;
}
}
sub refresh_externals {
- my ($self, $lxs) = @_;
+ my ($self, $lxs, $lei) = @_;
$self->git->cleanup;
my $lk = $self->lock_for_scope;
my $cur_lxs = ref($lxs)->new;
}
my @ibxish = $cur_lxs->locals;
for my $x ($lxs->locals) {
- my $d = File::Spec->canonpath($x->{inboxdir} // $x->{topdir});
+ my $d = $lei->canonpath_harder($x->{inboxdir} // $x->{topdir});
$seen_ibxish{$d} //= do {
$new .= "$d\n";
push @ibxish, $x;
$old = <$fh> // die "readline($f): $!";
}
for my $x (@ibxish) {
- $new .= File::Spec->canonpath($x->git->{git_dir})."/objects\n";
+ $new .= $lei->canonpath_harder($x->git->{git_dir})."/objects\n";
}
$self->{ibxish} = \@ibxish;
return if $old eq $new;
if ($opt->{mail} // ($has_hints ? 0 : 1)) {
if (grep(defined, @$opt{qw(include only)})) {
$lxs = $lei->lxs_prepare;
- $lei->ale->refresh_externals($lxs);
+ $lei->ale->refresh_externals($lxs, $lei);
}
my $rdr = {};
if ($opt->{mail}) {
return $lei->fail('no --git-dir to try') unless @$git_dirs;
unless ($lxs) {
$lxs = $lei->lxs_prepare or return;
- $lei->ale->refresh_externals($lxs);
+ $lei->ale->refresh_externals($lxs, $lei);
}
if ($lxs->remotes) {
require PublicInbox::LeiRemote;
# for the "lei init" command, not sure if it's even needed...
package PublicInbox::LeiInit;
use v5.10.1;
-use File::Spec;
sub lei_init {
my ($self, $dir) = @_;
$dir //= $self->store_path;
$dir = $self->rel2abs($dir);
my @cur = stat($cur) if defined($cur);
- $cur = File::Spec->canonpath($cur // $dir);
+ $cur = $self->canonpath_harder($cur // $dir);
my @dir = stat($dir);
my $exists = "# leistore.dir=$cur already initialized" if @dir;
if (@cur) {
sub lei_lcat {
my ($lei, @argv) = @_;
my $lxs = $lei->lxs_prepare or return;
- $lei->ale->refresh_externals($lxs);
+ $lei->ale->refresh_externals($lxs, $lei);
my $sto = $lei->_lei_store(1);
$lei->{lse} = $sto->search;
my $opt = $lei->{opt};
$fmt //= $devfd >= 0 ? 'json' : (detect_fmt($lei, $dst) or return);
if (index($dst, '://') < 0) { # not a URL, so assume path
- $dst = File::Spec->canonpath($dst);
+ $dst = $lei->canonpath_harder($dst);
} # else URL
my $self = bless { fmt => $fmt, dst => $dst }, $class;
my ($self, @argv) = @_;
PublicInbox::Config->json; # preload before forking
my $lxs = lxs_prepare($self) or return;
- $self->ale->refresh_externals($lxs);
+ $self->ale->refresh_externals($lxs, $self);
my $opt = $self->{opt};
my %mset_opt = map { $_ => $opt->{$_} } qw(threads limit offset);
$mset_opt{asc} = $opt->{'reverse'} ? 1 : 0;
$lei->{curl} //= which('curl') or return
$lei->fail('curl needed for', $lxs->remotes);
}
- $lei->ale->refresh_externals($lxs);
+ $lei->ale->refresh_externals($lxs, $lei);
my $self = bless {
-force_eml => 1, # for LeiInput->input_fh
lxs => $lxs,
}
$lei->{lss} = $lss; # for LeiOverview->new
my $lxs = $lei->lxs_prepare or return;
- $lei->ale->refresh_externals($lxs);
+ $lei->ale->refresh_externals($lxs, $lei);
$lei->_start_query;
}
require_git 2.6;
require_ok 'PublicInbox::LeiXSearch';
require_ok 'PublicInbox::LeiALE';
+require_ok 'PublicInbox::LEI';
my ($home, $for_destroy) = tmpdir();
my @ibx;
for my $V (1..2) {
my $smsg = $lxs->smsg_for($mitem) or BAIL_OUT 'smsg_for broken';
my $ale = PublicInbox::LeiALE::_new("$home/ale");
- $ale->refresh_externals($lxs);
+ my $lei = bless {}, 'PublicInbox::LEI';
+ $ale->refresh_externals($lxs, $lei);
my $exp = [ $smsg->{blob}, 'blob', -s 't/utf8.eml' ];
is_deeply([ $ale->git->check($smsg->{blob}) ], $exp, 'ale->git->check');
$lxs = PublicInbox::LeiXSearch->new;
$lxs->prepare_external($v2ibx);
- $ale->refresh_externals($lxs);
+ $ale->refresh_externals($lxs, $lei);
is_deeply([ $ale->git->check($smsg->{blob}) ], $exp,
'ale->git->check remembered inactive external');
rename("$home/v1tmp", "$home/v1moved") or BAIL_OUT "rename: $!";
- $ale->refresh_externals($lxs);
+ $ale->refresh_externals($lxs, $lei);
is($ale->git->check($smsg->{blob}), undef,
'missing after directory gone');
}