The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Evo::Fs::Class

VERSION

version 0.0235

SYNOPSIS

  use Evo '-Fs::Class; File::Basename fileparse';

  my $orig_fs = Evo::Fs::Class->new;
  my $fs      = $orig_fs->cd('/tmp');    # new Fs with cwd as '/tmp'
  $fs->write('a/foo', 'one');
  $fs->append('a/foo', 'two');
  say $fs->read('a/foo');                # onetwo
  say $fs->read('/tmp/a/foo');           # the same, a/foo resolves to /tmp/a/foo

  # bulk
  $fs->write_many('/tmp/a/foo' => 'afoo', '/tmp/b/foo' => 'bfoo');

  $fs->sysopen(my $fh, '/tmp/c', 'w+');
  $fs->syswrite($fh, "123456");
  $fs->sysseek($fh, 0);
  $fs->sysread($fh, \my $buf, 3);
  say $buf;                              # 123

  $fs->find_files(

    # where to start
    './',

    # do something with file
    sub ($path, $stat) {
      say $path;
    },

    # skip dirs like .git
    sub ($path, $stat) {
      scalar fileparse($path) !~ /^\./;
    }
  );

  $fs->find_files(
    ['/tmp'],
    sub ($path, $stat) {
      say $path;
    }
  );

Virtual testable mockable FileSystem. 11% slower than simple functions, but benefits worth it

cd ($self, $path)

  my $new = $fs->cd('foo/bar');
  say $new->cwd;    # ~/foo/bar
  $new = $fs->cd('foo/bar');
  say $new->cwd;    # ~/foo/bar

Returns new FS with passed cwd

cdm ($self, $path)

Same as "cd" but also calls "make_tree" before

append, write

$fs->write('/tmp/my/file', 'foo'); $fs->append('/tmp/my/file', 'bar'); say $fs->read('/tmp/my/file'); # foobar

Read, write or append a content to the file. Dirs will be created if they don't exist. Use lock 'ex' for append and write and lock 'sh' for read during each invocation

write_many

Write many files using write

sysseek($self, $position, $whence='start')

Whence can be one of:

sysread ($self, $fh, $ref, $length[, $offset])

Calls sysread but accepts scalar reference for convinience

write($self, $fh, $scalar, $length, $offset)

Calls syswrite

sysopen ($self, $fh, $path, $mode)

  $fs->sysopen(my $fh, '/tmp/foo', 'r');

Mode can be one of:

* w Open file for writing. The file is created (if it does not exist) or truncated (if it exists). * wx Like w but fails if path exists. * w+ Open file for reading and writing. The file is created (if it does not exist) or truncated (if it exists). * wx+ Like w+ but fails if path exists.

* a Open file for appending. The file is created if it does not exist. * ax Like a but fails if path exists. * a+ Open file for reading and appending. The file is created if it does not exist. * ax+ Like a+ but fails if path exists.

rename($self, $oldpath, $newpath)

Rename a file.

stat($self, $path)

Return a Evo::Fs::Stat object

to_abs

  my $fs = Evo::Fs::Base->new(cwd => '/foo');
  say $fs->to_abs('bar');    # /foo/bar

Convert relative path to absolute, depending on "cwd" attribute. This is virtual represantion only and "root" doesn't affects the value

cwd

Current working directory which affects relative paths. Should be absolute.

root

Can be used like a chroot in Linux. Should be absolute

path2real($virtual)

Convert a virtual path to the real one.

find_files($self, $dirs, $fn, $pick=undef)

  $fs->find_files('./tmp', sub ($fh, $stat) {...}, sub ($dir, $stat) {...});
  $fs->find_files(['/tmp'], sub ($fh, $stat) {...});

Find files in given directories. You can skip some directories by providing $pick->($dir, $stat) function. This will work ok on circular links, hard links and so on. Every file and it's stat will be passed to $fn->($fh, $stat)only once even if it has many links.

So, in situations, when a file have several hard and symbolic links, only one of them will be passed to $fn, and potentially each time it can be different path for each find_files invocation.

See "traverse" for examining all nodes. This method just decorate it's arguments

traverse($self, $dirs, $fn $pick=undef)

Traverse directories and invokes $fn->$path, $stat for each child node. Pay attention, unlike "find_files", $fn accepts $path, not Evo::Fs::File You can provide $pick->($dir, $stat) to skip directories.

  $fs->traverse('/tmp', sub ($path, $stat) {...}, sub ($dir, $stat) {...});
  $fs->traverse(['/tmp'], sub ($path, $stat) {...},);

Also this method doesn't try to access directories without X and R permissions or pass them to $pick (but such directories will be passed to fn because are regular nodes)

In most cases you may want to use "find_files" instead.

AUTHOR

alexbyk.com

COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by alexbyk.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.