File Coverage

blib/lib/App/GHPT/WorkSubmitter/ChangedFilesFactory.pm
Criterion Covered Total %
statement 53 64 82.8
branch 4 8 50.0
condition 7 20 35.0
subroutine 10 11 90.9
pod n/a
total 74 103 71.8


line stmt bran cond sub pod time code
1             package App::GHPT::WorkSubmitter::ChangedFilesFactory;
2              
3 1     1   9 use App::GHPT::Wrapper::OurMoose;
  1         3  
  1         13  
4              
5             our $VERSION = '1.000012';
6              
7 1     1   12 use IPC::Run3 qw( run3 );
  1         3  
  1         91  
8 1     1   7 use App::GHPT::Types qw( ArrayRef HashRef Str );
  1         66  
  1         26  
9 1     1   6886 use App::GHPT::WorkSubmitter::ChangedFiles;
  1         5  
  1         1625  
10              
11             has changed_files_class => (
12             is => 'ro',
13             isa => Str,
14             default => 'App::GHPT::WorkSubmitter::ChangedFiles',
15             );
16              
17             has merge_to_branch_name => (
18             is => 'ro',
19             isa => Str,
20             required => 1,
21             );
22              
23             has current_branch_name => (
24             is => 'ro',
25             isa => Str,
26             lazy => 1,
27             builder => '_build_current_branch_name',
28             );
29              
30             sub _build_current_branch_name {
31 2     2   9 my $branch;
32              
33 2         24 my @command = (
34             'git',
35             'rev-parse',
36             '--abbrev-ref',
37             'HEAD',
38             );
39              
40 2         33 run3 \@command, \undef, \$branch, \my $error;
41 2 50 33     23158 if ( $error || $? ) {
42 0         0 die join q{ }, 'Problem running git rev-parse:', @command, $error, $?;
43             }
44              
45 2         20 chomp $branch;
46 2         277 return $branch;
47             }
48              
49             has merge_base => (
50             is => 'ro',
51             isa => Str,
52             lazy => 1,
53             builder => '_build_merge_base',
54             );
55              
56 2     2   7 sub _build_merge_base ( $self, @ ) {
  2         12  
  2         9  
57 2         11 my $merge_base;
58              
59 2         86 my @command = (
60             'git',
61             'merge-base',
62             $self->current_branch_name,
63             $self->merge_to_branch_name,
64             );
65              
66 2         29 run3 \@command, \undef, \$merge_base, \my $error;
67 2 50 33     23652 if ( $error || $? ) {
68 0         0 die join q{ }, 'Problem running git merge-base:', @command, $error,
69             $?;
70             }
71              
72 2         29 chomp $merge_base;
73 2         298 return $merge_base;
74             }
75              
76             has _git_diff_file_list => (
77             is => 'ro',
78             isa => HashRef [ ArrayRef [Str] ],
79             lazy => 1,
80             builder => '_build_git_diff_file_list',
81             );
82              
83 2     2   6 sub _build_git_diff_file_list ($self) {
  2         5  
  2         7  
84 2         6 my %return_value;
85              
86 2         96 my @command = (
87             'git',
88             'diff',
89             '--name-status',
90             $self->merge_base,
91             $self->current_branch_name,
92             );
93              
94 0     0   0 run3 \@command, \undef, sub ($line) {
  0         0  
  0         0  
95 0         0 chomp $line;
96 0         0 my ( $code, $filename ) = split /\s+/, $line, 2;
97 0   0     0 $return_value{$code} ||= [];
98 0         0 push $return_value{$code}->@*, $filename;
99 2         68 }, \my $error;
100              
101 2 50 33     24637 if ( $error || $? ) {
102 0         0 die join q{ }, 'Problem running git diff:', @command, $error, $?;
103             }
104              
105 2         291 return \%return_value;
106             }
107              
108             has _all_files => (
109             is => 'ro',
110             isa => ArrayRef,
111             lazy => 1,
112             builder => '_build_all_files',
113             );
114              
115 2     2   10 sub _build_all_files ($self) {
  2         10  
  2         5  
116 2         8 my @files;
117              
118 2         26 my @command = (
119             'git',
120             'ls-tree',
121             '-r',
122             'HEAD:',
123             );
124              
125 2     2   14 run3 \@command, \undef, sub ($line) {
  2         21114  
  2         15  
126 2         89 chomp $line;
127 2         52 my ( undef, undef, undef, $filename ) = split /\s+/, $line, 4;
128 2         42 push @files, $filename;
129 2         46 }, \my $error;
130              
131 2 50 33     339 if ( $error || $? ) {
132 0         0 die join q{ }, 'Problem running git ls-tree:', @command,
133             $error, $?;
134             }
135              
136 2         276 return \@files;
137             }
138              
139             has changed_files => (
140             is => 'ro',
141             isa => 'App::GHPT::WorkSubmitter::ChangedFiles',
142             lazy => 1,
143             builder => '_build_changed_files',
144             );
145              
146 2     2   5 sub _build_changed_files ( $self, @ ) {
  2         10  
  2         8  
147             return $self->changed_files_class->new(
148             added_files => $self->_git_diff_file_list->{A} || [],
149             modified_files => $self->_git_diff_file_list->{M} || [],
150 2   50     105 deleted_files => $self->_git_diff_file_list->{D} || [],
      50        
      50        
151             all_files => $self->_all_files,
152             );
153             }
154              
155             __PACKAGE__->meta->make_immutable;
156              
157             1;
158              
159             # ABSTRACT: Work out what files have changed in the git branch
160              
161             __END__
162              
163             =pod
164              
165             =encoding UTF-8
166              
167             =head1 NAME
168              
169             App::GHPT::WorkSubmitter::ChangedFilesFactory - Work out what files have changed in the git branch
170              
171             =head1 VERSION
172              
173             version 1.000012
174              
175             =head1 SYNOPSIS
176              
177             =head1 DESCRIPTION
178              
179             Builds a L<App::GHPT::WorkSubmitter::ChangedFiles> from the git repo. Only concerns
180             itself with things that have been committed, doesn't care about what's in the
181             working directory at all.
182              
183             Used by L<App::GHPT::WorkSubmitter::AskPullRequestQuestions>.
184              
185             =for test_synopsis use v5.20;
186              
187             my $factory = App::GHPT::WorkSubmitter::ChangedFilesFactory->new(
188             merge_to_branch_name => 'master',
189             );
190              
191             my $changed_files = $factory->changed_files;
192              
193             say 'The files that were added or modified since branching are:';
194             say for $changed_files->changed_files;
195              
196             =head1 SUPPORT
197              
198             Bugs may be submitted through L<https://github.com/maxmind/App-GHPT/issues>.
199              
200             =head1 AUTHORS
201              
202             =over 4
203              
204             =item *
205              
206             Mark Fowler <mark@twoshortplanks.com>
207              
208             =item *
209              
210             Dave Rolsky <autarch@urth.org>
211              
212             =back
213              
214             =head1 COPYRIGHT AND LICENSE
215              
216             This software is Copyright (c) 2019 by MaxMind, Inc.
217              
218             This is free software, licensed under:
219              
220             The Artistic License 2.0 (GPL Compatible)
221              
222             =cut