Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
add open method and tempfile function to Mojo::File
  • Loading branch information
kraih committed Feb 5, 2017
1 parent 3b6e848 commit 49f3f78
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 30 deletions.
4 changes: 3 additions & 1 deletion Changes
@@ -1,5 +1,7 @@

7.24 2017-02-04
7.24 2017-02-05
- Added open method to Mojo::File.
- Added tempfile function to Mojo::File.

7.23 2017-01-29
- Added max_request_size attribute to Mojolicious.
Expand Down
34 changes: 11 additions & 23 deletions lib/Mojo/Asset/File.pm
Expand Up @@ -2,38 +2,26 @@ package Mojo::Asset::File;
use Mojo::Base 'Mojo::Asset';

use Carp 'croak';
use Errno 'EEXIST';
use Fcntl qw(O_APPEND O_CREAT O_EXCL O_RDONLY O_RDWR);
use Fcntl qw(SEEK_SET);
use File::Spec::Functions ();
use IO::File;
use Mojo::File;
use Mojo::Util 'md5_sum';
use Mojo::File 'tempfile';

has [qw(cleanup path)];
has handle => sub {
my $self = shift;

# Enable automatic cleanup if the file has to be created
my $path = $self->path;
$self->cleanup(1) if !defined $self->cleanup && (!defined $path || !-e $path);

# Open existing file
my $handle = IO::File->new;
my $path = $self->path;
if (defined $path && -f $path) {
$handle->open($path, O_RDONLY) or croak qq{Can't open file "$path": $!};
return $handle;
}
return Mojo::File->new($path)->open(-e $path ? '<' : '+>>') if defined $path;

# Open new or temporary file
my $base = Mojo::File->new($self->tmpdir, 'mojo.tmp')->to_string;
my $name = $path // $base;
until ($handle->open($name, O_APPEND | O_CREAT | O_EXCL | O_RDWR)) {
croak qq{Can't open file "$name": $!} if defined $path || $! != $!{EEXIST};
$name = "$base." . md5_sum(time . $$ . rand);
}
$self->path($name);

# Enable automatic cleanup
$self->cleanup(1) unless defined $self->cleanup;

return $handle;
my $template = 'mojo.tmp.XXXXXXXXXXXXXXXX';
my $file = tempfile DIR => $self->tmpdir, TEMPLATE => $template, UNLINK => 0;
$self->path($file->to_string);
return $file->open('+>>');
};
has tmpdir => sub { $ENV{MOJO_TMPDIR} || File::Spec::Functions::tmpdir };

Expand Down
33 changes: 30 additions & 3 deletions lib/Mojo/File.pm
Expand Up @@ -16,9 +16,10 @@ use File::Path ();
use File::Spec::Functions
qw(abs2rel canonpath catfile file_name_is_absolute rel2abs splitdir);
use File::Temp ();
use IO::File;
use Mojo::Collection;

our @EXPORT_OK = ('path', 'tempdir');
our @EXPORT_OK = ('path', 'tempdir', 'tempfile');

sub basename { scalar File::Basename::basename ${$_[0]}, @_ }

Expand Down Expand Up @@ -76,6 +77,13 @@ sub new {
return bless \$value, ref $class || $class;
}

sub open {
my $self = shift;
my $handle = IO::File->new;
$handle->open($$self, @_) or croak qq{Can't open file "$$self": $!};
return $handle;
}

sub path { __PACKAGE__->new(@_) }

sub remove_tree {
Expand All @@ -87,7 +95,7 @@ sub remove_tree {
sub slurp {
my $self = shift;

open my $file, '<', $$self or croak qq{Can't open file "$$self": $!};
CORE::open my $file, '<', $$self or croak qq{Can't open file "$$self": $!};
my $ret = my $content = '';
while ($ret = $file->sysread(my $buffer, 131072, 0)) { $content .= $buffer }
croak qq{Can't read from file "$$self": $!} unless defined $ret;
Expand All @@ -97,7 +105,7 @@ sub slurp {

sub spurt {
my ($self, $content) = (shift, join '', @_);
open my $file, '>', $$self or croak qq{Can't open file "$$self": $!};
CORE::open my $file, '>', $$self or croak qq{Can't open file "$$self": $!};
($file->syswrite($content) // -1) == length $content
or croak qq{Can't write to file "$$self": $!};
return $self;
Expand All @@ -107,6 +115,8 @@ sub tap { shift->Mojo::Base::tap(@_) }

sub tempdir { __PACKAGE__->new(File::Temp->newdir(@_)) }

sub tempfile { __PACKAGE__->new(File::Temp->new(@_)) }

sub to_abs { $_[0]->new(rel2abs ${$_[0]}) }

sub to_array { [splitdir ${shift()}] }
Expand Down Expand Up @@ -176,6 +186,17 @@ L<File::Temp>.
# Longer version
my $path = Mojo::File->new(File::Temp->newdir('tempXXXXX'));
=head2 tempfile
my $path = tempfile;
my $path = tempfile(DIR => '/tmp');
Construct a new scalar-based L<Mojo::File> object for a temporary file with
L<File::Temp>.
# Longer version
my $path = Mojo::File->new(File::Temp->new(DIR => '/tmp'));
=head1 METHODS
L<Mojo::File> implements the following methods.
Expand Down Expand Up @@ -305,6 +326,12 @@ directory.
# "foo/bar/baz.txt" (on UNIX)
Mojo::File->new('foo', 'bar', 'baz.txt');
=head2 open
my $handle = $path->open('<');
Open the file with L<IO::File>.
=head2 remove_tree
$path = $path->remove_tree;
Expand Down
22 changes: 19 additions & 3 deletions t/mojo/file.t
Expand Up @@ -5,7 +5,7 @@ use Cwd 'getcwd';
use File::Basename qw(basename dirname);
use File::Spec::Functions qw(abs2rel canonpath catfile rel2abs splitdir);
use File::Temp;
use Mojo::File qw(path tempdir);
use Mojo::File qw(path tempdir tempfile);

# Constructor
is(Mojo::File->new, canonpath(getcwd), 'same path');
Expand Down Expand Up @@ -64,6 +64,22 @@ ok -d $path, 'directory exists';
undef $dir;
ok !-d $path, 'directory does not exist anymore';

# Temporary file
$dir = tempdir;
my $file = tempfile(DIR => $dir);
$path = "$file";
ok -f $path, 'file exists';
is $file->dirname, $dir, 'same directory';
is $file->spurt('test')->slurp, 'test', 'right result';
undef $file;
ok !-f $path, 'file does not exist anymore';

# Open
$file = tempfile;
$file->spurt("test\n123\n");
my $handle = $file->open('<');
is_deeply [<$handle>], ["test\n", "123\n"], 'right structure';

# Make path
$dir = tempdir;
my $subdir = $dir->child('foo', 'bar');
Expand Down Expand Up @@ -134,8 +150,8 @@ is_deeply path($lib)->list_tree({hidden => 1})->map('to_string')->to_array,
[@hidden, @files], 'right files';

# I/O
$dir = tempdir;
my $file = $dir->child('test.txt')->spurt('just works!');
$dir = tempdir;
$file = $dir->child('test.txt')->spurt('just works!');
is $file->slurp, 'just works!', 'right content';
is $file->spurt('w', 'orks', ' too!')->slurp, 'works too!', 'right content';
{
Expand Down

0 comments on commit 49f3f78

Please sign in to comment.