7 use Fedora
::Rebuild
::Set
::Package
;
8 use Fedora
::Rebuild
::Package
;
9 use Fedora
::Rebuild
::Scheduler
;
18 rebuildsync - Reset package for rebuild if remote repository has changed
22 rebuildsync [--config FILE] < PACKAGE_LIST
26 This tool checks packages listed on standard input or in a file named in
27 positional arguments for newer version in remote GIT repository.
29 This is a helper for L<rebuildperl(1)> and it assumes the packages have
30 already been populated by rebuildperl. This tool compares local copy of origin
31 GIT repository with repository on the remote server and if it finds the HEADs
32 are different, it will reset the local repository and removes all stage locks
33 except I<.clone>. It will also edit I<all>, I<done>, and I<failed> package
34 lists (see the configuration) accordingly. (It will remove changed packaged
35 from done and failed list.)
39 my $cfgfile = File
::Spec
->catfile($ENV{HOME
}, '.rebuildperlrc');
53 =head2 --config I<FILE>
55 Read configuration from I<FILE>, or F<~/.rebuildperlrc> if not specified.
59 =head2 F<~/.rebuildperlrc>
61 Configuration is in L<Config::Tiny> format. Following options are needed:
72 # Remove listed packages from file.
74 my ($file_name, $packages) = @_;
76 print "Strippig packages from file `$file_name'...\n";
79 # Write mode for exclusive lock
80 open($file, '+<', $file_name) or
81 croak
"Could not open `$file_name': $!";
82 flock($file, Fcntl
::LOCK_EX
) or
83 croak
"Could not lock `$file_name' file: $!";
86 my ($new_file, $new_file_name) =
87 File
::Temp
::tempfile
($file_name . 'XXXXXX', UNLINK
=> 0, EXLOCK
=> 1);
89 # Filter input file into output file
90 while (local $_ = <$file>) {
92 if (m/^\s*$/) { next; }
93 if ($packages->contains($_)) { next; }
94 print $new_file "$_\n" or
95 croak
"Could not write into temporary file `$new_file_name' :$!";
98 croak
"Could not read list of package names fromfile `$file_name' :$!";
101 # Finish writing and replace the the files
102 $new_file->flush && $new_file->sync or
103 croak
"Could not flush temporary file `$new_file_name': $!";
104 rename $new_file_name, $file_name or
105 croak
"Could not replace file `$file_name' with stripped " .
106 "`$new_file_name': $!";
108 croak
"Could not close `$file_name': $!";
110 # This unlocks input file.
113 print "Strippig packages from file `$file_name' finished successfully.\n";
117 GetOptions
('config=s' => \
$cfgfile) or die "Could not parse program options\n";
121 my $cfg = Config
::Tiny
->new->read($cfgfile);
122 if (! defined $cfg) {
123 print STDERR
"Could not parse `" . $cfgfile .
124 "' configuration file: " . $Config::Tiny
::errstr
. "\n";
127 foreach (keys %{$cfg->{_
}}) {
128 $config{$_} = $cfg->{_
}->{$_};
129 $config{$_} = eval $config{$_} if $_ eq 'buildrequiresfilter';
133 # Load list of packages to synchronize
134 my $packages = Fedora
::Rebuild
::Set
::Package
->new();
135 print "Loading list of package names to synchronize with remote origin...\n";
136 while (local $_ = <>) {
138 if (m/^\s*$/) { next; }
139 if ($packages->contains($_)) { next; }
140 my $package = Fedora
::Rebuild
::Package
->new(name
=> $_,
141 workdir
=> $config{workdir
}, dist
=> $config{dist
},
142 pkgdist
=> $config{pkgdist
}, target
=> $config{target
},
143 message
=> $config{message
});
144 $packages->insert($package);
147 croak
"Could not read list of package names to synchronize: $!";
149 print "Number of packages: " . $packages->size() . "\n";
152 my $changed_packages = Fedora
::Rebuild
::Set
::Package
->new();
155 my $scheduler = Fedora
::Rebuild
::Scheduler
->new(
156 limit
=> $config{loadthreads
},
157 name
=> 'Checking remote repository',
158 total
=> $packages->size
163 for my $package ($packages->packages) {
164 my $job = $scheduler->schedule($package->can('reset_remotly_updated'),
166 if (! defined $job) {
169 $jobs{$job} = $package;
170 my %finished = $scheduler->finish(++$i < $packages->size);
172 while (my ($job, $status) = each %finished) {
173 my $package = $jobs{$job};
175 print "Could not check remote repository for package `",
176 $package->name, "'.\n";
177 print "Waiting for finishing scheduled jobs...\n";
178 $scheduler->finish(1);
179 print "All jobs have finished.\n";
180 croak
"Could not check all packages for remote changes.\n";
181 } elsif (2 == $$status[0]) {
182 print "`", $package->name,
183 "' has been remotly changed and locally reset.\n";
184 $changed_packages->insert($package);
189 if ($changed_packages->size > 0) {
190 print "Following packages have been changed in the remote repository ",
191 "and thus locally reset (",
192 $changed_packages->size, "): ", $changed_packages->string, "\n";
193 edit_file
($config{done
}, $changed_packages);
194 edit_file
($config{failed
}, $changed_packages);
196 print "None package has been changed in the remote repository.\n";