File Coverage

blib/lib/App/GitGot/Command/add.pm
Criterion Covered Total %
statement 77 78 98.7
branch 12 18 66.6
condition 1 3 33.3
subroutine 22 22 100.0
pod 0 1 0.0
total 112 122 91.8


line stmt bran cond sub pod time code
1             package App::GitGot::Command::add;
2             our $AUTHORITY = 'cpan:GENEHACK';
3             $App::GitGot::Command::add::VERSION = '1.337';
4             # ABSTRACT: add a new repo to your config
5 15     15   1344814 use 5.014;
  15         100  
6              
7 15     15   126 use Class::Load qw/ try_load_class /;
  15         43  
  15         1574  
8 15     15   7844 use Config::INI::Reader;
  15         432966  
  15         668  
9 15     15   141 use Cwd;
  15         43  
  15         1396  
10 15     15   7119 use IO::Prompt::Simple;
  15         28061  
  15         1038  
11 15     15   141 use List::Util qw/ any pairmap /;
  15         40  
  15         1642  
12 15     15   118 use Path::Tiny;
  15         32  
  15         875  
13 15     15   6520 use PerlX::Maybe;
  15         36061  
  15         100  
14 15     15   1080 use Types::Standard -types;
  15         37  
  15         407  
15              
16 15     15   86137 use App::GitGot -command;
  15         58  
  15         279  
17 15     15   72874 use App::GitGot::Repo::Git;
  15         42  
  15         784  
18              
19 15     15   122 use Moo;
  15         49  
  15         271  
20             extends 'App::GitGot::Command';
21 15     15   9106 use namespace::autoclean;
  15         40  
  15         326  
22              
23             sub options {
24 8     8 0 1536 my( $class , $app ) = @_;
25             return (
26 8         162 [ 'defaults|D' => 'FIXME' => { default => 0 } ] ,
27             [ 'origin|o=s' => 'FIXME' => { default => 'origin' } ] ,
28             [ 'recursive' => 'search all sub-directories for repositories' => { default => 0 } ],
29             );
30             }
31              
32 8     8   47 sub _use_io_page { 0 }
33              
34             sub _execute {
35 8     8   30 my ( $self, $opt, $args ) = @_;
36              
37 8         24 my @dirs = @$args;
38 8 50       50 push @dirs, '.' unless @dirs; # default dir is this one
39              
40 8 100       98 if( $self->opt->recursive ) { # hunt for repos
41 1 50       42 try_load_class( 'Path::Iterator::Rule' )
42             or die "--recursive requires module 'Path::Iterator::Rule' to be installed\n";
43              
44             Path::Iterator::Rule->add_helper(
45             is_git => sub {
46             return sub {
47 29         14130 my $item = shift;
48 29         523 return -d "$item/.git";
49             }
50 1     1   111 }
51 1         185 );
52              
53 1         80 @dirs = Path::Iterator::Rule->new->dir->is_git->all(@dirs);
54             }
55              
56 8         2291 $self->_process_dir($_) for map { path($_)->absolute } @dirs;
  9         284  
57             }
58              
59             sub _build_new_entry_from_user_input {
60 8     8   32 my( $self, $path ) = @_;
61              
62 8 100       197 unless ( -e "$path/.git" ) {
63 1         38 say STDERR "ERROR: Non-git repos not supported at this time.";
64 1         32 exit(1);
65             }
66              
67 7         229 my( $repo, $type ) = $self->_init_for_git( $path );
68              
69             # if 'defaults' option is true, tell IO::Prompt::Simple to use default choices
70 7         80 $ENV{PERL_IOPS_USE_DEFAULT} = $self->opt->defaults;
71              
72 7 50       124 return unless prompt( "\nAdd repository at '$path'? ", { yn => 1, default => 'y' } );
73              
74 7         2650 my $name = prompt( 'Name? ', lc path( $path )->basename );
75              
76 7         1357 my $remote;
77 7 50       56 if ( 1 == scalar keys %$repo ) { # one remote? No choice
78 0         0 ($remote) = values %$repo;
79             }
80             else {
81             $remote = prompt( 'Tracking remote? ', {
82             anyone => $repo,
83             verbose => 1,
84 7   33     94 maybe default => ( $repo->{$self->opt->origin} && $self->opt->origin ),
85             });
86             }
87              
88             return App::GitGot::Repo::Git->new({ entry => {
89             type => $type,
90             path => "$path", # Path::Tiny to string coercion
91             name => $name,
92             repo => $remote,
93 7 50       1188 maybe tags => ( join ' ', prompt( 'Tags? ', join ' ', @{$self->tags||[]} )),
  7         313  
94             }});
95             }
96              
97             sub _init_for_git {
98 7     7   25 my( $self, $path ) = @_;
99              
100             ### FIXME probably should have some error handling here...
101 7         37 my $cfg = Config::INI::Reader->read_file("$path/.git/config");
102              
103 7 50   7   7466 my %remotes = pairmap { $a =~ /remote "(.*?)"/ ? ( $1 => $b->{url} ) : () } %$cfg;
  7         57  
104              
105 7         83 return ( \%remotes, 'git' );
106             }
107              
108             sub _process_dir {
109 9     9   4213 my( $self, $dir ) = @_;
110              
111             # first thing, do we already "got" it?
112             return warn "Repository at '$dir' already registered with Got, skipping\n"
113 9 100   3   403 if any { $_ eq $dir } map { $_->path } $self->all_repos;
  3         52  
  3         400  
114              
115 8         852 $self->add_repo(
116             $self->_build_new_entry_from_user_input($dir)
117             );
118              
119 7         1411 $self->write_config;
120             }
121              
122             1;
123              
124             __END__