App-DistSync
view release on metacpan or search on metacpan
lib/App/DistSync/Util.pm view on Meta::CPAN
Show debug information to STDERR
=head2 fdelete
my $status = fdelete( $file );
Deleting a file if it exists
=head2 manifind
my $files_struct = manifind($dir); # { ... }
Read direactory and returns file structure
=head2 maniread
my $mani_struct = maniread($file, skipflag); # { ... }
Read file as manifest and returns hash structure
=head2 maniwrite
maniwrite($file, $mani_struct);
This function writes manifest structure to manifest file
=head2 qrreconstruct
my $r = qrreconstruct('!!perl/regexp (?i-xsm:^\s*(error|fault|no))');
# Translate to:
# qr/^\s*(error|fault|no)/i
Returns regular expression (QR) by perl/regexp string. YAML form of definition
my $r = qrreconstruct('perl/regexp (?i-xsm:^\s*(error|fault|no))');
# Translate to:
# qr/^\s*(error|fault|no)/i
Not-YAML form of definition
my $r = qrreconstruct('regexp (?i-xsm:^\s*(error|fault|no))');
# Translate to:
# qr/^\s*(error|fault|no)/i
Short form of definition
See also L<YAML::Type/regexp> of L<YAML::Types>
=head2 read_yaml
my $yaml = read_yaml($yaml_file);
Read YAML file
=head2 slurp
my $data = slurp($file, %args);
my $data = slurp($file, { %args });
slurp($file, { buffer => \my $data });
my $data = slurp($file, { binmode => ":raw:utf8" });
Reads file $filename into a scalar
my $data = slurp($file, { binmode => ":unix" });
Reads file in fast, unbuffered, raw mode
my $data = slurp($file, { binmode => ":unix:encoding(UTF-8)" });
Reads file with UTF-8 encoding
By default it returns this scalar. Can optionally take these named arguments:
=over 4
=item binmode
Set the layers to read the file with. The default will be something sensible on your platform
=item block_size
Set the buffered block size in bytes, default to 1048576 bytes (1 MiB)
=item buffer
Pass a reference to a scalar to read the file into, instead of returning it by value.
This has performance benefits
=back
See also L</spew> to writing data to file
=head2 spew
spew($file, $data, %args);
spew($file, $data, { %args });
spew($file, \$data, { %args });
spew($file, \@data, { %args });
spew($file, $data, { binmode => ":raw:utf8" });
Writes data to a file atomically. The only argument is C<binmode>, which is passed to
C<binmode()> on the handle used for writing.
Can optionally take these named arguments:
=over 4
=item append
This argument is a boolean option, defaulted to false (C<0>).
Setting this argument to true (C<1>) will cause the data to be be written at the end of the current file.
Internally this sets the sysopen mode flag C<O_APPEND>
=item binmode
Set the layers to write the file with. The default will be something sensible on your platform
=item locked
This argument is a boolean option, defaulted to false (C<0>).
Setting this argument to true (C<1>) will ensure an that existing file will not be overwritten
=item mode
This numeric argument sets the default mode of opening files to write.
By default this argument to C<(O_WRONLY | O_CREAT)>.
Please DO NOT set this argument unless really necessary!
=item perms
This argument sets the permissions of newly-created files.
This value is modified by your process's umask and defaults to 0666 (same as sysopen)
=back
See also L</slurp> to reading data from file
=head2 tms
print tms();
This function returns current time and PID in format, for eg.:
[Sat Dec 6 19:09:54 2025] [533052]
=head2 touch
touch( "file" ) or die "Can't touch file";
Makes file exist, with current timestamp
See L<ExtUtils::Command>
=head2 write_yaml
write_yaml($yaml_file, $yaml);
Write YAML file
=head1 HISTORY
See C<Changes> file
=head1 TO DO
See C<TODO> file
=head1 SEE ALSO
L<LWP::Simple>
=head1 AUTHOR
Serż Minus (Sergey Lepenkov) L<https://www.serzik.com> E<lt>abalama@cpan.orgE<gt>
lib/App/DistSync/Util.pm view on Meta::CPAN
i => sub { qr{$_[0]}i },
s => sub { qr{$_[0]}s },
m => sub { qr{$_[0]}m },
ix => sub { qr{$_[0]}ix },
sx => sub { qr{$_[0]}sx },
mx => sub { qr{$_[0]}mx },
si => sub { qr{$_[0]}si },
mi => sub { qr{$_[0]}mi },
ms => sub { qr{$_[0]}sm },
six => sub { qr{$_[0]}six },
mix => sub { qr{$_[0]}mix },
msx => sub { qr{$_[0]}msx },
msi => sub { qr{$_[0]}msi },
msix => sub { qr{$_[0]}msix },
},
};
sub debug {
return unless $DEBUG;
my $txt = (scalar(@_) == 1) ? shift(@_) : sprintf(shift(@_), @_);
warn $txt, "\n";
return 1;
}
sub tms { sprintf "[%s] [%d]", scalar(localtime(time())), $$ }
sub qrreconstruct { # See app/paysrelay
# Returns regular expression (QR)
# Gets from YAML::Type::regexp of YAML::Types
# To input:
# !!perl/regexp (?i-xsm:^\s*(error|fault|no))
# Translate to:
# qr/^\s*(error|fault|no)/i
my $v = shift;
return undef unless defined $v;
return $v unless $v =~ /^\s*\!{0,2}(perl\/)?regexp\s*/i;
$v =~ s/\s*\!{0,2}(perl\/)?regexp\s*//i;
return qr{$v} unless $v =~ /^\(\?([\^\-uxism]*):(.*)\)\z/s;
my ($flags, $re) = ($1, $2);
$flags =~ s/-.*//; # remove all after '-'
$flags =~ s/^\^//; # remove start-symbol
$flags =~ tr/u//d; # remove u modifier
my $sub = QRTYPES->{$flags} || sub { qr{$_[0]} };
return $sub->($re);
}
sub slurp {
my $file = shift // '';
my $args = @_ ? @_ > 1 ? {@_} : {%{$_[0]}} : {};
return unless length($file) && -r $file;
my $cleanup = 1;
# Open filehandle
my $fh;
if (ref($file)) {
$fh = $file;
$cleanup = 0; # Disable closing filehandle for passed filehandle
} else {
$fh = IO::File->new($file, "r");
unless (defined $fh) {
carp qq/Can't open file "$file": $!/;
return;
}
}
# Set binmode layer
my $bm = $args->{binmode} // ':raw'; # read in :raw by default
$fh->binmode($bm);
# Set buffer
my $buf;
my $buf_ref = $args->{buffer} // \$buf;
${$buf_ref} = ''; # Set empty string to buffer
my $blk_size = $args->{block_size} || 1024 * 1024; # Set block size (1 MiB)
# Read whole file
my ($pos, $ret) = (0, 0);
while ($ret = $fh->read(${$buf_ref}, $blk_size, $pos)) {
$pos += $ret if defined $ret;
}
unless (defined $ret) {
carp qq/Can't read from file "$file": $!/;
return;
}
# Close filehandle
$fh->close if $cleanup; # automatically closes the file
# Return content if no buffer specified
return if defined $args->{buffer};
return ${$buf_ref};
}
sub spew {
my $file = shift // '';
my $data = shift // '';
my $args = @_ ? @_ > 1 ? {@_} : {%{$_[0]}} : {};
my $cleanup = 1;
# Get binmode layer, mode and perms
my $bm = $args->{binmode} // ':raw'; # read in :raw by default
my $perms = $args->{perms} // 0666; # set file permissions
my $mode = $args->{mode} // O_WRONLY | O_CREAT;
$mode |= O_APPEND if $args->{append};
$mode |= O_EXCL if $args->{locked};
# Open filehandle
my $fh;
if (ref($file)) {
$fh = $file;
$cleanup = 0; # Disable closing filehandle for passed filehandle
} else {
$fh = IO::File->new($file, $mode, $perms);
unless (defined $fh) {
carp qq/Can't open file "$file": $!/;
return;
}
}
# Set binmode layer
$fh->binmode($bm);
# Set buffer
my $buf;
my $buf_ref = \$buf;
if (ref($data) eq 'SCALAR') {
$buf_ref = $data;
} elsif (ref($data) eq 'ARRAY') {
${$buf_ref} = join '', @$data;
} else {
$buf_ref = \$data;
}
# Seek, print, truncate and close
$fh->seek(0, SEEK_END) if $args->{append}; # SEEK_END == 2
$fh->print(${$buf_ref}) or return;
$fh->truncate($fh->tell) if $cleanup;
$fh->close if $cleanup;
return 1;
}
sub touch {
my $fn = shift // '';
return 0 unless length($fn);
my $t = time;
my $ostat = open my $fh, '>>', $fn;
unless ($ostat) {
printf STDERR "Can't touch file \"%s\": %s\n", $fn, $!;
return 0;
}
close $fh if $ostat;
utime($t, $t, $fn);
return 1;
}
sub fdelete {
my $file = shift;
return 0 unless defined $file && -e $file;
unless (unlink($file)) {
printf STDERR "Can't delete file \"%s\": %s\n", $file, $!;
return 0;
}
return 1;
}
sub read_yaml {
my $file = shift;
return [] unless defined $file;
return [] unless (-e $file) && -r $file;
my $yaml = YAML::Tiny->new;
my $data = $yaml->read($file);
return [] unless $data;
return $data;
}
sub write_yaml {
my $file = shift;
my $data = shift;
return 0 unless defined $file;
return 0 unless defined $data;
my $yaml = YAML::Tiny->new($data);
$yaml->write($file);
return 1;
}
sub maniread { # Reading data from MANEFEST, MIRRORS and MANEFEST.* files
# Original see Ext::Utils::maniread
my $mfile = shift;
( run in 2.767 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )