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.339';
4             # ABSTRACT: add a new repo to your config
5 15     15   1414716 use 5.014;
  15         101  
6              
7 15     15   121 use Class::Load qw/ try_load_class /;
  15         51  
  15         2078  
8 15     15   8020 use Config::INI::Reader;
  15         436052  
  15         732  
9 15     15   162 use Cwd;
  15         40  
  15         1614  
10 15     15   7261 use IO::Prompt::Simple;
  15         28251  
  15         1102  
11 15     15   148 use List::Util qw/ any pairmap /;
  15         72  
  15         1676  
12 15     15   138 use Path::Tiny;
  15         57  
  15         901  
13 15     15   6684 use PerlX::Maybe;
  15         36263  
  15         77  
14 15     15   1013 use Types::Standard -types;
  15         40  
  15         396  
15              
16 15     15   86402 use App::GitGot -command;
  15         63  
  15         247  
17 15     15   75007 use App::GitGot::Repo::Git;
  15         43  
  15         827  
18              
19 15     15   101 use Moo;
  15         43  
  15         263  
20             extends 'App::GitGot::Command';
21 15     15   9046 use namespace::autoclean;
  15         44  
  15         361  
22              
23             sub options {
24 8     8 0 1548 my( $class , $app ) = @_;
25             return (
26 8         215 [ '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         27 my @dirs = @$args;
38 8 50       63 push @dirs, '.' unless @dirs; # default dir is this one
39              
40 8 100       105 if( $self->opt->recursive ) { # hunt for repos
41 1 50       38 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         13927 my $item = shift;
48 29         573 return -d "$item/.git";
49             }
50 1     1   109 }
51 1         126 );
52              
53 1         86 @dirs = Path::Iterator::Rule->new->dir->is_git->all(@dirs);
54             }
55              
56 8         2223 $self->_process_dir($_) for map { path($_)->absolute } @dirs;
  9         262  
57             }
58              
59             sub _build_new_entry_from_user_input {
60 8     8   33 my( $self, $path ) = @_;
61              
62 8 100       205 unless ( -e "$path/.git" ) {
63 1         39 say STDERR "ERROR: Non-git repos not supported at this time.";
64 1         37 exit(1);
65             }
66              
67 7         246 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         69 $ENV{PERL_IOPS_USE_DEFAULT} = $self->opt->defaults;
71              
72 7 50       126 return unless prompt( "\nAdd repository at '$path'? ", { yn => 1, default => 'y' } );
73              
74 7         2674 my $name = prompt( 'Name? ', lc path( $path )->basename );
75              
76 7         1717 my $remote;
77 7 50       49 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     77 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       1121 maybe tags => ( join ' ', prompt( 'Tags? ', join ' ', @{$self->tags||[]} )),
  7         302  
94             }});
95             }
96              
97             sub _init_for_git {
98 7     7   42 my( $self, $path ) = @_;
99              
100             ### FIXME probably should have some error handling here...
101 7         46 my $cfg = Config::INI::Reader->read_file("$path/.git/config");
102              
103 7 50   7   7444 my %remotes = pairmap { $a =~ /remote "(.*?)"/ ? ( $1 => $b->{url} ) : () } %$cfg;
  7         59  
104              
105 7         94 return ( \%remotes, 'git' );
106             }
107              
108             sub _process_dir {
109 9     9   4282 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   388 if any { $_ eq $dir } map { $_->path } $self->all_repos;
  3         69  
  3         372  
114              
115 8         883 $self->add_repo(
116             $self->_build_new_entry_from_user_input($dir)
117             );
118              
119 7         1371 $self->write_config;
120             }
121              
122             1;
123              
124             __END__