Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re^4: shedding a bash wrapper and updating to Path::Tiny

by kevbot (Priest)
on Jul 13, 2018 at 05:49 UTC ( #1218421=note: print w/replies, xml ) Need Help??

in reply to Re^3: shedding a bash wrapper and updating to Path::Tiny
in thread shedding a bash wrapper and updating to Path::Tiny

Hello Datz_cozee75,

Here are a few comments.

  • Path::Tiny has a method for getting the absolute path of the current working directory, so path(".")->absolute; with  Path::Tiny->cwd;
  • You do not need to quote the variables when you create a new path, so code like this path( "$current", "$to", "$ts" ) can be changed to code like this path( $current, $to, $ts )
  • You do not need to use stringify on a path before printing it, so code like this say "string abs from is $string_abs_from"; can be changed to use the variable that contains the Path::Tiny object like this say "string abs from is $abs_from";. Generally, Path::Tiny objects will stringify on their own when necessary. However, there may be times when you are passing a Path::Tiny object to another method (for example, a method from a different CPAN package) you may sometimes need to stringify the path first.
  • I like to use named variables in my foreach loops, so I made some changes to reflect this.
  • The Path::Tiny children method can be given an argument of a regular expression, where only children that match the regular expression are returned. This allowed me to simplify your code a bit.

Here is the modified code. Please note that this code is untested and I did this quickly, so it may need some small adjustments and there may be some typos. Please be sure that you have a backup of your data before running this code.

#!/usr/bin/perl -w use strict; use 5.010; use utf8; use open qw/:std :utf8/; use Path::Tiny; my %vars = ( place => 'Vancouver', book => 'Медитац&# +1080;я на perlем', chapter => 'populated title', print_module => 1, script_file => undef, server_dir => 'perlmonks', image_dir => 'pmimage', ); # This script clones the template directory in $1 to $2. # Some names need munging. # $from is a populated child directory; $to is child dir to be create +d. $pop is the folder with the data. my ( $from, $to, $pop ) = @ARGV; my $ts = "template_stuff"; my $current = Path::Tiny->cwd; #say "current is $current"; say "-------------"; say "making directories"; # define the paths within the target directory: my $abs_to = path( $current, $to, $ts ); $abs_to->mkpath; say "abs to template is $abs_to"; # $from template directory: my $abs_from = path( $current, $from, $ts ); say "string abs from is $abs_from"; say "-------------"; say "copying files"; foreach my $child ( $abs_from->children(qr/\.(txt|pm|css|tmpl|pl|sh)$/ +) { next unless $child->is_file; my $base = $child->basename; #syntax is from to to my $return = path($child)->copy( $abs_to, $base ); if ($base =~ m/\.(pl|sh)$/) { $return->chmod(0755); } say "return is $return"; } say "-------------"; # copy css file to template with munged name foreach my $child ( $abs_from->children ) { my $base = $child->basename; if ( $base =~ m/^$from(\d*)\.css$/ ) { #say "matching is $base"; say "dollar one is $1"; my $munge = $to . "1" . ".css"; say "munge is $munge"; my $name = path( $abs_to, $munge ); say "name is $name"; #syntax is from to to my $return = path( $abs_from, $base )->copy($name); say "return2 is $return"; } } ## munge and copy executable, change permissions say "-------------"; my $d = path( $current, $from ); # @matching will be an array of Path::Tiny objects my @matching = $d->children(qr/$from(\d*)\.pl$/i); @matching = sort @matching; say "matched is @matching"; my $winner = pop @matching; my $newfile = "${to}"; my $b = path( $current, $to, $newfile ); print "b is $b\n"; # $winner will already be a Path::Tiny object my $return3 = $winner->copy("$b"); say "return3 is $return3"; $return3->chmod(0755); say "end of clone"; my $path = path(qw(master_list 2013 North_America)); # prints 'master_list/2013/North_America'; say $path; # prints 'master_list/2013/North_America' on unix, # 'master_list\2013\North_America' on win32 say $path->canonpath; # prints /home/santa/master_list/2013/North_America when $CWD is /home +/santa say $path->absolute; # prints 'master_list/2013' say $path->parent; # prints 'master_list/2013/North_America/Vancouver/ETHER' say $path->child( 'Vancouver', 'ETHER' ); my $tempdir = Path::Tiny->tempdir('delivery_list_XXXXXX'); my $tempfile = Path::Tiny->tempfile( TEMPLATE => 'delivery_list_XXXXXX', suffix => +'.bin' ); my $scratch_file = $tempdir->child( 'batch_01', 'scratchfile.txt' )->t +ouchpath; chdir $tempdir unless $tempdir->subsumes( Path::Tiny->cwd ); system("pwd &"); my $abs_pop = path( $current, $pop, $ts ); say "string abs pop is $abs_pop"; foreach my $child ( $abs_pop->children ) { next $child->is_dir; say "e is $child"; my $base_dir = $child->basename; say "base dir is $base_dir"; my $folder = path( $current, $to, $ts, $base_dir )->mkpath; say "folder is $folder"; say "string folder is $folder"; my $pop_from = $child; next if( $child =~ m/logs/; foreach $pchild ( $pop_from->children ) { say "default is $pchild\n"; my $base = $pchild->basename; say "base is $base"; my $to_name = path( $folder, $base ); say "to name is $to_name"; my $return4 = path($pchild)->copy($to_name); say "return4 is $return4"; } } my $exec_path = path( $current, $to ); my $return5 = chdir($exec_path); say "return5 is $return5"; system("pwd "); system("ls "); system ("./$newfile ");

Replies are listed 'Best First'.
Re^5: shedding a bash wrapper and updating to Path::Tiny
by Aldebaran (Curate) on Jul 25, 2018 at 05:45 UTC

    Thx kevbot, this script really added a lot of polish to the Path::Tiny idioms, but I could not get away from stringifying one line. After you make the method call to mkdir, it's gonna return 1 if successful, so the line with the mkdir call isn't any good for building a path in subsequent path statements. First is the script and then the output:

    Resulting html page shows successful cloning. I appreciate your comments, and my humble script is vastly-improved over the lifetime of this thread.

      Hello Datz_cozee75,

      I'm glad you found my post helpful. I don't see mkdir used anywhere in your code. When you refer to mkdir, I assume you are referring to the mkpath method from Path::Tiny that you use in a couple places (not to be confused with the perl function mkdir). So, code like this may need to be changed to do what you want...

      my $folder = path( $current, $to, $ts, $base_dir )->mkpath;
      The documentation for the Path::Tiny mkpath method states that it returns the list of directories created or an empty list if the directories already exist, just like make_path.. So perhaps this would be more useful,
      my $folder_path = path( $current, $to, $ts, $base_dir ); $folder_path->mkpath; # This will print the path regardless if the path already existed or n +ot print "My folder path is $folder_path\n";
      If you wanted to check the return value of the mkpath method, you could store it in a scalar like this,
      my $mkpath_return_value = $folder_path->mkpath; # The value of $mkpath_return_value will be equal to the number of dir +s created (since the return value will be a list that is forced into # scalar context), or it will be equal to zero if the path already exi +sted.
      or if you wanted the list of dirs that were created you could do this,
      my @dirs = $folder_path->mkpath;

        Gosh, kevbot, I try to be done making mistakes for one thread, so I hope that we can address this last one. Indeed, in my write-up I did conflate perl's mkdir with Path::Tiny's mkpath method. When one uses the latter in list context, one can build subsequent paths with it:

        my @dirs = path( $current, $to, $ts, $base_dir )->mkpath; say "dirs are @dirs"; foreach my $pchild ( $pop_from->children ) { my $base = $pchild->basename; say "base is $base"; my $to_name = path( @dirs, $base );

        I didn't find all that many examples for using Path::Tiny out there, so let's hope that others get something out of this.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1218421]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2022-09-28 23:37 GMT
Find Nodes?
    Voting Booth?
    I prefer my indexes to start at:

    Results (125 votes). Check out past polls.