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             package Dist::Zilla::Plugin::Git::FilePermissions;
2              
3 2     2   3456048 use 5.006;
  2         8  
4 2     2   12 use strict;
  2         5  
  2         45  
5 2     2   10 use warnings;
  2         4  
  2         87  
6              
7             our $VERSION = '1.001';
8              
9 2     2   1327 use Moose;
  2         627201  
  2         14  
10             with 'Dist::Zilla::Role::BeforeBuild';
11              
12 2     2   15002 use Git::Background 0.003;
  2         41153  
  2         56  
13 2     2   1796 use Path::Tiny;
  2         11650  
  2         153  
14              
15 2     2   882 use namespace::autoclean;
  2         8215  
  2         15  
16              
17 5     5 0 406484 sub mvp_multivalue_args { return (qw( perms )) }
18              
19             has _git => (
20             is => 'ro',
21             isa => 'Git::Background',
22             lazy => 1,
23             default => sub { Git::Background->new( path( shift->zilla->root )->absolute ) },
24             );
25              
26             has default => (
27             is => 'ro',
28             isa => 'Str',
29             default => '0644',
30             );
31              
32             has perms => (
33             is => 'ro',
34             isa => 'Maybe[ArrayRef]',
35             default => sub { [] },
36             );
37              
38             sub before_build {
39 5     5 0 1951147 my ($self) = @_;
40              
41 5         90 my @files = $self->_git_ls_files();
42 5 50       45 return if !@files;
43              
44 5         56 my @perms = $self->_permissions;
45              
46             FILE:
47 5         42 for my $file (@files) {
48              
49             # Git reports submodules as a file although they are a directory on
50             # the file system. We skip them because the default permissions of
51             # 0644 are suboptimal for directories.
52 30 100       443 next FILE if !-f $file;
53              
54             # default permission
55 25         1313 my $perm = oct( $self->default );
56              
57             PERMS:
58 25         83 for my $perm_ref (@perms) {
59 19         40 my ( $regex, $p ) = @{$perm_ref};
  19         70  
60              
61 19 100       243 next PERMS if $file !~ m{$regex};
62              
63 4         23 $perm = $p;
64 4         17 last PERMS;
65             }
66              
67 25 100       108 if ( $perm eq q{-} ) {
68 1         33 $self->log_debug("Ignoring permissions of file $file");
69 1         124 next FILE;
70             }
71              
72 24         338 my $current_perm = ( stat $file )[2] & 07777;
73              
74 24 100       117 if ( $current_perm != $perm ) {
75 14         271 $self->log( sprintf "Setting permission of $file to %o", $perm );
76              
77 14         7319 my $rc = chmod $perm, $file;
78 14 50       96 if ( $rc != 1 ) {
79 0         0 $self->log_fatal( sprintf "Unable to change permissions of file $file to %o", $perm );
80             }
81             }
82             }
83              
84 5         60 return;
85             }
86              
87             sub _git_ls_files {
88 5     5   40 my ($self) = @_;
89              
90 5         308 my $git = $self->_git;
91              
92 5         34 my $files_f = $git->run('ls-files')->await;
93              
94 5 50       109232 $self->log_fatal( scalar $files_f->failure ) if $files_f->is_failed;
95              
96 5         4136 my @files = $files_f->stdout;
97 5         383 return @files;
98             }
99              
100             sub _permissions {
101 5     5   51 my ($self) = @_;
102              
103 5         18 my @perms;
104              
105             LINE:
106 5         35 for my $line ( @{ $self->perms } ) {
  5         664  
107 4         97 my ( $regex, $perm ) = $line =~ m{ ( .+ ) \s+ ((?: 0[0-9]+ | - )) \s* $ }xsm;
108              
109 4 50       43 if ( !defined $perm ) {
110 0         0 $self->log_fatal("Unable to parse permissions line: $line");
111             }
112              
113 4 100       68 push @perms, [
114             $regex,
115             $perm eq q{-} ? q{-} : oct($perm),
116             ];
117             }
118              
119 5         53 return @perms;
120             }
121              
122             __PACKAGE__->meta->make_immutable;
123              
124             1;
125              
126             __END__
127              
128             =pod
129              
130             =encoding UTF-8
131              
132             =head1 NAME
133              
134             Dist::Zilla::Plugin::Git::FilePermissions - fix the file permissions in your Git repository with Dist::Zilla
135              
136             =head1 VERSION
137              
138             Version 1.001
139              
140             =head1 SYNOPSIS
141              
142             # in dist.ini:
143             [Git::FilePermissions]
144             perms = ^bin/ 0755
145             perms = ^scripts/ 0755
146              
147             =head1 DESCRIPTION
148              
149             This plugin fixes the file permissions of all the files in the Git repository
150             where your project is saved. Files not in the Git index, and directories, are
151             ignored.
152              
153             Without configuration, every file is changed to the default permission of
154             0644. The default permissions can be changed with the C<default> option
155             and you can configure different permissions for some files with the
156             C<perms> option in the F<dist.ini>.
157              
158             The plugin runs in the before build phase, which means it will fix the file
159             permissions before the files are picked up in the file gather phase. The new
160             permissions are therefore also the ones used in the build.
161              
162             The plugin should ensure that you always commit your files with the correct
163             permissions.
164              
165             =head2 perms
166              
167             The C<perms> configuration option takes the form of:
168              
169             perms = REGEX WHITESPACE PERMS
170              
171             or
172              
173             perms = REGEX WHITESPACE -
174              
175             The C<perms> configuration options are processed in order for every file. If
176             a file matches the C<REGEX> the file permissions are changed to the
177             corresponding C<PERMS> instead of the default permissions of 0644. If the
178             C<PERMS> are C<-> the file is ignored.
179              
180             =head1 SUPPORT
181              
182             =head2 Bugs / Feature Requests
183              
184             Please report any bugs or feature requests through the issue tracker
185             at L<https://github.com/skirmess/Dist-Zilla-Plugin-Git-FilePermissions/issues>.
186             You will be notified automatically of any progress on your issue.
187              
188             =head2 Source Code
189              
190             This is open source software. The code repository is available for
191             public review and contribution under the terms of the license.
192              
193             L<https://github.com/skirmess/Dist-Zilla-Plugin-Git-FilePermissions>
194              
195             git clone https://github.com/skirmess/Dist-Zilla-Plugin-Git-FilePermissions.git
196              
197             =head1 AUTHOR
198              
199             Sven Kirmess <sven.kirmess@kzone.ch>
200              
201             =head1 COPYRIGHT AND LICENSE
202              
203             This software is Copyright (c) 2017-2022 by Sven Kirmess.
204              
205             This is free software, licensed under:
206              
207             The (two-clause) FreeBSD License
208              
209             =head1 SEE ALSO
210              
211             L<Dist::Zilla::Plugin::Git::RequireUnixEOL|Dist::Zilla::Plugin::Git::RequireUnixEOL>
212              
213             =cut
214              
215             # vim: ts=4 sts=4 sw=4 et: syntax=perl