line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Test::Smoke::Syncer::Git; |
2
|
11
|
|
|
11
|
|
64
|
use warnings; |
|
11
|
|
|
|
|
18
|
|
|
11
|
|
|
|
|
320
|
|
3
|
11
|
|
|
11
|
|
50
|
use strict; |
|
11
|
|
|
|
|
18
|
|
|
11
|
|
|
|
|
368
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '0.029'; |
6
|
|
|
|
|
|
|
|
7
|
11
|
|
|
11
|
|
63
|
use base 'Test::Smoke::Syncer::Base'; |
|
11
|
|
|
|
|
24
|
|
|
11
|
|
|
|
|
1216
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 Test::Smoke::Syncer::Git |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
This handles syncing with git repositories. |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=cut |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
|
16
|
11
|
|
|
11
|
|
65
|
use Cwd; |
|
11
|
|
|
|
|
18
|
|
|
11
|
|
|
|
|
566
|
|
17
|
11
|
|
|
11
|
|
69
|
use File::Spec::Functions; |
|
11
|
|
|
|
|
61
|
|
|
11
|
|
|
|
|
1055
|
|
18
|
11
|
|
|
11
|
|
64
|
use Test::Smoke::LogMixin; |
|
11
|
|
|
|
|
37
|
|
|
11
|
|
|
|
|
507
|
|
19
|
11
|
|
|
11
|
|
68
|
use Test::Smoke::Util::Execute; |
|
11
|
|
|
|
|
16
|
|
|
11
|
|
|
|
|
642
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head2 Test::Smoke::Syncer::Git->new( %args ) |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
Keys for C<%args>: |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
* gitorigin |
26
|
|
|
|
|
|
|
* gitdir |
27
|
|
|
|
|
|
|
* gitbin |
28
|
|
|
|
|
|
|
* gitbranchfile |
29
|
|
|
|
|
|
|
* gitdfbranch |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=cut |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head2 $syncer->sync() |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Do the actual syncing. |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
There are 2 repositories, they both need to be updated: |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
The first (proxy) repository has the github.com/Perl repository as its |
40
|
|
|
|
|
|
|
(origin) remote. The second repository is used to run the smoker from. |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
For the proxy-repository we do: |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
git fetch --all |
45
|
|
|
|
|
|
|
git remote prune origin |
46
|
|
|
|
|
|
|
git reset --hard origin/$gitbranch |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
For the working-repository we do: |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
git clean -dfx |
51
|
|
|
|
|
|
|
git fetch --all |
52
|
|
|
|
|
|
|
git reset --hard origin/$gitbranch |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=cut |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub sync { |
57
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
my $gitbin = Test::Smoke::Util::Execute->new( |
60
|
|
|
|
|
|
|
command => $self->{gitbin}, |
61
|
0
|
|
|
|
|
|
verbose => $self->verbose, |
62
|
|
|
|
|
|
|
); |
63
|
11
|
|
|
11
|
|
61
|
use Carp; |
|
11
|
|
|
|
|
49
|
|
|
11
|
|
|
|
|
6788
|
|
64
|
0
|
|
|
|
|
|
my $cwd = cwd(); |
65
|
|
|
|
|
|
|
# Handle the proxy-clone |
66
|
0
|
0
|
0
|
|
|
|
if ( ! -d $self->{gitdir} || ! -d catdir($self->{gitdir}, '.git') ) { |
67
|
|
|
|
|
|
|
my $cloneout = $gitbin->run( |
68
|
|
|
|
|
|
|
clone => $self->{gitorigin}, |
69
|
|
|
|
|
|
|
$self->{gitdir}, |
70
|
0
|
0
|
|
|
|
|
($^O eq 'MSWin32' ? ('--config', 'core.autocrlf=input') : ()), |
71
|
|
|
|
|
|
|
'2>&1' |
72
|
|
|
|
|
|
|
); |
73
|
0
|
0
|
|
|
|
|
if ( my $gitexit = $gitbin->exitcode ) { |
74
|
0
|
|
|
|
|
|
croak("Cannot make initial clone: $self->{gitbin} exit $gitexit"); |
75
|
|
|
|
|
|
|
} |
76
|
0
|
|
|
|
|
|
$self->log_debug("[git clone from $self->{gitorigin}]: $cloneout"); |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
|
my $gitbranch = $self->get_git_branch; |
80
|
0
|
0
|
|
|
|
|
chdir $self->{gitdir} or croak("Cannot chdir($self->{gitdir}): $!"); |
81
|
0
|
|
|
|
|
|
$self->log_debug("chdir($self->{gitdir})"); |
82
|
|
|
|
|
|
|
|
83
|
0
|
|
|
|
|
|
my $gitout = $gitbin->run(remote => 'update', '--prune', '2>&1'); |
84
|
0
|
|
|
|
|
|
$self->log_debug("gitorigin(update --prune): $gitout"); |
85
|
|
|
|
|
|
|
|
86
|
0
|
|
|
|
|
|
$gitout = $gitbin->run(checkout => $gitbranch, '2>&1'); |
87
|
0
|
|
|
|
|
|
$self->log_debug("gitorigin(checkout): $gitout"); |
88
|
|
|
|
|
|
|
|
89
|
0
|
|
|
|
|
|
$gitout = $gitbin->run(reset => '--hard', "origin/$gitbranch", '2>&1'); |
90
|
0
|
|
|
|
|
|
$self->log_debug("gitorigin(reset --hard): $gitout"); |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# Now handle the working-clone |
93
|
0
|
0
|
|
|
|
|
chdir $cwd or croak("Cannot chdir($cwd): $!"); |
94
|
0
|
|
|
|
|
|
$self->log_debug("chdir($cwd)"); |
95
|
|
|
|
|
|
|
# make the working-clone if it doesn't exist yet |
96
|
0
|
0
|
0
|
|
|
|
if ( ! -d $self->{ddir} || ! -d catdir($self->{ddir}, '.git') ) { |
97
|
|
|
|
|
|
|
# It needs to be empty ... |
98
|
|
|
|
|
|
|
my $cloneout = $gitbin->run( |
99
|
|
|
|
|
|
|
clone => $self->{gitdir}, |
100
|
|
|
|
|
|
|
$self->{ddir}, |
101
|
0
|
0
|
|
|
|
|
($^O eq 'MSWin32' ? ('--config', 'core.autocrlf=input') : ()), |
102
|
|
|
|
|
|
|
'2>&1' |
103
|
|
|
|
|
|
|
); |
104
|
0
|
0
|
|
|
|
|
if ( my $gitexit = $gitbin->exitcode ) { |
105
|
0
|
|
|
|
|
|
croak("Cannot make smoke clone: $self->{gitbin} exit $gitexit"); |
106
|
|
|
|
|
|
|
} |
107
|
0
|
|
|
|
|
|
$self->log_debug("[git clone $self->{gitdir}]: $cloneout"); |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
0
|
0
|
|
|
|
|
chdir $self->{ddir} or croak("Cannot chdir($self->{ddir}): $!"); |
111
|
0
|
|
|
|
|
|
$self->log_debug("chdir($self->{ddir})"); |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# reset the working-dir to HEAD of the last branch smoked |
114
|
0
|
|
|
|
|
|
$gitout = $gitbin->run(reset => '--hard', 'HEAD', '2>&1'); |
115
|
0
|
|
|
|
|
|
$self->log_debug("working-dir(reset --hard): $gitout"); |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# remove all untracked files and dirs |
118
|
0
|
|
|
|
|
|
$gitout = $gitbin->run(clean => '-dfx', '2>&1'); |
119
|
0
|
|
|
|
|
|
$self->log_debug("working-dir(clean -dfx): $gitout"); |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
# update from origin |
122
|
0
|
|
|
|
|
|
$gitout = $gitbin->run(fetch => 'origin', '2>&1'); |
123
|
0
|
|
|
|
|
|
$self->log_debug("working-dir(fetch origin): $gitout"); |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
# now checkout the branch we want smoked |
126
|
0
|
|
|
|
|
|
$gitout = $gitbin->run(checkout => $gitbranch, '2>&1'); |
127
|
0
|
|
|
|
|
|
$self->log_debug("working-dir(checkout $gitbranch): $gitout"); |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
# Make sure HEAD is exactly what the branch is |
130
|
0
|
|
|
|
|
|
$gitout = $gitbin->run(reset => '--hard', "origin/$gitbranch", '2>&1'); |
131
|
0
|
|
|
|
|
|
$self->log_debug("working-dir(reset --hard): $gitout"); |
132
|
|
|
|
|
|
|
|
133
|
0
|
|
|
|
|
|
$self->make_dot_patch(); |
134
|
|
|
|
|
|
|
|
135
|
0
|
|
|
|
|
|
chdir $cwd; |
136
|
|
|
|
|
|
|
|
137
|
0
|
|
|
|
|
|
return $self->check_dot_patch; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=head2 $git->get_git_branch() |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
Reads the first line of the file set in B and returns its |
143
|
|
|
|
|
|
|
value. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=cut |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
sub get_git_branch { |
148
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
149
|
|
|
|
|
|
|
|
150
|
0
|
0
|
|
|
|
|
return $self->{gitdfbranch} if !$self->{gitbranchfile}; |
151
|
0
|
0
|
|
|
|
|
return $self->{gitdfbranch} if ! -f $self->{gitbranchfile}; |
152
|
|
|
|
|
|
|
|
153
|
0
|
0
|
|
|
|
|
if (open my $fh, '<', $self->{gitbranchfile}) { |
154
|
0
|
|
|
|
|
|
$self->log_debug("Reading branch to smoke from: '$self->{gitbranchfile}'"); |
155
|
|
|
|
|
|
|
|
156
|
0
|
|
|
|
|
|
chomp( my $branch = <$fh> ); |
157
|
0
|
|
|
|
|
|
close $fh; |
158
|
0
|
|
|
|
|
|
return $branch; |
159
|
|
|
|
|
|
|
} |
160
|
0
|
|
|
|
|
|
$self->log_warn("Error opening '$self->{gitbranchfile}': $!"); |
161
|
0
|
|
|
|
|
|
return $self->{gitdfbranch}; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
1; |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=head1 COPYRIGHT |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
(c) 2002-2013, All rights reserved. |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
* Abe Timmerman |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
173
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
See: |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
* , |
178
|
|
|
|
|
|
|
* |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, |
181
|
|
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
182
|
|
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=cut |