File Coverage

blib/lib/MooseX/Types/Path/Tiny.pm
Criterion Covered Total %
statement 24 24 100.0
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 32 32 100.0


line stmt bran cond sub pod time code
1 4     4   5364320 use strict;
  4         9  
  4         170  
2 4     4   23 use warnings;
  4         9  
  4         251  
3             package MooseX::Types::Path::Tiny;
4             # git description: v0.010-16-gf86e422
5             $MooseX::Types::Path::Tiny::VERSION = '0.011';
6             # ABSTRACT: Path::Tiny types and coercions for Moose
7             # KEYWORDS: moose type constraint path filename directory
8              
9 4     4   1721 use Moose 2;
  4         1112784  
  4         32  
10 4     4   41108 use MooseX::Types::Stringlike qw/Stringable/;
  4         997346  
  4         47  
11 4     4   6845 use MooseX::Types::Moose qw/Str ArrayRef/;
  4         9  
  4         25  
12 4         30 use MooseX::Types -declare => [qw/
13             Path AbsPath
14             File AbsFile
15             Dir AbsDir
16             Paths AbsPaths
17 4     4   22472 /];
  4         10  
18 4     4   39554 use Path::Tiny ();
  4         15166  
  4         182  
19 4     4   29 use if MooseX::Types->VERSION >= 0.42, 'namespace::autoclean';
  4         9  
  4         129  
20              
21             #<<<
22             subtype Path, as 'Path::Tiny';
23             subtype AbsPath, as Path, where { $_->is_absolute };
24              
25             subtype File, as Path, where { $_->is_file }, message { "File '$_' does not exist" };
26             subtype Dir, as Path, where { $_->is_dir }, message { "Directory '$_' does not exist" };
27              
28             subtype AbsFile, as AbsPath, where { $_->is_file }, message { "File '$_' does not exist" };
29             subtype AbsDir, as AbsPath, where { $_->is_dir }, message { "Directory '$_' does not exist" };
30              
31             subtype Paths, as ArrayRef[Path];
32             subtype AbsPaths, as ArrayRef[AbsPath];
33             #>>>
34              
35             for my $type ( 'Path::Tiny', Path, File, Dir ) {
36             coerce(
37             $type,
38             from Str() => via { Path::Tiny::path($_) },
39             from Stringable() => via { Path::Tiny::path($_) },
40             from ArrayRef() => via { Path::Tiny::path(@$_) },
41             );
42             }
43              
44             for my $type ( AbsPath, AbsFile, AbsDir ) {
45             coerce(
46             $type,
47             from 'Path::Tiny' => via { $_->absolute },
48             from Str() => via { Path::Tiny::path($_)->absolute },
49             from Stringable() => via { Path::Tiny::path($_)->absolute },
50             from ArrayRef() => via { Path::Tiny::path(@$_)->absolute },
51             );
52             }
53              
54             coerce(
55             Paths,
56             from Path() => via { [ $_ ] },
57             from Str() => via { [ Path::Tiny::path($_) ] },
58             from Stringable() => via { [ Path::Tiny::path($_) ] },
59             from ArrayRef() => via { [ map { Path::Tiny::path($_) } @$_ ] },
60             );
61              
62             coerce(
63             AbsPaths,
64             from AbsPath() => via { [ $_ ] },
65             from Str() => via { [ Path::Tiny::path($_)->absolute ] },
66             from Stringable() => via { [ Path::Tiny::path($_)->absolute ] },
67             from ArrayRef() => via { [ map { Path::Tiny::path($_)->absolute } @$_ ] },
68             );
69              
70             ### optionally add Getopt option type (adapted from MooseX::Types:Path::Class
71             ##eval { require MooseX::Getopt; };
72             ##if ( !$@ ) {
73             ## MooseX::Getopt::OptionTypeMap->add_option_type_to_map( $_, '=s', )
74             ## for ( 'Path::Tiny', Path );
75             ##}
76              
77             1;
78              
79             =pod
80              
81             =encoding UTF-8
82              
83             =head1 NAME
84              
85             MooseX::Types::Path::Tiny - Path::Tiny types and coercions for Moose
86              
87             =head1 VERSION
88              
89             version 0.011
90              
91             =head1 SYNOPSIS
92              
93             ### specification of type constraint with coercion
94              
95             package Foo;
96              
97             use Moose;
98             use MooseX::Types::Path::Tiny qw/Path Paths AbsPath/;
99              
100             has filename => (
101             is => 'ro',
102             isa => Path,
103             coerce => 1,
104             );
105              
106             has directory => (
107             is => 'ro',
108             isa => AbsPath,
109             coerce => 1,
110             );
111              
112             has filenames => (
113             is => 'ro',
114             isa => Paths,
115             coerce => 1,
116             );
117              
118             ### usage in code
119              
120             Foo->new( filename => 'foo.txt' ); # coerced to Path::Tiny
121             Foo->new( directory => '.' ); # coerced to path('.')->absolute
122             Foo->new( filenames => [qw/bar.txt baz.txt/] ); # coerced to ArrayRef[Path::Tiny]
123              
124             =head1 DESCRIPTION
125              
126             This module provides L<Path::Tiny> types for L<Moose>. It handles
127             two important types of coercion:
128              
129             =over 4
130              
131             =item *
132              
133             coercing objects with overloaded stringification
134              
135             =item *
136              
137             coercing to absolute paths
138              
139             =back
140              
141             It also can check to ensure that files or directories exist.
142              
143             =for stopwords coercions
144              
145             =head1 SUBTYPES
146              
147             =for stopwords SUBTYPES subtype subtypes
148              
149             This module uses L<MooseX::Types> to define the following subtypes.
150              
151             =for stopwords AbsPath AbsFile AbsDir
152              
153             =head2 Path
154              
155             C<Path> ensures an attribute is a L<Path::Tiny> object. Strings and
156             objects with overloaded stringification may be coerced.
157              
158             =head2 AbsPath
159              
160             C<AbsPath> is a subtype of C<Path> (above), but coerces to an absolute path.
161              
162             =head2 File, AbsFile
163              
164             These are just like C<Path> and C<AbsPath>, except they check C<-f> to ensure
165             the file actually exists on the filesystem.
166              
167             =head2 Dir, AbsDir
168              
169             These are just like C<Path> and C<AbsPath>, except they check C<-d> to ensure
170             the directory actually exists on the filesystem.
171              
172             =head2 Paths, AbsPaths
173              
174             These are arrayrefs of C<Path> and C<AbsPath>, and include coercions from
175             arrayrefs of strings.
176              
177             =head1 CAVEATS
178              
179             =head2 Path vs File vs Dir
180              
181             C<Path> just ensures you have a L<Path::Tiny> object.
182              
183             C<File> and C<Dir> check the filesystem. Don't use them unless that's really
184             what you want.
185              
186             =head2 Usage with File::Temp
187              
188             Be careful if you pass in a L<File::Temp> object. Because the argument is
189             stringified during coercion into a L<Path::Tiny> object, no reference to the
190             original L<File::Temp> argument is held. Be sure to hold an external reference to
191             it to avoid immediate cleanup of the temporary file or directory at the end of
192             the enclosing scope.
193              
194             A better approach is to use L<Path::Tiny>'s own C<tempfile> or C<tempdir>
195             constructors, which hold the reference for you.
196              
197             Foo->new( filename => Path::Tiny->tempfile );
198              
199             =head1 SEE ALSO
200              
201             =over 4
202              
203             =item *
204              
205             L<Path::Tiny>
206              
207             =item *
208              
209             L<Moose::Manual::Types>
210              
211             =item *
212              
213             L<Types::Path::Tiny>
214              
215             =back
216              
217             =head1 AUTHOR
218              
219             David Golden <dagolden@cpan.org>
220              
221             =head1 COPYRIGHT AND LICENSE
222              
223             This software is Copyright (c) 2013 by David Golden.
224              
225             This is free software, licensed under:
226              
227             The Apache License, Version 2.0, January 2004
228              
229             =head1 CONTRIBUTORS
230              
231             =for stopwords Karen Etheridge Toby Inkster Demian Riccardi
232              
233             =over 4
234              
235             =item *
236              
237             Karen Etheridge <ether@cpan.org>
238              
239             =item *
240              
241             Toby Inkster <mail@tobyinkster.co.uk>
242              
243             =item *
244              
245             Demian Riccardi <dde@ornl.gov>
246              
247             =back
248              
249             =cut
250              
251             __END__
252              
253              
254             # vim: ts=4 sts=4 sw=4 et: