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}1.pl";
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 ");
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.
| [reply] [d/l] [select] |
|
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;
| [reply] [d/l] [select] |
|
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. | [reply] [d/l] |
|
|