App-CdUtils

 view release on metacpan or  search on metacpan

script/cdtree-backend  view on Meta::CPAN

sub _search {
    my ($wanted, $dir, $direlems, $search_siblings) = @_;
    #warn "-> _search($wanted, $dir, [".join(",",@$direlems)."])\n" if $DEBUG;

    if (-d $wanted) {
        warn "cdtree: Found       $dir/$wanted\n" if $DEBUG;
        return "$dir/$wanted";
    }
    opendir my($dh), "." or do {
        warn "cdtree: Can't readdir($dir): $!, skipped\n" if $DEBUG;
        return;
    };

    #warn "cdtree: Searching descendants\n" if $DEBUG;
    for my $entry (sort readdir $dh) {
        next if $entry eq '.' || $entry eq '..';
        next unless (-d $entry) && !(-l $entry);
        chdir $entry or do {
            warn "cdtree: Can't chdir to $dir/$entry: $!, skipped\n" if $DEBUG;
            next;
        };
        warn "cdtree: Looking in $dir/$entry\n" if $DEBUG;
        my $found = _search($wanted, "$dir/$entry", [@$direlems, $entry]);
        chdir ".." or die "cdtree: ERROR: Can't chdir back to $dir: $!\n";
        return $found if $found;
    }

    if ($search_siblings) {
        #warn "cdtree: Searching siblings\n" if $DEBUG;
        my %exclude;
        for (2..@$direlems-1) {
            $exclude{ join("/", @{$direlems}[0..$_]) }++;
        }
        while (@$direlems > 1) {
            pop @$direlems;
            chdir ".." or die "cdtree: ERROR: Can't chdir ..: $!\n";
            $dir = join("/", @$direlems);
            opendir my($dh), "." or do {
                warn "cdtree: Can't readdir($dir): $!, skipped\n" if $DEBUG;
                next;
            };
            for my $entry (sort readdir $dh) {
                next if $entry eq '.' || $entry eq '..';
                next unless (-d $entry) && !(-l $entry);
                next if $exclude{"$dir/$entry"};
                chdir $entry or do {
                    warn "cdtree: Can't chdir to $dir/$entry: $!, skipped\n" if $DEBUG;
                    next;
                };
                warn "cdtree: Looking in $dir/$entry\n" if $DEBUG;
                my $found = _search($wanted, "$dir/$entry", [@$direlems, $entry]);
                chdir ".." or die "cdtree: ERROR: Can't chdir back to $dir: $!\n";
                return $found if $found;
            }
        }
    }

    undef;
}

my $found = _search($ARGV[0], $cwd, [split m!/+!, $cwd], 1);

if ($found) {
    print "$found\n";
} else {
    warn "cdtree: Can't find any match, giving up\n" if $DEBUG;
    print ".\n";
}

# ABSTRACT: Search tree for your directory
# PODNAME: cdtree-backend

__END__

=pod

=encoding UTF-8

=head1 NAME

cdtree-backend - Search tree for your directory

=head1 VERSION

This document describes version 0.015 of cdtree-backend (from Perl distribution App-CdUtils), released on 2026-04-07.

=head1 SYNOPSIS

To use in shell:

 % cdtree() { cd `cdtree-backend "$1"`; }

Take a look at this example filesystem layout:

 media/
   mv/
     en/
       a/
         acdc/
         ...
       b/
         bruno-mars/
         ...
       c/
         carly-rae-japsen/
         celine-dion/
         charlie-puth/
         ...
       d/
         demi-lovato/
         dido/
         ...
     fr/
       a/
       b/
       c/
         celine-dion/
         christophe-willem/
         ...
     it/
     ...



( run in 0.575 second using v1.01-cache-2.11-cpan-71847e10f99 )