File Coverage

blib/lib/Dist/Zilla/Plugin/GatherFile.pm
Criterion Covered Total %
statement 46 47 97.8
branch 7 8 87.5
condition n/a
subroutine 12 12 100.0
pod 0 3 0.0
total 65 70 92.8


line stmt bran cond sub pod time code
1             package Dist::Zilla::Plugin::GatherFile 6.037;
2             # ABSTRACT: gather individual file(s)
3              
4 2     2   2852 use Moose;
  2         6  
  2         21  
5 2     2   19443 use Dist::Zilla::Types qw(Path ArrayRefOfPaths);
  2         5  
  2         52  
6             with 'Dist::Zilla::Role::FileGatherer';
7              
8 2     2   7650 use Dist::Zilla::Pragmas;
  2         5  
  2         22  
9              
10 2     2   20 use MooseX::Types::Moose 'ArrayRef';
  2         5  
  2         21  
11 2     2   14051 use Path::Tiny;
  2         5  
  2         208  
12 2     2   17 use Dist::Zilla::File::OnDisk;
  2         6  
  2         74  
13 2     2   13 use Dist::Zilla::Util;
  2         4  
  2         88  
14 2     2   14 use namespace::autoclean;
  2         4  
  2         22  
15              
16             #pod =head1 SYNOPSIS
17             #pod
18             #pod [GatherFile]
19             #pod filename = examples/file.txt
20             #pod
21             #pod =head1 DESCRIPTION
22             #pod
23             #pod This is a very, very simple L<FileGatherer|Dist::Zilla::Role::FileGatherer>
24             #pod plugin. It adds all the files referenced by the C<filename> option that are
25             #pod found in the directory named in the L</root> attribute. If the root begins
26             #pod with a tilde, the tilde is passed through C<glob()> first.
27             #pod
28             #pod Since normally every distribution will use a GatherDir plugin, you would only
29             #pod need to use the GatherFile plugin if the file was already being excluded (e.g.
30             #pod from an C<exclude_match> configuration).
31             #pod
32             #pod =cut
33              
34             #pod =attr root
35             #pod
36             #pod This is the directory in which to look for files. If not given, it defaults to
37             #pod the dist root -- generally, the place where your F<dist.ini> or other
38             #pod configuration file is located.
39             #pod
40             #pod =cut
41              
42             has root => (
43             is => 'ro',
44             isa => Path,
45             lazy => 1,
46             coerce => 1,
47             required => 1,
48             default => sub { shift->zilla->root },
49             );
50              
51             #pod =attr prefix
52             #pod
53             #pod This parameter can be set to place the gathered files under a particular
54             #pod directory. See the L<description|DESCRIPTION> above for an example.
55             #pod
56             #pod =cut
57              
58             has prefix => (
59             is => 'ro',
60             isa => 'Str',
61             default => '',
62             );
63              
64             #pod =attr filename
65             #pod
66             #pod The name of the file to gather, relative to the C<root>.
67             #pod Can be used more than once.
68             #pod
69             #pod =cut
70              
71             has filenames => (
72             is => 'ro', isa => ArrayRefOfPaths,
73             lazy => 1,
74             coerce => 1,
75             default => sub { [] },
76             );
77              
78 4     4 0 548 sub mvp_aliases { +{ filename => 'filenames' } }
79 4     4 0 1541 sub mvp_multivalue_args { qw(filenames) }
80              
81             around dump_config => sub {
82             my $orig = shift;
83             my $self = shift;
84              
85             my $config = $self->$orig;
86              
87             $config->{+__PACKAGE__} = {
88             prefix => $self->prefix,
89             # only report relative to dist root to avoid leaking private info
90             root => path($self->root)->relative($self->zilla->root),
91             filenames => [ sort @{ $self->filenames } ],
92             };
93              
94             return $config;
95             };
96              
97             sub gather_files {
98 4     4 0 10 my ($self) = @_;
99              
100 4         143 my $repo_root = $self->zilla->root;
101 4         111 my $root = "" . $self->root;
102 4         28 $root =~ s{^~([\\/])}{ Dist::Zilla::Util->homedir . $1 }e;
  0         0  
103 4         15 $root = path($root);
104 4 100       177 $root = $root->absolute($repo_root) if path($root)->is_relative;
105              
106 4         302 for my $filename (@{ $self->filenames })
  4         146  
107             {
108 4         14 $filename = $root->child($filename);
109 4 50       213 $self->log_fatal("$filename is a directory! Use [GatherDir] instead?") if -d $filename;
110              
111 4         137 my $fileobj = $self->_file_from_filename($filename->stringify);
112              
113 3         11 $filename = $fileobj->name;
114 3         17 my $file = path($filename)->relative($root);
115 3 100       1016 $file = path($self->prefix, $file) if $self->prefix;
116              
117 3         37 $fileobj->name($file->stringify);
118 3         16 $self->add_file($fileobj);
119             }
120              
121 3         15 return;
122             }
123              
124             # as in GatherDir
125             sub _file_from_filename {
126 4     4   29 my ($self, $filename) = @_;
127              
128 4 100       68 my @stat = stat $filename or $self->log_fatal("$filename does not exist!");
129              
130 3         176 return Dist::Zilla::File::OnDisk->new({
131             name => $filename,
132             mode => $stat[2] & 0755, # kill world-writeability
133             });
134             }
135              
136             __PACKAGE__->meta->make_immutable;
137              
138             __END__
139              
140             =pod
141              
142             =encoding UTF-8
143              
144             =head1 NAME
145              
146             Dist::Zilla::Plugin::GatherFile - gather individual file(s)
147              
148             =head1 VERSION
149              
150             version 6.037
151              
152             =head1 SYNOPSIS
153              
154             [GatherFile]
155             filename = examples/file.txt
156              
157             =head1 DESCRIPTION
158              
159             This is a very, very simple L<FileGatherer|Dist::Zilla::Role::FileGatherer>
160             plugin. It adds all the files referenced by the C<filename> option that are
161             found in the directory named in the L</root> attribute. If the root begins
162             with a tilde, the tilde is passed through C<glob()> first.
163              
164             Since normally every distribution will use a GatherDir plugin, you would only
165             need to use the GatherFile plugin if the file was already being excluded (e.g.
166             from an C<exclude_match> configuration).
167              
168             =head1 PERL VERSION
169              
170             This module should work on any version of perl still receiving updates from
171             the Perl 5 Porters. This means it should work on any version of perl
172             released in the last two to three years. (That is, if the most recently
173             released version is v5.40, then this module should work on both v5.40 and
174             v5.38.)
175              
176             Although it may work on older versions of perl, no guarantee is made that the
177             minimum required version will not be increased. The version may be increased
178             for any reason, and there is no promise that patches will be accepted to
179             lower the minimum required perl.
180              
181             =head1 ATTRIBUTES
182              
183             =head2 root
184              
185             This is the directory in which to look for files. If not given, it defaults to
186             the dist root -- generally, the place where your F<dist.ini> or other
187             configuration file is located.
188              
189             =head2 prefix
190              
191             This parameter can be set to place the gathered files under a particular
192             directory. See the L<description|DESCRIPTION> above for an example.
193              
194             =head2 filename
195              
196             The name of the file to gather, relative to the C<root>.
197             Can be used more than once.
198              
199             =head1 AUTHOR
200              
201             Ricardo SIGNES 😏 <cpan@semiotic.systems>
202              
203             =head1 COPYRIGHT AND LICENSE
204              
205             This software is copyright (c) 2026 by Ricardo SIGNES.
206              
207             This is free software; you can redistribute it and/or modify it under
208             the same terms as the Perl 5 programming language system itself.
209              
210             =cut