File Coverage

blib/lib/Test/BrewBuild/Git.pm
Criterion Covered Total %
statement 21 101 20.7
branch 0 24 0.0
condition n/a
subroutine 7 18 38.8
pod 8 8 100.0
total 36 151 23.8


line stmt bran cond sub pod time code
1             package Test::BrewBuild::Git;
2 37     37   26857 use strict;
  37         90  
  37         837  
3 37     37   148 use warnings;
  37         57  
  37         992  
4              
5 37     37   953 use Capture::Tiny qw(:all);
  37         56535  
  37         3675  
6 37     37   200 use Carp qw(croak);
  37         55  
  37         1450  
7 37     37   1298 use Logging::Simple;
  37         25811  
  37         847  
8 37     37   13739 use LWP::Simple qw(head);
  37         1829097  
  37         286  
9 37     37   7076 use Test::BrewBuild::Regex;
  37         77  
  37         37931  
10              
11             our $VERSION = '2.20';
12              
13             my $log;
14              
15             sub new {
16 0     0 1   my ($class, %args) = @_;
17 0           my $self = bless {}, $class;
18              
19 0           $log = Logging::Simple->new(
20             name => 'Git',
21             level => 0
22             );
23              
24 0 0         if (defined $args{debug}){
25 0           $log->level($args{debug});
26             }
27              
28 0           $log->child('new')->_5("instantiating new object");
29              
30 0           return $self;
31             }
32             sub git {
33 0     0 1   my $self = shift;
34 0           my $cmd;
35              
36 0 0         return $self->{git} if defined $self->{git};
37              
38 0 0         if ($^O =~ /MSWin/){
39 0           for (split /;/, $ENV{PATH}){
40 0 0         if (-x "$_/git.exe"){
41 0           $cmd = "$_/git.exe";
42 0           last;
43             }
44             }
45             }
46             else {
47 0           $cmd = 'git';
48             }
49              
50 0           $log->child('git')->_6("git command set to '$cmd'");
51              
52 0           $self->{git} = $cmd;
53              
54 0           return $cmd;
55             }
56             sub link {
57 0     0 1   my $self = shift;
58 0           my $git = $self->git;
59 0           my $link = (split /\n/, `"$git" config --get remote.origin.url`)[0];
60 0           $log->child('link')->_6("found $link for the repo");
61 0           return $link
62             }
63             sub name {
64 0     0 1   my ($self, $repo) = @_;
65              
66 0           $log->child('name')->_6("converting repository link to repo name");
67              
68 0 0         if ($repo =~ m!${ re_git('extract_repo_name') }!){
  0            
69 0           $log->child('name')->_6("repo link converted to $1");
70 0           return $1;
71             }
72             }
73             sub clone {
74 0     0 1   my ($self, $repo) = @_;
75              
76 0           $log->child('clone')->_7("initiating remote repo clone");
77              
78 0 0         if ($repo !~ /https/){
79 0           $log->child('clone')->_2("git clone failed, repo doesn't exist");
80 0           croak "repository $repo doesn't exist; can't clone...\n";
81             }
82              
83 0           my $git = $self->git;
84              
85             my $output = capture_merged {
86 0     0     `"$git" clone $repo`;
87 0           };
88              
89 0 0         if ($output =~ /fatal/){
90 0           croak "fatal error cloning $repo, can't clone...\n";
91             }
92              
93 0           return $output;
94             }
95             sub pull {
96 0     0 1   my $self = shift;
97 0           my $git = $self->git;
98              
99 0           $log->child('clone')->_6("initiating git pull");
100              
101 0           my $output = `"$git" pull`;
102 0           return $output;
103             }
104             sub revision {
105 0     0 1   my ($self, %args) = @_;
106              
107 0           my $remote = $args{remote};
108 0           my $repo = $args{repo};
109              
110 0           my $log = $log->child('revision');
111              
112 0           my $git = $self->git;
113              
114 0           $log->child('revision')->_6("initiating git revision");
115              
116 0           my $csum;
117              
118 0 0         if (! $remote) {
119 0           $log->_6("local: 'rev-parse HEAD' sent");
120 0           $csum = `"$git" rev-parse HEAD`;
121             }
122             else {
123 0 0         if (! defined $repo){
124 0           $log->_0(
125             "Git::revision() requires a repo sent in while in remote " .
126             "mode. Croaking."
127             );
128 0           croak "Git::revision() requires a repo sent in while in " .
129             "remote mode.";
130             }
131              
132 0           $log->_6("remote: 'ls-remote $repo' sent");
133              
134             # void capture, as there's unneeded stuff going to STDERR
135             # on the ls-remote call
136              
137             capture_stderr {
138 0     0     my $sums = `"$git" ls-remote $repo`;
139 0 0         if ($sums =~ /${ re_git('extract_commit_csum') }/){
  0            
140 0           $csum = $1;
141             }
142             }
143 0           }
144              
145 0           chomp $csum;
146 0           $log->_5("commit checksum: $csum");
147 0           return $csum;
148             }
149             sub status {
150 0     0 1   my ($self) = @_;
151              
152 0           $log->child('status')->_7("checking git status");
153              
154 0           my $git = $self->git;
155              
156 0           my $status = `$git status`;
157              
158 0 0         if ($status =~ /Your branch is ahead/){
159 0           return 0;
160             }
161 0           return 1;
162             }
163             sub _separate_url {
164             # this method is actually not needed. Was going to be used if we used the
165             # github API to fetch stuff...
166             # eg: https://api.github.com/repos/$user/$repo/commits
167              
168 0     0     my ($self, $repo) = @_;
169              
170 0 0         if (! defined $repo){
171 0           $repo = $self->link;
172             }
173              
174 0           my ($user, $repo_name) = (split /\//, $repo)[-2, -1];
175              
176 0           return ($user, $repo_name);
177             }
178              
179             1;
180              
181             =head1 NAME
182              
183             Test::BrewBuild::Git - Git repository manager for the C test
184             platform system.
185              
186             =head1 SYNOPSIS
187              
188             use Test::BrewBuild::Git;
189              
190             my $git = Test::BrewBuild::Git->new;
191              
192             my $repo_link = $git->link;
193              
194             my $repo_name = $git->name($link);
195              
196             $git->clone($repo_link);
197              
198             $git->pull;
199              
200             =head1 DESCRIPTION
201              
202             Manages Git repositories, including gathering names, cloning, pulling etc.
203              
204             =head1 METHODS
205              
206             =head2 new
207              
208             Returns a new C object.
209              
210             Parameters:
211              
212             debug => $level
213              
214             Optional, Integer. $level vary between 0-7, 0 being the least verbose.
215              
216             =head2 git
217              
218             Returns the C command for the local platform.
219              
220             =head2 link
221              
222             Fetches and returns the full link to the master repository from your current
223             working directory. This is the link you used to originally clone the repo.
224              
225             =head2 name($link)
226              
227             Extracts the repo name from the full link path.
228              
229             =head2 clone($repo)
230              
231             Clones the repo into the current working directory.
232              
233             =head2 pull
234              
235             While in a repository directory, pull down any updates.
236              
237             =head2 revision(remote => $bool, repo => $github_url)
238              
239             Returns the current commit SHA1 for a repo, with ability to get the local commit
240             or remote commit SHA1 sum.
241              
242             Parameters:
243              
244             All parameters are passed in as a hash.
245              
246             repo
247              
248             Optional, string. The Github url to the repo. If not sent in, we will attempt
249             to get this information from the current working directory. Mandatory if the
250             C parameter is sent in.
251              
252             remote
253              
254             Optional, bool. If sent in, we'll fetch the current commit's SHA1 sum from
255             Github itself, else we'll get the sum from the most recent local, unpushed
256             commit. The C parameter is mandatory if this one is sent in.
257              
258             =head2 status
259              
260             Returns true of the repo we're working on is behind or equal to the remote
261             regarding commits, and false if we're ahead.
262              
263             =head1 AUTHOR
264              
265             Steve Bertrand, C<< >>
266              
267             =head1 LICENSE AND COPYRIGHT
268              
269             Copyright 2017 Steve Bertrand.
270              
271             This program is free software; you can redistribute it and/or modify it
272             under the terms of either: the GNU General Public License as published
273             by the Free Software Foundation; or the Artistic License.
274              
275             See L for more information.
276              
277             =cut
278