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.336';
4             # ABSTRACT: add a new repo to your config
5 15     15   1015104 use 5.014;
  15         62  
6              
7 15     15   95 use Class::Load qw/ try_load_class /;
  15         32  
  15         1108  
8 15     15   6269 use Config::INI::Reader;
  15         329572  
  15         483  
9 15     15   103 use Cwd;
  15         29  
  15         1031  
10 15     15   5367 use IO::Prompt::Simple;
  15         21748  
  15         777  
11 15     15   101 use List::Util qw/ any pairmap /;
  15         27  
  15         1222  
12 15     15   81 use Path::Tiny;
  15         28  
  15         630  
13 15     15   4726 use PerlX::Maybe;
  15         19139  
  15         772  
14 15     15   152 use Types::Standard -types;
  15         40  
  15         395  
15              
16 15     15   66095 use App::GitGot -command;
  15         29  
  15         169  
17 15     15   53767 use App::GitGot::Repo::Git;
  15         27  
  15         578  
18              
19 15     15   86 use Moo;
  15         28  
  15         199  
20             extends 'App::GitGot::Command';
21 15     15   6768 use namespace::autoclean;
  15         36  
  15         229  
22              
23             sub options {
24 8     8 0 1567 my( $class , $app ) = @_;
25             return (
26 8         145 [ '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   42 sub _use_io_page { 0 }
33              
34             sub _execute {
35 8     8   23 my ( $self, $opt, $args ) = @_;
36              
37 8         20 my @dirs = @$args;
38 8 50       45 push @dirs, '.' unless @dirs; # default dir is this one
39              
40 8 100       80 if( $self->opt->recursive ) { # hunt for repos
41 1 50       30 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         11460 my $item = shift;
48 29         416 return -d "$item/.git";
49             }
50 1     1   84 }
51 1         107 );
52              
53 1         64 @dirs = Path::Iterator::Rule->new->dir->is_git->all(@dirs);
54             }
55              
56 8         994 $self->_process_dir($_) for map { path($_)->absolute } @dirs;
  9         208  
57             }
58              
59             sub _build_new_entry_from_user_input {
60 8     8   25 my( $self, $path ) = @_;
61              
62 8 100       163 unless ( -e "$path/.git" ) {
63 1         31 say STDERR "ERROR: Non-git repos not supported at this time.";
64 1         27 exit(1);
65             }
66              
67 7         186 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         65 $ENV{PERL_IOPS_USE_DEFAULT} = $self->opt->defaults;
71              
72 7 50       113 return unless prompt( "\nAdd repository at '$path'? ", { yn => 1, default => 'y' } );
73              
74 7         2224 my $name = prompt( 'Name? ', lc path( $path )->basename );
75              
76 7         1096 my $remote;
77 7 50       40 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     76 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       1024 maybe tags => ( join ' ', prompt( 'Tags? ', join ' ', @{$self->tags||[]} )),
  7         250  
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         39 my $cfg = Config::INI::Reader->read_file("$path/.git/config");
102              
103 7 50   7   6609 my %remotes = pairmap { $a =~ /remote "(.*?)"/ ? ( $1 => $b->{url} ) : () } %$cfg;
  7         58  
104              
105 7         82 return ( \%remotes, 'git' );
106             }
107              
108             sub _process_dir {
109 9     9   3337 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   308 if any { $_ eq $dir } map { $_->path } $self->all_repos;
  3         39  
  3         281  
114              
115 8         661 $self->add_repo(
116             $self->_build_new_entry_from_user_input($dir)
117             );
118              
119 7         2046 $self->write_config;
120             }
121              
122             1;
123              
124             __END__