From: Matt S Trout Date: Fri, 14 Feb 2014 07:28:26 +0000 (+0000) Subject: create directory and create file, now with mode setting X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=640fa37e45199b590ef6a35715b9c4689985cf0b;p=scpubgit%2FDKit.git create directory and create file, now with mode setting --- diff --git a/lib/DX/Lib/FS.pm b/lib/DX/Lib/FS.pm index a11622f..220daec 100644 --- a/lib/DX/Lib/FS.pm +++ b/lib/DX/Lib/FS.pm @@ -8,6 +8,8 @@ use DX::SetOver; use Moo; our @RULES = ( + [ has_action => [ qw(Thing Action) ], + [ prop => 'Thing', \'required_action', 'Action' ] ], [ path_status => [ qw(PS) ], [ member_of => 'PS', \'path_status' ] ], [ path => [ qw(PS P) ], @@ -72,6 +74,20 @@ our @RULES = ( [ exists => [ qw(FilePath) ], [ catfile => qw(DirPath FileName FilePath) ], [ file_at => qw(FileStatus FilePath) ] ] ] ], + [ mode => [ qw(PS M) ], + [ exists => [ qw(A) ], + [ has_action => qw(PS A) ], + [ does => 'A', \'DX::Lib::FS::Action::CreateDirectory' ], + [ react => [ qw(PS M) ], sub { + $_[0]->but(mode => $_[1]); + } ] ] ], + [ mode => [ qw(PS M) ], + [ exists => [ qw(A) ], + [ has_action => qw(PS A) ], + [ does => 'A', \'DX::Lib::FS::Action::CreateFile' ], + [ react => [ qw(PS M) ], sub { + $_[0]->but(mode => $_[1]); + } ] ] ], ); sub load_into { @@ -95,7 +111,7 @@ sub load_into { catfile => [ qw(DirPath FileName FilePath) ], [ qw(+ + -) ] => sub { my ($vol, $dir) = File::Spec->splitpath($_{DirPath}, 1); - my $file_path = File::Spec->catpath($vol, $dir, $_{FilePath}); + my $file_path = File::Spec->catpath($vol, $dir, $_{FileName}); +(FilePath => [ value => $file_path ]) }, [ qw(- - +) ] => sub { @@ -104,6 +120,10 @@ sub load_into { +(DirPath => [ value => $dir_path ], FileName => [ value => $file ]) } ); + $solver->add_rule( + does => [ qw(Thing RoleName) ], + [ constrain => [ qw(Thing RoleName) ], sub { $_[0]->DOES($_[1]) } ] + ); $solver->add_rule(@$_) for @RULES; } diff --git a/lib/DX/Lib/FS/Action/CreateDirectory.pm b/lib/DX/Lib/FS/Action/CreateDirectory.pm index ef11a20..5fcdef3 100644 --- a/lib/DX/Lib/FS/Action/CreateDirectory.pm +++ b/lib/DX/Lib/FS/Action/CreateDirectory.pm @@ -8,17 +8,29 @@ with 'DX::Role::Action'; has path => (is => 'ro', required => 1); +has mode => (is => 'ro', predicate => 1); + sub expected_effect { my ($self) = @_; return +(path_status => PathStatus->new( path => $self->path, - info => PathStatusInfo->new(is_directory => 1, mode => '') + info => PathStatusInfo->new( + is_directory => 1, + mode => ($self->has_mode ? $self->mode : '') + ) )); } sub _do_run { my ($self) = @_; - mkdir($self->path) or die "Couldn't mkdir ${\$self->path}: $!"; + if ($self->has_mode) { + my $umask = umask(0000); + mkdir($self->path, oct($self->mode)) + or do { umask($umask); die "Couldn't mkdir ${\$self->path}: $!" }; + umask($umask); + } else { + mkdir($self->path) or die "Couldn't mkdir ${\$self->path}: $!"; + } +(path_status => PathStatus->new(path => $self->path)); } diff --git a/lib/DX/Lib/FS/Action/CreateFile.pm b/lib/DX/Lib/FS/Action/CreateFile.pm index 80379e3..feed8f7 100644 --- a/lib/DX/Lib/FS/Action/CreateFile.pm +++ b/lib/DX/Lib/FS/Action/CreateFile.pm @@ -2,23 +2,38 @@ package DX::Lib::FS::Action::CreateFile; use aliased 'DX::Lib::FS::Fact::PathStatus'; use aliased 'DX::Lib::FS::Fact::PathStatusInfo'; +use POSIX (); use Moo; with 'DX::Role::Action'; has path => (is => 'ro', required => 1); +has mode => (is => 'ro', predicate => 1); + sub expected_effect { my ($self) = @_; return +(path_status => PathStatus->new( path => $self->path, - info => PathStatusInfo->new(is_file => 1, mode => '') + info => PathStatusInfo->new( + is_file => 1, + mode => ($self->has_mode ? $self->mode : '') + ) )); } sub _do_run { my ($self) = @_; - open my $fh, '>>', $self->path or die "Couldn't create ${\$self->path}: $!"; + if ($self->has_mode) { + my $umask = umask(0000); + my $fd = POSIX::open( + $self->path, POSIX::O_CREAT | POSIX::O_RDONLY, oct($self->mode) + ) or do { umask($umask); die "Couldn't create ${\$self->path}: $!" }; + POSIX::close($fd); + umask($umask); + } else { + open my $fh, '>>', $self->path or die "Couldn't create ${\$self->path}: $!"; + } +(path_status => PathStatus->new(path => $self->path)); }