ovedpo15 has asked for the wisdom of the Perl Monks concerning the following question:
Basically, it creates a graph that contains link/dir/file vertices. If it's a file it does not have any children, if it's a link it has only one child and if it's a dir it could contain zero or more children. Just to make it more clear, consider this small example:sub add_new_path { my ($self,$path) = @_; my $canonical_path = get_canonical_path($path); my @subpaths = splitdir($canonical_path); for my $index (0..$#subpaths) { next if (@subpaths[$index] eq ""); # Ignore empty strings my $parent_path = abs_path(catdir(@subpaths[0..($index-1)])); my $current_path = catdir($parent_path,@subpaths[$index]); my $original_path_flag = ($index eq $#subpaths); next if ($self->{"graph"}->has_vertex($current_path)); if (-l $current_path) { my @resloved_links = resolve_symlink($current_path); my $target_path = $resloved_links[1]; $self->add_path($target_path); $self->{"graph"}->add_edge($parent_path,$current_path); $self->{"graph"}->add_edge($current_path,$target_path); $self->{"graph"}->set_vertex_attributes($current_path, { " +type" => "link", "original" => $original_path_flag }); } elsif (-f $current_path) { $self->{"graph"}->add_edge($parent_path,$current_path); $self->{"graph"}->set_vertex_attributes($current_path, { " +type" => "file", "original" => $original_path_flag }); } elsif (-d $current_path) { $self->{"graph"}->add_edge($parent_path,$current_path); $self->{"graph"}->set_vertex_attributes($current_path, { " +type" => "dir", "original" => $original_path_flag }); } } } sub resolve_symlink { my ($file) = @_; unless (file_name_is_absolute($file)) { log_debug("Failed to resolve link $file"); return; } my @files; my $origwd = getcwd; my $rv = eval { my $f = $file; while (1) { my $dir; ($f,$dir) = fileparse($f); last unless (-d $dir); chdir $dir or die "chdir $dir: $!"; push @files, catfile(getcwd,$f); last unless (-l $f); defined( $f = readlink $f ) or die "readlink $f (cwd=".get +cwd."): $!"; } 1 }; my $err = $@ || 'unknown error'; chdir $origwd or (log_error("Failed to chdir $origwd: $!") && retu +rn); die $err unless ($rv); return @files ? @files : ($file); }
Now the problem I'm having and trying to solve: I have an array of links. For each link $l with target $t I want to iterate over the graph and replace any subpath ^$t/.*<code> to be <code>$l/.*. In other words, I want to "fix" the graph to support virtual paths, instead of the physical paths./ (dir) -> /a (dir) /a (dir) -> /a/b (dir) /a/b/ (dir) -> /a/b/c (dir) /a/b/c (dir) -> /a/b/c/file (file) / (dir) -> /p (link) /p (dir) -> /a/b/c (dir)
If you have link /p -> /a/b/c, then you will get:/a/b/c/file1 /a/b/d/e/file2
If the link /p -> /a/b/c is already part of graph, then of course we need to remove it as well./p/file1 /a/b/d/e/file2
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: How to enable virtual paths inside a graph DS?
by etj (Priest) on Apr 24, 2022 at 14:34 UTC | |
by ovedpo15 (Pilgrim) on Apr 26, 2022 at 10:41 UTC | |
by Fletch (Bishop) on Apr 26, 2022 at 14:28 UTC | |
by ovedpo15 (Pilgrim) on Apr 26, 2022 at 20:35 UTC | |
by etj (Priest) on Apr 27, 2022 at 15:54 UTC |