File Coverage

blib/lib/Github/Backup.pm
Criterion Covered Total %
statement 62 111 55.8
branch 17 56 30.3
condition 10 15 66.6
subroutine 15 20 75.0
pod 4 5 80.0
total 108 207 52.1


line stmt bran cond sub pod time code
1             package Github::Backup;
2              
3 6     6   60134 use strict;
  6         34  
  6         148  
4 6     6   25 use warnings;
  6         9  
  6         138  
5              
6 6     6   25 use Carp qw(croak);
  6         18  
  6         370  
7 6     6   3105 use Data::Dumper;
  6         36700  
  6         384  
8 6     6   2582 use Git::Repository;
  6         246697  
  6         23  
9 6     6   2559 use Hook::Output::Tiny;
  6         5531  
  6         168  
10 6     6   2534 use File::Copy;
  6         23271  
  6         338  
11 6     6   42 use File::Path;
  6         10  
  6         339  
12 6     6   3196 use JSON;
  6         51389  
  6         41  
13 6     6   4031 use LWP::UserAgent;
  6         211828  
  6         203  
14 6     6   3416 use Moo;
  6         42592  
  6         30  
15 6     6   10254 use Pithub;
  6         660067  
  6         217  
16              
17 6     6   47 use namespace::clean;
  6         10  
  6         52  
18              
19             our $VERSION = '1.03';
20              
21             # external
22              
23             has api_user => (
24             is => 'rw',
25             );
26             has _clean => (
27             # used to clean up test backup directories
28             is => 'rw',
29             );
30             has dir => (
31             is => 'rw',
32             );
33             has forks => (
34             is => 'rw',
35             );
36             has token => (
37             is => 'rw',
38             );
39             has proxy => (
40             is => 'rw',
41             );
42             has user => (
43             is => 'rw',
44             );
45             has limit => (
46             is => 'rw',
47             );
48              
49             # internal
50              
51             has gh => (
52             # Pithub object
53             is => 'rw',
54             );
55             has stg => (
56             # staging dir
57             is => 'rw',
58             );
59              
60             sub BUILD {
61 6     6 0 9657 my ($self) = @_;
62              
63 6 100       24 if (! $self->token){
64 2 50       6 $self->token($ENV{GITHUB_TOKEN}) if $ENV{GITHUB_TOKEN};
65             }
66              
67 6         13 for my $key (qw/api_user token dir/){
68 13 100       29 if (! $self->{$key}){
69 4         442 croak "ERROR: Missing mandatory parameter [$key].\n";
70             }
71             }
72              
73 2         16 my $ua = LWP::UserAgent->new;
74              
75 2 100       5034 if ($self->proxy){
76 1         10 $ENV{http_proxy} = $self->proxy;
77 1         6 $ENV{https_proxy} = $self->proxy;
78              
79 1         5 $ua->env_proxy;
80             }
81              
82 2         42849 my $gh = Pithub->new(
83             ua => $ua,
84             user => $self->api_user,
85             token => $self->token,
86             auto_pagination => 1,
87             );
88              
89 2         19166 $self->stg($self->dir . '.stg');
90 2         9 $self->gh($gh);
91              
92 2 50       18 $self->user($self->api_user) if ! defined $self->user;
93              
94 2 50       105 if (-d $self->stg){
95 0 0       0 rmtree $self->stg or die "can't remove the old staging directory...$!";
96             }
97              
98 2 50       294 mkdir $self->stg or die "can't create the backup staging directory...$!\n";
99             }
100              
101             sub list {
102 0     0 1 0 my ($self) = @_;
103              
104 0 0       0 if (! $self->{repo_list}) {
105 0         0 my $repo_list = $self->gh->repos->list(user => $self->user);
106 0         0 while (my $repo = $repo_list->next) {
107 0         0 push @{ $self->{repo_list} }, $repo;
  0         0  
108             }
109             }
110              
111 0         0 return $self->{repo_list};
112             }
113             sub repos {
114 0     0 1 0 my ($self) = @_;
115              
116 0         0 my $repos = $self->list;
117              
118 0         0 my $repo_count = 0;
119 0         0 for my $repo (@$repos){
120 0         0 $repo_count++;
121              
122 0 0       0 if ($self->limit) {
123 0 0       0 last if $repo_count >= $self->limit;
124             }
125              
126 0         0 $self->_trap->hook('stderr');
127              
128 0         0 print "Cloning $repo->{name}\n";
129              
130 0         0 my $stg = $self->stg . "/$repo->{name}";
131              
132 0 0       0 if (! $self->forks){
133 0 0       0 if (! exists $repo->{parent}){
134             Git::Repository->run(
135 0         0 clone => $repo->{clone_url} => $stg,
136             { quiet => 0 }
137             );
138             }
139             }
140             else {
141             Git::Repository->run(
142 0         0 clone => $repo->{clone_url} => $stg,
143             { quiet => 0 }
144             );
145             }
146 0         0 $self->_trap->unhook('stderr');
147             }
148             }
149             sub issues {
150 0     0 1 0 my ($self) = @_;
151              
152 0 0       0 mkdir $self->stg . "/issues" or die "can't create the 'issues' dir: $!";
153              
154 0         0 my $repos = $self->list;
155              
156 0         0 my $repo_count = 0;
157              
158 0         0 for my $repo (@$repos) {
159 0         0 $repo_count++;
160              
161 0 0       0 if ($self->limit) {
162 0 0       0 last if $repo_count >= $self->limit;
163             }
164              
165             my $issue_list = $self->gh->issues->list(
166             user => $self->user,
167             repo => $repo->{name}
168 0         0 );
169              
170 0         0 my $issue_dir = $self->stg . "/issues/$repo->{name}";
171              
172 0         0 my $dir_created = 0;
173              
174 0         0 while (my $issue = $issue_list->next){
175 0 0       0 if (! $dir_created) {
176 0 0       0 mkdir $issue_dir or die $!;
177 0         0 $dir_created = 1;
178             }
179 0 0       0 open my $fh, '>', "$issue_dir/$issue->{id}"
180             or die "can't create the issue file";
181              
182 0         0 print "Copied $repo->{name} issue #$issue->{number}\n";
183              
184 0         0 print $fh encode_json $issue;
185             }
186             }
187             }
188             sub finish {
189 0     0 1 0 my ($self) = @_;
190 0 0 0     0 if ($self->stg && -d $self->stg) {
191 0 0       0 move $self->stg,
192             $self->dir or die "can't rename the staging directory: $!";
193             }
194             }
195             sub _trap {
196 0     0   0 my ($self) = @_;
197 0 0       0 if (! $self->{trap}) {
198 0         0 $self->{trap} = Hook::Output::Tiny->new;
199             }
200              
201 0         0 return $self->{trap};
202             }
203             sub DESTROY {
204 6     6   3284 my $self = shift;
205              
206 6 50 66     112 if ($self->dir && -d $self->dir) {
207 0 0       0 rmtree $self->dir or die "can't remove the old backup directory: $!";
208             }
209              
210 6 100 66     60 if ($self->stg && -d $self->stg) {
211 2 50       21 move $self->stg,
212             $self->dir or die "can't rename the staging directory: $!";
213             }
214              
215 6 100 100     303 if ($self->dir && -d $self->dir && $self->_clean) {
      100        
216             # we're in testing mode, clean everything up
217 1 50       441 rmtree $self->dir
218             or die "can't remove the test backup directory...$!";
219             }
220             }
221              
222             1;
223             __END__