7 use Fedora
::Rebuild
::Set
::Package
;
8 use Fedora
::Rebuild
::Package
;
9 use Fedora
::Rebuild
::Scheduler
;
10 use Fedora
::Rebuild
::Package
::ListLog
;
19 rebuildreset - Reset package for rebuild
23 rebuilreset [--config FILE] [--changed] < PACKAGE_LIST
27 This tool resets packages listed on standard input or in a file named in
28 positional arguments, so that next L<rebuildperl(1)> will consider the
29 packages as not yet rebuilt.
31 This is a helper for L<rebuildperl(1)> and it assumes the packages have
32 already been populated by rebuildperl. It will reset the local repository and
33 removes all stage locks except I<.clone>. It will also edit I<all>, I<done>,
34 and I<failed> package lists (see the configuration) accordingly. (It will
35 remove changed packaged from done and failed list.)
37 With other options, the set of packages to reset can be reduced more.
41 my $cfgfile = File
::Spec
->catfile($ENV{HOME
}, '.rebuildperlrc');
57 =head2 --config I<FILE>
59 Read configuration from I<FILE>, or F<~/.rebuildperlrc> if not specified.
63 Reset only packages whose remote repository has changed (e.g. there is a newer
64 version). It compares local copy of I<origin> GIT repository with repository
65 on the remote server and if it finds the HEADs are different it will reset the
66 package. Otherwise the package will not be reset.
68 If I<failedtemp> configuration option is defined and there is an error while
69 checking the remote repository, the faulting package will be logged into
70 the I<failedtemp> file. This is because talking to a GIT server can result
71 into intermittent network error that can disappear on next retry.
75 =head2 F<~/.rebuildperlrc>
77 Configuration is in L<Config::Tiny> format. Following options are needed:
81 failedtemp = failedtemp
89 # Remove listed packages from file.
91 my ($file_name, $packages) = @_;
93 print "Strippig packages from file `$file_name'...\n";
96 # Write mode for exclusive lock
97 open($file, '+<', $file_name) or
98 croak
"Could not open `$file_name': $!";
99 flock($file, Fcntl
::LOCK_EX
) or
100 croak
"Could not lock `$file_name' file: $!";
103 my ($new_file, $new_file_name) =
104 File
::Temp
::tempfile
($file_name . 'XXXXXX', UNLINK
=> 0, EXLOCK
=> 1);
106 # Filter input file into output file
107 while (local $_ = <$file>) {
109 if (m/^\s*$/) { next; }
110 if ($packages->contains($_)) { next; }
111 print $new_file "$_\n" or
112 croak
"Could not write into temporary file `$new_file_name' :$!";
115 croak
"Could not read list of package names fromfile `$file_name' :$!";
118 # Finish writing and replace the the files
119 $new_file->flush && $new_file->sync or
120 croak
"Could not flush temporary file `$new_file_name': $!";
121 rename $new_file_name, $file_name or
122 croak
"Could not replace file `$file_name' with stripped " .
123 "`$new_file_name': $!";
125 croak
"Could not close `$file_name': $!";
127 # This unlocks input file.
130 print "Strippig packages from file `$file_name' finished successfully.\n";
135 'config=s' => \
$cfgfile,
136 'changed' => \
$changed_only
137 ) or die "Could not parse program options\n";
141 my $cfg = Config
::Tiny
->new->read($cfgfile);
142 if (! defined $cfg) {
143 print STDERR
"Could not parse `" . $cfgfile .
144 "' configuration file: " . $Config::Tiny
::errstr
. "\n";
147 foreach (keys %{$cfg->{_
}}) {
148 $config{$_} = $cfg->{_
}->{$_};
149 $config{$_} = eval $config{$_} if $_ eq 'buildrequiresfilter';
153 # Load list of packages to synchronize
154 my $packages = Fedora
::Rebuild
::Set
::Package
->new();
155 print "Loading list of package names...\n";
156 while (local $_ = <>) {
158 if (m/^\s*$/) { next; }
159 if ($packages->contains($_)) { next; }
160 my $package = Fedora
::Rebuild
::Package
->new(name
=> $_,
161 workdir
=> $config{workdir
}, dist
=> $config{dist
},
162 pkgdist
=> $config{pkgdist
}, target
=> $config{target
},
163 message
=> $config{message
});
164 $packages->insert($package);
167 croak
"Could not read list of package names: $!";
169 print "Number of packages: " . $packages->size() . "\n";
172 my $changed_packages = Fedora
::Rebuild
::Set
::Package
->new();
173 my $temporary_error = 0;
176 my $scheduler = Fedora
::Rebuild
::Scheduler
->new(
177 limit
=> $config{loadthreads
},
178 name
=> ($changed_only) ?
179 'Checking remote repository' : 'Reseting repository',
180 total
=> $packages->size
185 for my $package ($packages->packages) {
186 my $job = $scheduler->schedule($package->can(
187 ($changed_only) ?
'reset_remotly_updated' : 'reset'
189 if (! defined $job) {
192 $jobs{$job} = $package;
193 my %finished = $scheduler->finish(++$i < $packages->size);
195 while (my ($job, $status) = each %finished) {
196 my $package = $jobs{$job};
200 print "Could not check remote repository for package `",
201 $package->name, "'.\n";
203 if (defined $config{failedtemp
}) {
204 Fedora
::Rebuild
::Package
::ListLog
->new(
205 file
=> $config{failedtemp
})->log($package);
207 print "Waiting for finishing scheduled jobs...\n";
208 $scheduler->finish(1);
209 print "All jobs have finished.\n";
210 croak
"Could not check all packages for remote changes.\n";
212 } elsif (2 == $$status[0]) {
213 print "`", $package->name,
214 "' has been remotely changed and locally reset.\n";
215 $changed_packages->insert($package);
219 print "Could not reset package `", $package->name, "'.\n";
220 print "Waiting for finishing scheduled jobs...\n";
221 $scheduler->finish(1);
222 print "All jobs have finished.\n";
223 croak
"Could not reset all specified packages.\n";
225 $changed_packages->insert($package);
230 if ($changed_packages->size > 0) {
231 print "Following packages have been locally reset (",
232 $changed_packages->size, "): ", $changed_packages->string, "\n";
233 edit_file
($config{done
}, $changed_packages);
234 edit_file
($config{failed
}, $changed_packages);
236 print "None package has been reset.\n";
239 if ($temporary_error) {