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) ],
[ 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 {
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 {
+(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;
}
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));
}
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));
}