File Coverage

blib/lib/Dist/Zilla/Plugin/Git/FilePermissions.pm
Criterion Covered Total %
statement 57 59 96.6
branch 14 18 77.7
condition n/a
subroutine 11 11 100.0
pod 0 2 0.0
total 82 90 91.1


line stmt bran cond sub pod time code
1             # vim: ts=4 sts=4 sw=4 et: syntax=perl
2             #
3             # Copyright (c) 2017-2022 Sven Kirmess
4             #
5             # Permission to use, copy, modify, and distribute this software for any
6             # purpose with or without fee is hereby granted, provided that the above
7             # copyright notice and this permission notice appear in all copies.
8             #
9             # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10             # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11             # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12             # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13             # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14             # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15             # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16              
17 2     2   3486200 use 5.006;
  2         7  
18 2     2   11 use strict;
  2         6  
  2         48  
19 2     2   9 use warnings;
  2         3  
  2         108  
20              
21              
22             our $VERSION = '1.002';
23              
24             use Moose;
25 2     2   1378 with 'Dist::Zilla::Role::BeforeBuild';
  2         534783  
  2         18  
26              
27             use Git::Background 0.003;
28 2     2   15681 use Path::Tiny;
  2         41843  
  2         60  
29 2     2   1752  
  2         12637  
  2         136  
30             use namespace::autoclean;
31 2     2   571  
  2         8403  
  2         14  
32              
33 5     5 0 384347 has _git => (
34             is => 'ro',
35             isa => 'Git::Background',
36             lazy => 1,
37             default => sub { Git::Background->new( path( shift->zilla->root )->absolute ) },
38             );
39              
40             has default => (
41             is => 'ro',
42             isa => 'Str',
43             default => '0644',
44             );
45              
46             has perms => (
47             is => 'ro',
48             isa => 'Maybe[ArrayRef]',
49             default => sub { [] },
50             );
51              
52             my ($self) = @_;
53              
54             my @files = $self->_git_ls_files();
55 5     5 0 1751183 return if !@files;
56              
57 5         77 my @perms = $self->_permissions;
58 5 50       49  
59             FILE:
60 5         50 for my $file (@files) {
61              
62             # Git reports submodules as a file although they are a directory on
63 5         26 # the file system. We skip them because the default permissions of
64             # 0644 are suboptimal for directories.
65             next FILE if !-f $file;
66              
67             # default permission
68 30 100       433 my $perm = oct( $self->default );
69              
70             PERMS:
71 25         1261 for my $perm_ref (@perms) {
72             my ( $regex, $p ) = @{$perm_ref};
73              
74 25         76 next PERMS if $file !~ m{$regex};
75 19         37  
  19         68  
76             $perm = $p;
77 19 100       269 last PERMS;
78             }
79 4         22  
80 4         15 if ( $perm eq q{-} ) {
81             $self->log_debug("Ignoring permissions of file $file");
82             next FILE;
83 25 100       102 }
84 1         27  
85 1         110 my $current_perm = ( stat $file )[2] & 07777;
86              
87             if ( $current_perm != $perm ) {
88 24         338 $self->log( sprintf "Setting permission of $file to %o", $perm );
89              
90 24 100       135 my $rc = chmod $perm, $file;
91 14         310 if ( $rc != 1 ) {
92             $self->log_fatal( sprintf "Unable to change permissions of file $file to %o", $perm );
93 14         7741 }
94 14 50       98 }
95 0         0 }
96              
97             return;
98             }
99              
100 5         44 my ($self) = @_;
101              
102             my $git = $self->_git;
103              
104 5     5   59 my $files_f = $git->run('ls-files')->await;
105              
106 5         317 $self->log_fatal( scalar $files_f->failure ) if $files_f->is_failed;
107              
108 5         43 my @files = $files_f->stdout;
109             return @files;
110 5 50       82465 }
111              
112 5         3839 my ($self) = @_;
113 5         511  
114             my @perms;
115              
116             LINE:
117 5     5   55 for my $line ( @{ $self->perms } ) {
118             my ( $regex, $perm ) = $line =~ m{ ( .+ ) \s+ ((?: 0[0-9]+ | - )) \s* $ }xsm;
119 5         31  
120             if ( !defined $perm ) {
121             $self->log_fatal("Unable to parse permissions line: $line");
122 5         47 }
  5         659  
123 4         100  
124             push @perms, [
125 4 50       35 $regex,
126 0         0 $perm eq q{-} ? q{-} : oct($perm),
127             ];
128             }
129 4 100       59  
130             return @perms;
131             }
132              
133             __PACKAGE__->meta->make_immutable;
134              
135 5         44 1;
136              
137              
138             =pod
139              
140             =encoding UTF-8
141              
142             =head1 NAME
143              
144             Dist::Zilla::Plugin::Git::FilePermissions - fix the file permissions in your Git repository with Dist::Zilla
145              
146             =head1 VERSION
147              
148             Version 1.002
149              
150             =head1 SYNOPSIS
151              
152             # in dist.ini:
153             [Git::FilePermissions]
154             perms = ^bin/ 0755
155             perms = ^scripts/ 0755
156              
157             =head1 DESCRIPTION
158              
159             This plugin fixes the file permissions of all the files in the Git repository
160             where your project is saved. Files not in the Git index, and directories, are
161             ignored.
162              
163             Without configuration, every file is changed to the default permission of
164             0644. The default permissions can be changed with the C<default> option
165             and you can configure different permissions for some files with the
166             C<perms> option in the F<dist.ini>.
167              
168             The plugin runs in the before build phase, which means it will fix the file
169             permissions before the files are picked up in the file gather phase. The new
170             permissions are therefore also the ones used in the build.
171              
172             The plugin should ensure that you always commit your files with the correct
173             permissions.
174              
175             =head2 perms
176              
177             The C<perms> configuration option takes the form of:
178              
179             perms = REGEX WHITESPACE PERMS
180              
181             or
182              
183             perms = REGEX WHITESPACE -
184              
185             The C<perms> configuration options are processed in order for every file. If
186             a file matches the C<REGEX> the file permissions are changed to the
187             corresponding C<PERMS> instead of the default permissions of 0644. If the
188             C<PERMS> are C<-> the file is ignored.
189              
190             =head1 SUPPORT
191              
192             =head2 Bugs / Feature Requests
193              
194             Please report any bugs or feature requests through the issue tracker
195             at L<https://github.com/skirmess/Dist-Zilla-Plugin-Git-FilePermissions/issues>.
196             You will be notified automatically of any progress on your issue.
197              
198             =head2 Source Code
199              
200             This is open source software. The code repository is available for
201             public review and contribution under the terms of the license.
202              
203             L<https://github.com/skirmess/Dist-Zilla-Plugin-Git-FilePermissions>
204              
205             git clone https://github.com/skirmess/Dist-Zilla-Plugin-Git-FilePermissions.git
206              
207             =head1 AUTHOR
208              
209             Sven Kirmess <sven.kirmess@kzone.ch>
210              
211             =head1 SEE ALSO
212              
213             L<Dist::Zilla::Plugin::Git::RequireUnixEOL|Dist::Zilla::Plugin::Git::RequireUnixEOL>
214              
215             =cut