File Coverage

blib/lib/Git/Megapull.pm
Criterion Covered Total %
statement 18 59 30.5
branch 0 24 0.0
condition 0 3 0.0
subroutine 6 11 54.5
pod 2 2 100.0
total 26 99 26.2


line stmt bran cond sub pod time code
1 1     1   26623 use strict;
  1         3  
  1         35  
2 1     1   5 use warnings;
  1         2  
  1         55  
3             package Git::Megapull;
4             {
5             $Git::Megapull::VERSION = '0.101752';
6             }
7 1     1   5 use base 'App::Cmd::Simple';
  1         2  
  1         969  
8             # ABSTRACT: clone or update all repositories found elsewhere
9              
10 1     1   56302 use autodie;
  1         19546  
  1         7  
11 1     1   6677 use Config::GitLike;
  1         57219  
  1         54  
12 1     1   1027 use String::RewritePrefix;
  1         1014  
  1         7  
13              
14              
15             sub opt_spec {
16             return (
17             # [ 'private|p!', 'include private repositories' ],
18 0     0 1   [ 'bare|b!', 'produce bare clones' ],
19             [ 'clonely|c', 'only clone things that do not exist; skip others' ],
20             [ 'origin=o', 'name to use when creating or fetching; default: origin',
21             { default => 'origin' } ],
22             [ 'source|s=s', "the source class (or a short form of it)",
23             { default => $ENV{GIT_MEGAPULL_SOURCE} } ],
24             );
25             }
26              
27             sub execute {
28 0     0 1   my ($self, $opt, $args) = @_;
29              
30 0           my $source = $opt->{source};
31 0 0         unless ($source) {
32 0           my $config = Config::GitLike->new(confname => "$ENV{HOME}/.gitconfig");
33 0           $config->load;
34 0           $source = $config->get(key => "megapull.source");
35             }
36              
37 0   0       $source ||= $self->_default_source;
38              
39 0 0         $self->usage_error("no source provided") unless $source;
40              
41 0           $source = String::RewritePrefix->rewrite(
42             { '' => 'Git::Megapull::Source::', '=' => '' },
43             $source,
44             );
45              
46             # XXX: validate $source as module name -- rjbs, 2009-09-13
47             # XXX: validate $opt->{origin} -- rjbs, 2009-09-13
48              
49 0 0         eval "require $source; 1" or die;
50              
51             die "bad source: not a Git::Megapull::Source\n"
52 0 0         unless eval { $source->isa('Git::Megapull::Source') };
  0            
53              
54 0           my $repos = $source->repo_uris;
55              
56 0 0         my %existing_dir = map { $_ => 1 } grep { $_ !~ m{\A\.} and -d $_ } <*>;
  0            
  0            
57              
58 0           for my $name (sort { $a cmp $b } keys %$repos) {
  0            
59 0           my $name = $name;
60 0           my $uri = $repos->{ $name };
61 0 0         my $dirname = $opt->{bare} ? "$name.git" : $name;
62              
63 0 0         if (-d $dirname) {
64 0 0         if (not $opt->{clonely}) {
65 0 0         my $merge = $opt->{bare} ? '' : "&& git merge $opt->{origin}/master";
66 0           $self->__do_cmd(
67             "cd $dirname && "
68             . "git fetch $opt->{origin} $merge"
69             );
70             }
71             } else {
72 0           $self->_clone_repo($name, $uri, $opt);
73             }
74              
75 0           delete $existing_dir{ $dirname };
76             }
77              
78 0           for (keys %existing_dir) {
79 0           warn "unknown directory found: $_\n";
80             }
81             }
82              
83 0     0     sub _default_source {}
84             sub _clone_repo {
85 0     0     my ($self, $repo, $uri, $opt) = @_;
86              
87 0 0         my $bare = $opt->{bare} ? '--bare' : '';
88             # git clone --origin doesn't work with --bare on git 1.6.6.1 or git
89             # 1.7: "fatal: --bare and --origin origin options are incompatible."
90 0 0         my $orig = $opt->{bare} ? '' : "--origin $opt->{origin}";
91 0           $self->__do_cmd("git clone $orig $bare $uri");
92              
93 0 0         if ($opt->{bare}) {
94             # Add an origin remote so we can git fetch later
95 0           my ($target) = $uri =~ m[/(.*?)$];
96 0           $self->__do_cmd("(cd $target && git remote add origin $uri && cd ..)");
97             }
98             }
99              
100             sub __do_cmd {
101 0     0     my ($self, $cmd) = @_;
102 0           print "$cmd\n";
103 0           system("$cmd");
104             }
105              
106             1;
107              
108             __END__