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