File Coverage

blib/lib/App/Git/Workflow/Command/BranchGrep.pm
Criterion Covered Total %
statement 50 81 61.7
branch 11 30 36.6
condition 3 5 60.0
subroutine 10 11 90.9
pod 2 2 100.0
total 76 129 58.9


line stmt bran cond sub pod time code
1             package App::Git::Workflow::Command::BranchGrep;
2              
3             # Created on: 2014-03-11 20:58:59
4             # Create by: Ivan Wills
5             # $Id$
6             # $Revision$, $HeadURL$, $Date$
7             # $Revision$, $Source$, $Date$
8              
9 2     2   105176 use strict;
  2         12  
  2         62  
10 2     2   13 use warnings;
  2         4  
  2         66  
11 2     2   502 use version;
  2         1908  
  2         14  
12 2     2   689 use English qw/ -no_match_vars /;
  2         3608  
  2         13  
13 2     2   1398 use Term::ANSIColor qw/colored/;
  2         8827  
  2         1852  
14 2     2   550 use App::Git::Workflow;
  2         6  
  2         116  
15 2     2   481 use App::Git::Workflow::Command qw/get_options/;
  2         7  
  2         1339  
16              
17             our $VERSION = version->new(1.1.16);
18             our $workflow = App::Git::Workflow->new;
19             our ($name) = $PROGRAM_NAME =~ m{^.*/(.*?)$}mxs;
20             our %option = (
21             master => 'origin/master',
22             );
23              
24             sub run {
25 6     6 1 30 get_options(
26             \%option,
27             'search|s=s',
28             'colour|color|c',
29             'remote|r',
30             'all|a',
31             'insensitive|i',
32             'unmerged|u!',
33             'master|m=s',
34             'limit|n=i',
35             );
36              
37 6   100     19 $ARGV[0] ||= '';
38 6         10 my @options;
39 6 100       17 push @options, '-r' if $option{remote};
40 6 100       15 push @options, '-a' if $option{all};
41 6 100       28 my $grep = $option{insensitive} ? "(?i:$ARGV[0])" : $ARGV[0];
42 6         12 shift @ARGV;
43              
44 6         11 my $count = 1;
45              
46 6 50       25 for my $branch ( sort {_sorter()} grep { $option{v} ? !/$grep/ : /$grep/ } $workflow->git->branch(@options) ) {
  5         12  
  17         135  
47 9         25 my $clean_branch = $branch;
48 9         30 $clean_branch =~ s/^..//;
49 9         16 $clean_branch =~ s/ -> .*$//;
50              
51 9 50       26 if ( $option{unmerged} ) {
52 0 0       0 next if unmerged($clean_branch, $option{master});
53             }
54              
55 9 50 33     21 last if $option{limit} && $count++ > $option{limit};
56              
57 9 50       23 if (@ARGV) {
58 0         0 my $shown = 0;
59 0         0 for my $file (@ARGV) {
60             my @contents = map {
61 0         0 my $found = $_;
62 0 0       0 if ($option{colour}) {
63 0         0 $found =~ s/($grep)/colored ['red'], $1/egxms;
  0         0  
64             }
65             $found
66 0         0 }
67 0         0 grep {/$option{search}/}
  0         0  
68             `git show $clean_branch:$file`;
69 0 0       0 if (@contents) {
70 0 0       0 if (!$shown++) {
71 0         0 print "$clean_branch\n";
72             }
73 0         0 print " $file\n";
74 0         0 print @contents;
75 0         0 print "\n";
76             }
77             }
78             }
79             else {
80 9 50       29 if ( $option{colour} ) {
81 0         0 $branch =~ s/($grep)/colored ['red'], $1/egxms;
  0         0  
82             }
83 9         290 print "$branch\n";
84             }
85             }
86             }
87              
88             sub _sorter {
89 2     2   17 no warnings;
  2         5  
  2         725  
90 5     5   9 my $A = $a;
91 5         10 my $B = $b;
92 5         13 $A =~ s/(\d+)/sprintf "%06d", $1/egxms;
  2         14  
93 5         10 $B =~ s/(\d+)/sprintf "%06d", $1/egxms;
  2         7  
94 5         16 $A cmp $B;
95             }
96              
97             my %dest;
98             sub unmerged {
99 0     0 1   my ($source, $dest) = @_;
100              
101 0 0         if ( ! $dest{$dest} ) {
102 0           @{$dest{$dest}} = map {/^(.*)\n/; $1} `git log --format=format:%H $dest`;
  0            
  0            
  0            
103 0 0         die "No destination branch commits for '$dest'" if !@{$dest{$dest}};
  0            
104             }
105              
106 0           my $source_sha = `git log --format=format:%H -n 1 $source`;
107 0           chomp $source_sha;
108              
109 0 0         return scalar grep {$_ && $_ eq $source_sha} @{$dest{$dest}};
  0            
  0            
110             }
111              
112             1;
113              
114             __DATA__
115              
116             =head1 NAME
117              
118             git-branch-grep - grep for branch names (and optionally files with them)
119              
120             =head1 VERSION
121              
122             This documentation refers to git-branch-grep version 1.1.16
123              
124             =head1 SYNOPSIS
125              
126             git-branch-grep [--remote|-r|--all|-a] regex
127             git-branch-grep ((-s|--search) regex) [--remote|-r|--all|-a] regex -- file(s)
128              
129             OPTIONS:
130             regex grep's perl (-P) regular expression
131             file When a file is specified the regexp will be run on the file
132             not the branch name.
133             -r --remote List all remote branches
134             -a --all List all branches
135             -v Find all branches that don't match regex
136             -u --unmerged
137             Only show branches not merged to --master
138             --no-unmerged
139             Only show branches merged to master
140             -m --master[=]str
141             Branch to check against for --unmerged and --no-unmerged
142             (Default origin/master)
143             -n --limit[=]int
144             Limit the out put to this number
145             -s --search[=]regex
146             Search term for looking within files
147              
148             --verbose Show more detailed option
149             --version Prints the version information
150             --help Prints this help information
151             --man Prints the full documentation for git-branch-grep
152              
153             Note: to search in all branches set the regex to ''
154             eg git branch-grep --search thin '' -- file1 file2
155              
156             =head1 DESCRIPTION
157              
158             Short hand for running
159              
160             C<git branch (-r|-a)? | grep -P 'regex'>
161              
162             =head1 SUBROUTINES/METHODS
163              
164             =head2 C<run ()>
165              
166             Executes the git workflow command
167              
168             =head2 C<unmerged ($source, $dest)>
169              
170             Check if there are any commits in C<$source> that are not in C<$dest>
171              
172             =head1 DIAGNOSTICS
173              
174             =head1 CONFIGURATION AND ENVIRONMENT
175              
176             =head1 DEPENDENCIES
177              
178             =head1 INCOMPATIBILITIES
179              
180             =head1 BUGS AND LIMITATIONS
181              
182             There are no known bugs in this module.
183              
184             Please report problems to Ivan Wills (ivan.wills@gmail.com).
185              
186             Patches are welcome.
187              
188             =head1 AUTHOR
189              
190             Ivan Wills - (ivan.wills@gmail.com)
191              
192             =head1 LICENSE AND COPYRIGHT
193              
194             Copyright (c) 2014 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW Australia 2077).
195             All rights reserved.
196              
197             This module is free software; you can redistribute it and/or modify it under
198             the same terms as Perl itself. See L<perlartistic>. This program is
199             distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
200             without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
201             PARTICULAR PURPOSE.
202              
203             =cut