Coder Social home page Coder Social logo

perl6-temp-path's Introduction

NAME

Temp::Path - Make a temporary path, file, or directory

SYNOPSIS

use Temp::Path;

with make-temp-path {
        .spurt: 'meows';
    say .slurp: :bin; # OUTPUT: «Buf[uint8]:0x<6d 65 6f 77 73>␤»
    say .absolute;    # OUTPUT: «/tmp/1E508EE56B7C069B7ABB7C71F2DE0A3CE40C20A1398B45535AF3694E39199E9A␤»
}

with make-temp-path :content<meows> :chmod<423> :suffix<.txt> {
    .slurp.say; # OUTPUT: «meows␤»
    .mode .say; # OUTPUT: «0647␤»
    say .absolute; # OUTPUT «/tmp/8E548EE56B7C119B7ABB7C71F2DE0A3CE40C20A1398B45535AF3694E39199EAE.txt␤»
}

with make-temp-dir {
    .add('meows').spurt: 'I ♥ Perl 6!';
    .dir.say; # OUTPUT: «("/tmp/B42F3C9D8B6A0C5C911EE24DD93DD213F1CE1DD0239263AC3A7D29A2073621A5/meows".IO)␤»
}

{
    temp $*TMPDIR = make-temp-dir :chmod<0o700>;
    $*TMPDIR.say;
    # OUTPUT:
    # "/tmp/F5AA112627DA7B59C038900A3C8C7CB05477DCCCEADF2DC447EC304017A1009E".IO

    say make-temp-path;
    # OUTPUT:
    # "/tmp/F5AA112627DA7B59C038900A3C8C7CB05477DCCCEADF2DC447EC304017A1009E/…
    # …C41E7114DD24C65C6722981F8C5693E762EBC5958238E23F7B324A1BDD37A541".IO
}

EXPORTED TERMS

This module exports terms (not subroutines), so you don't need to use parentheses to avoid block gobbling errors. Just use these same way as you'd use constant π

If you have to use parens for some reason, make them go around the whole them, not just the args:

make-temp-path(:content<foo> :chmod<423>) # WRONG
(make-temp-path :content<foo> :chmod<423>) # RIGHT

make-temp-path

Defined as:

sub term:<make-temp-path> (
    :$content where Any|Blob:D|Cool:D,
    Int :$chmod,
    Str() :$prefix = '',
    Str() :$suffix = ''
    --> IO::Path:D
)

Creates an IO::Path object pointing to a path inside $*TMPDIR that will be deleted (see DETAILS OF DELETION section below).

Unless :$chmod or :$content are given, no files will be created. If :$chmod is given a file containing :$content (or empty, if no :$content is given) will be created with $chmod permissions. If :$content is given without :$chmod, the mode will be the default resulting from files created with IO::Handle.open.

The basename of the path is currently a SHA256 hash, but your program should not make assumptions about the format of the basename.

Security Note: at the moment, :chmod is set after the file is created and its content is written. This will be fixed once a way to create a file with a specific mode is available in Rakudo. While it will work at the moment, it might not be the best idea to assume :$content will be successfully written if you set :$chmod that does not let the current process write to the file.

make-temp-dir

Defined as:

sub term:<make-temp-dir> (Int :$chmod, Str() :$prefix = '', Str() :$suffix = '' --> IO::Path:D)

Creates a directory inside $*TMPDIR that will be deleted (see DETAILS OF DELETION section below) and returns the IO::Path object pointing to it.

If :$chmod is provided, the directory will be created with that mode. Otherwise, the default .mkdir mode will be used.

Note that currently .mkdir pays attention to umask and make-temp-dir will first the :$chmod to .mkdir, to create umask masked directory, and then it will .chmod it, to remove the effects of the umask.

DETAILS OF DELETION

The deletion of files created by this module will happen either when the returned IO::Path objects are garbage collected or when the END phaser gets run. Note that this means temporary files/directories may be left behind if your program crashes or gets aborted.

The temporary IO::Path objects created by make-temp-path and make-temp-dir terms have a role Temp::Path::AutoDel mixed in that will rmtree or .unlink the filesystem object the path points to.

Note that deletion will happen only if the path was created by this module. For example doing make-temp-dir.sibling: 'foo' will still give you an IO::Path with Temp::Path::AutoDel mixed in due to how IO::Path methods create new objects. But new objects created by .sibling, .add, .child, .parent, etc won't be deleted, when the object gets garbage collected, because you created it and not the module. Of course, when a parent directory, that was created by this module gets deleted, all its contents that you created with .child gets removed from the disk. Siblings need to be removed manually.

REPOSITORY

Fork this module on GitHub: https://github.com/ufobat/perl6-Temp-Path

BUGS

To report bugs or request features, please use https://github.com/ufobat/perl6-Temp-Path/issues

AUTHOR

LICENSE

You can use and distribute this module under the terms of the The Artistic License 2.0. See the LICENSE file included in this distribution for complete details.

The META6.json file of this distribution may be distributed and modified without restrictions or attribution.

perl6-temp-path's People

Contributors

alexdaniel avatar ba01m avatar kivikakk avatar pheix avatar ufobat avatar zoffixznet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

pheix

perl6-temp-path's Issues

Please "git tag" your RAKU modules with it's versions

Can you please "GIT TAG" your RAKU modules with it's version, similar and at the same time you maintain it's "version": "x.y.z" in your META6.json file?

I was told, this will happen "for free" going forward with mi6 anyhow, but for now it would be great if you spend those 2 seconds already now :)

"Tagging" is generally highly appreciated in regards to "reproducible builds" and here especially for the "Rakudo Star" modules

THANK YOU!

Sometimes directories don't get deleted

While using this module i realized that directories (with their content) don't get deleted. It doesn't happen all the time so it's some kind of race condition.

specify filename suffixes

I am using this module in combination with tools like convert and tesseract. In those tools the filename suffix is important.

question regarding deletion of directories (and their content)

When you create a temp path or dir you get an $object of IO::Path. As soon as the GC cleans the $object up the 'delete' command gets invoked, removing the directory and all it's content.

Assuming following code:

sub make-file(--> IO::Path) {
    my $dir = make-temp-dir;
    my $file = $dir.add('my file');
    return $file;      # $dir runs out of scope and DESTROY would probably be called soon.
}

my $file = make-file;
$file.spurt: $data;

# do something else
# as soon as GC runs and cleans up `$dir`, your `$file` gets removed from disk.
  1. I am wondering whether it makes sense to use a BagHash instead of the SetHash and count the number of files you have created (with methods on the original $dir, or objects that were created this way). Creating an object would cause the counter to increase, Destroying an object would cause the counter do decrease. If the counter is 0, the file get's nuked.

  2. You rely on the mechanism of how IO::Path creates new objects. eg my $file = $dir.add: 'foo'; because you keep the mixin that way. There is a way to "untie (=remove the mixin)" this. But this is not documented.

$ perl6 -e 'use Temp::Path; my $dir = make-temp-dir; my $file = $dir.add: "foo"; my $untied = IO::Path.new($file); for ($dir, $file, $u ntied) { .WHICH.say }'
IO::Path+{Temp::Path::AutoDel[IO::Path]}\|178195712 
IO::Path+{Temp::Path::AutoDel[IO::Path]}\|178195792 
IO::Path\|178195872

if you created a file somehow manually, there is no (obvious) way to "tie" this to the (temp) $dir again?

Flopping tests

===> Testing: Temp::Path:ver('1.001001')
Testing with plugin: Zef::Service::TAP+{<anon|85479024>}
t/01-make-temp-path.t .. ok
t/02-make-temp-dir.t ... ok
t/03-DESTROY.t ......... All 4 subtests passed 
t/04-to-IO-Path.t ...... ok
t/meta.t ............... ok
All tests successful.

Test Summary Report
-------------------
t/03-DESTROY.t  (Wstat: 11 Tests: 3 Failed: 0)
Non-zero wait status: 11
  Parse errors: Bad plan.  You planned 4 tests but ran 3.
Files=5, Tests=52,  12 wallclock secs
Result: FAILED
===> Testing [FAIL]: Temp::Path:ver('1.001001')
Reporting with plugin: Zef::CPANReporter+{<anon|85479024>}
Use of uninitialized value of type Zef::CPANReporter in string context.
Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful.
  in method report at /home/cpan/.rakudobrew/moar-nom/install/share/perl6/site/sources/643D88410EFE62A5D6F3C68A2811502A3DD01FF4 (Zef::CPANReporter) line 18
Aborting due to test failure: Temp::Path:ver('1.001001') (use --force-test to override)
  in code  at /home/cpan/.rakudobrew/moar-nom/install/share/perl6/site/sources/5CBAAFEFAAB1740958A5BF3BCD5E24C04D43EEB5 (Zef::Client) line 373
  in method test at /home/cpan/.rakudobrew/moar-nom/install/share/perl6/site/sources/5CBAAFEFAAB1740958A5BF3BCD5E24C04D43EEB5 (Zef::Client) line 351
  in code  at /home/cpan/.rakudobrew/moar-nom/install/share/perl6/site/sources/5CBAAFEFAAB1740958A5BF3BCD5E24C04D43EEB5 (Zef::Client) line 528
  in sub  at /home/cpan/.rakudobrew/moar-nom/install/share/perl6/site/sources/5CBAAFEFAAB1740958A5BF3BCD5E24C04D43EEB5 (Zef::Client) line 525
  in method install at /home/cpan/.rakudobrew/moar-nom/install/share/perl6/site/sources/5CBAAFEFAAB1740958A5BF3BCD5E24C04D43EEB5 (Zef::Client) line 631
  in sub MAIN at /home/cpan/.rakudobrew/moar-nom/install/share/perl6/site/sources/EC4CB3A653760AFCB434D28800A3F559EA8634E0 (Zef::CLI) line 152
  in block <unit> at /home/cpan/.rakudobrew/moar-nom/install/share/perl6/site/resources/007D5E5A61B87BAA8B85A58771E235214AFADB77 line 1

cpan@toaster:~/toaster$ 

Some exceptions were thrown in END blocks: "Cannot send a message on a closed channel"

Saw this happen on more than one occasion. The module seems to install fine but installation shows this message:

===> Testing: zef:ver<0.2.9>:auth<github:ugexe>
===> Testing [OK] for zef:ver<0.2.9>:auth<github:ugexe>
===> Installing: zef:ver<0.2.9>:auth<github:ugexe>
1 bin/ script [zef] installed to:
/home/zoffix/R/install/share/perl6/site/bin
===> Searching for: Inline::Perl5
===> Updated cpan mirror: https://raw.githubusercontent.com/ugexe/Perl6-ecosystems/master/cpan.json
===> Updated p6c mirror: http://ecosystem-api.p6c.org/projects.json
===> Found: Inline::Perl5:ver<0.32>:auth<github:niner> [via Zef::Repository::Ecosystems<cpan>]
===> Dependencies: LibraryMake, File::Temp
===> Searching for missing dependencies: LibraryMake, File::Temp
===> Found dependencies: LibraryMake:ver<1.0.0>:auth<github:retupmoca>, File::Temp:ver<0.0.6> [via Zef::Repository::Ecosystems<p6c>]
===> Dependencies: Shell::Command, File::Directory::Tree, Test
===> Searching for missing dependencies: Shell::Command, File::Directory::Tree
===> Found dependencies: Shell::Command, File::Directory::Tree:auth<labster> [via Zef::Repository::Ecosystems<p6c>]
===> Dependencies: File::Which, File::Find, Test
===> Searching for missing dependencies: File::Which, File::Find
===> Found dependencies: File::Which:ver<1.0.1>, File::Find:ver<0.1> [via Zef::Repository::Ecosystems<p6c>]
===> Dependencies: Test
===> Fetching: Inline::Perl5
Fetching with plugin: Zef::Service::Shell::curl+{<anon|1>}
===> Fetching [OK]: Inline::Perl5:ver<0.32>:auth<github:niner> to /home/zoffix/.zef/tmp/1524869141.31573.7740/Inline-Perl5-0.32.tar.gz
===> Fetching: LibraryMake
Fetching with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Fetching [OK]: LibraryMake:ver<1.0.0>:auth<github:retupmoca> to /home/zoffix/.zef/tmp/1524869141.31573.398/P6-LibraryMake.git
===> Fetching: File::Temp
Fetching with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Fetching [OK]: File::Temp:ver<0.0.6> to /home/zoffix/.zef/tmp/1524869142.31573.7347/p6-File-Temp.git
===> Fetching: Shell::Command
Fetching with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Fetching [OK]: Shell::Command to /home/zoffix/.zef/tmp/1524869142.31573.2273/Shell-Command.git
===> Fetching: File::Directory::Tree
Fetching with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Fetching [OK]: File::Directory::Tree:auth<labster> to /home/zoffix/.zef/tmp/1524869143.31573.4761/p6-file-directory-tree.git
===> Fetching: File::Which
Fetching with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Fetching [OK]: File::Which:ver<1.0.1> to /home/zoffix/.zef/tmp/1524869143.31573.2731/perl6-file-which.git
===> Fetching: File::Find
Fetching with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Fetching [OK]: File::Find:ver<0.1> to /home/zoffix/.zef/tmp/1524869144.31573.7725/File-Find.git
===> Extracting: Inline::Perl5
Extracting with plugin: Zef::Service::Shell::tar+{<anon|1>}
===> Extraction [OK]: Inline::Perl5 to /home/zoffix/.zef/store/Inline-Perl5-0.32.tar.gz
===> Extracting: LibraryMake
Extracting with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Extraction [OK]: LibraryMake to /home/zoffix/.zef/store/P6-LibraryMake.git
===> Extracting: File::Temp
Extracting with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Extraction [OK]: File::Temp to /home/zoffix/.zef/store/p6-File-Temp.git
===> Extracting: Shell::Command
Extracting with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Extraction [OK]: Shell::Command to /home/zoffix/.zef/store/Shell-Command.git
===> Extracting: File::Directory::Tree
Extracting with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Extraction [OK]: File::Directory::Tree to /home/zoffix/.zef/store/p6-file-directory-tree.git
===> Extracting: File::Which
Extracting with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Extraction [OK]: File::Which to /home/zoffix/.zef/store/perl6-file-which.git
===> Extracting: File::Find
Extracting with plugin: Zef::Service::Shell::git+{<anon|1>}
===> Extraction [OK]: File::Find to /home/zoffix/.zef/store/File-Find.git
===> Filtering: Inline::Perl5:ver<0.32>:auth<github:niner>
===> Filtering [OK] for Inline::Perl5:ver<0.32>:auth<github:niner>
===> Filtering: LibraryMake:ver<1.0.0>:auth<github:retupmoca>
===> Filtering [OK] for LibraryMake:ver<1.0.0>:auth<github:retupmoca>
===> Filtering: File::Temp:ver<0.0.6>
===> Filtering [OK] for File::Temp:ver<0.0.6>
===> Filtering: Shell::Command
===> Filtering [OK] for Shell::Command
===> Filtering: File::Directory::Tree:auth<labster>
===> Filtering [OK] for File::Directory::Tree:auth<labster>
===> Filtering: File::Which:ver<1.0.1>
===> Filtering [OK] for File::Which:ver<1.0.1>
===> Filtering: File::Find:ver<0.1>
===> Filtering [OK] for File::Find:ver<0.1>
===> # SKIP: No need to build File::Which:ver<1.0.1>
===> # SKIP: No need to build File::Find:ver<0.1>
===> # SKIP: No need to build Shell::Command
===> # SKIP: No need to build LibraryMake:ver<1.0.0>:auth<github:retupmoca>
===> # SKIP: No need to build File::Directory::Tree:auth<labster>
===> # SKIP: No need to build File::Temp:ver<0.0.6>
===> Building: Inline::Perl5:ver<0.32>:auth<github:niner>
Building with plugin: Zef::Service::Shell::LegacyBuild+{<anon|1>}
Command: /home/zoffix/R/install/bin/perl6 -Ilib -I/home/zoffix/.zef/store/P6-LibraryMake.git/9d953275df44c239e0ef89d1538bbbf1f74ef538/lib -I/home/zoffix/.zef/store/Shell-Command.git/a0f1d295f80777f5809af452b85ff80feb648e3b/lib -I/home/zoffix/.zef/store/perl6-file-which.git/1dfbeba2f92f8b2b04e8b26619eb20d599198d25/lib -I/home/zoffix/.zef/store/File-Find.git/5754d97b25cbf3b6abe997a9d829eac4e5aba7d9/lib -I/home/zoffix/.zef/store/p6-File-Temp.git/7f128adc5bbad8d172f87e868c52eb85339fc90f/lib -I/home/zoffix/.zef/store/p6-file-directory-tree.git/25faef927c83eea1b688b5a324d5e11011f7305f/lib -e require '/home/zoffix/.zef/store/Inline-Perl5-0.32.tar.gz/Inline-Perl5-0.32/Build.pm'; ::('Build').new.build('/home/zoffix/.zef/store/Inline-Perl5-0.32.tar.gz/Inline-Perl5-0.32') ?? exit(0) !! exit(1);
make: Nothing to be done for `all'.
===> Building [OK] for Inline::Perl5:ver<0.32>:auth<github:niner>
===> Installing: File::Which:ver<1.0.1>
===> Install [OK] for File::Which:ver<1.0.1>
===> Installing: File::Find:ver<0.1>
===> Install [OK] for File::Find:ver<0.1>
===> Installing: Shell::Command
===> Install [OK] for Shell::Command
===> Installing: LibraryMake:ver<1.0.0>:auth<github:retupmoca>
===> Install [OK] for LibraryMake:ver<1.0.0>:auth<github:retupmoca>
===> Installing: File::Directory::Tree:auth<labster>
===> Install [OK] for File::Directory::Tree:auth<labster>
===> Installing: File::Temp:ver<0.0.6>
===> Install [OK] for File::Temp:ver<0.0.6>
===> Installing: Inline::Perl5:ver<0.32>:auth<github:niner>
===> Install [OK] for Inline::Perl5:ver<0.32>:auth<github:niner>
Some exceptions were thrown in END blocks:
  X::Channel::SendOnClosed+{X::Await::Died}: Cannot send a message on a closed channel
      in submethod DESTROY at /home/zoffix/rakudo/install/share/perl6/site/sources/67C5BEF16E4683C939CFFCE2193ED799313B12F7 (Temp::Path) line 39
      in block  at /home/zoffix/rakudo/install/share/perl6/site/sources/67C5BEF16E4683C939CFFCE2193ED799313B12F7 (Temp::Path) line 7

2018.03.265 zoffix@VirtualBox~$ 
2018.03.265 zoffix@VirtualBox~/R/rakudo (master)$ ./perl6 -v
This is Rakudo version 2018.04-20-g7847768ca built on MoarVM version 2018.04-34-g25f165ad7
implementing Perl 6.c.
2018.03.265 zoffix@VirtualBox~/R/rakudo (master)$ uname -a
Linux VirtualBox 4.2.0-30-generic #36~14.04.1-Ubuntu SMP Fri Feb 26 18:49:23 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
2018.03.265 zoffix@VirtualBox~/R/rakudo (master)$ perl -v

This is perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-multi
(with 1 registered patch, see perl -V for more detail)

Copyright 1987-2017, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

2018.03.265 zoffix@VirtualBox~/R/rakudo (master)$ 

Make better error message

For when the program crashes for some reason.

"Unhandled exception: Cannot send a message on a closed channel" muddies the output.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.