1 package Fedora
::Rebuild
::Package
;
9 use Fedora
::Rebuild
::Package
::StateLock
;
10 use Fedora
::Rebuild
::RPM
;
11 use Fedora
::Rebuild
::Mock
;
15 use version
0.77; our $VERSION = version
->declare("v0.8.0");
17 has
'name' => (is
=> 'ro', isa
=> 'Str', required
=> 1);
18 # Build-time dependencies
19 has
'requires' => (is
=> 'rw', isa
=> 'HashRef', lazy_build
=> 1,
21 # Run-time dependencies hashed by binary package ENVR.
22 has
'runrequires' => (is
=> 'rw', isa
=> 'HashRef', lazy_build
=> 1,
24 # Run-time provides hashes by binary package ENVR.
25 has
'provides' => (is
=> 'rw', isa
=> 'HashRef', lazy_build
=> 1,
27 has
'workdir' => (is
=> 'ro', isa
=> 'Str', required
=> 1);
29 # "f14", "f15" etc. Use "rawhide" for latest one.
30 has
'dist' => (is
=> 'ro', isa
=> 'Str', required
=> 1);
32 # "dist-f14", "dist-f15" etc. Use "rawhide" for latest one.
33 has
'target' => (is
=> 'ro', isa
=> 'Str', required
=> 1);
34 has
'message' => (is
=> 'ro', isa
=> 'Str', required
=> 1);
36 has
'packagedir' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
38 has
'repodir' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
40 has
'mockdir' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
42 has
'rpmdir' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
44 has
'requiresstore' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
46 has
'runrequiresstore' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
48 has
'providesstore' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
50 has
'taskstore' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
52 has
'branch' => (is
=> 'ro', isa
=> 'Str', lazy_build
=> 1,
55 # Make object shared between threads.
56 # XXX: Not all attributes are shared automatically.
60 return shared_clone
($class->$orig(@_));
63 # Clean package locks bound to attributes
66 for my $state ('buildrequires', 'runrequires', 'provides') {
67 Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
68 state => $state)->mark_failed;
72 # BuildRequires. Shared.
73 # Initialize to empty hash. Call get_buildrequires() to populate.
76 my $requires :shared
= shared_clone
({});
80 # Run-time Requires. Shared.
81 # Initialize to empty hash. Call get_runrequires() to populate.
82 sub _build_runrequires
{
84 my $runrequires :shared
= shared_clone
({});
88 # Run-time provides. Shared.
89 # Initialize to empty hash. Call rebuild() or get_binaryprovides() to populate.
92 my $provides :shared
= shared_clone
({});
96 sub _build_packagedir
{
98 my $directory = File
::Spec
->catfile($self->workdir, $self->name);
99 if (! -d
$directory) {
100 File
::Path
::make_path
($directory) or
101 die "Could not create directory $directory: $!";
108 return File
::Spec
->catfile($self->packagedir, 'repository');
113 return File
::Spec
->catfile($self->packagedir, 'mock');
118 return File
::Spec
->catfile($self->packagedir, 'RPMS');
121 sub _build_requiresstore
{
123 return File
::Spec
->catfile($self->packagedir, 'buildrequires.store');
126 sub _build_runrequiresstore
{
128 return File
::Spec
->catfile($self->packagedir, 'runrequires.store');
131 sub _build_providesstore
{
133 return File
::Spec
->catfile($self->packagedir, 'provides.store');
136 sub _build_taskstore
{
138 return File
::Spec
->catfile($self->packagedir, 'task.store');
143 if ($self->dist eq 'rawhide') {
151 # Clones package repository and switch to proper branch if not yet done.
152 # Return true on success.
155 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
157 if ($lock->is_done) { return 1; }
159 # XXX: fedpkg creates subdirectory named like package. The package name
160 # could clash with our file structure. Thus we need to clone into secure
161 # directory and move repository content to fixed name $self->repodir after
164 if (-d
$self->repodir) { File
::Path
::remove_tree
($self->repodir); }
165 my $tempdir = File
::Spec
->catfile($self->packagedir, 'tmp');
166 my $temprepodir = File
::Spec
->catfile($tempdir, $self->name);
167 if (-d
$tempdir) { File
::Path
::remove_tree
($tempdir); }
168 if (!File
::Path
::make_path
($tempdir)) {
169 $lock->log("Could not create directory `" . $tempdir . "': $!\n");
170 return $lock->mark_failed;
173 if (!$lock->do($tempdir, 'fedpkg', 'clone', $self->name)) {
174 $lock->log("Could not clone `" . $self->name . "' repository.\n");
175 return $lock->mark_failed;
178 if (!rename($temprepodir, $self->repodir)) {
179 $lock->log("Could not move `" . $temprepodir . "' content to to `" .
180 $self->repodir . "'.\n");
181 return $lock->mark_failed;
183 File
::Path
::remove_tree
($tempdir);
185 if (!$lock->do($self->repodir, 'fedpkg', 'switch-branch', $self->branch)) {
186 $lock->log("Could not switch `" . $self->name .
187 "' repository to branch `" . $self->branch . "'.\n");
188 return $lock->mark_failed;
191 return $lock->mark_done;
194 # Builds SRPM locally. Return true on success.
195 # If first argument is true, recreate SRPM forcefully.
198 my ($self, $force) = @_;
199 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
201 if ($force) { $lock->remove_lock; }
202 if ($lock->is_done) { return 1; }
204 if (!$lock->do($self->repodir, 'fedpkg', 'srpm')) {
205 $lock->log("Could not build SRPM for `" . $self->name .
206 "' package locally.\n");
207 return $lock->mark_failed;
210 return $lock->mark_done;
213 # Get current package NEVRA from sources in repository.
214 # First argument is state lock where process of getting NEVRA including
215 # potential failure is logged.
216 # XXX: The state is not marked as failed in case of error,
217 # Return NEVRA string or undef in case of error.
218 sub get_nevra_from_git
{
219 my ($self, $lock) = @_;
222 if (!$lock->dooutput($self->repodir, \
$nevra, 'fedpkg', 'verrel') ||
224 $lock->log("Could not get NEVRA from `" . $self->name .
225 "' git repository package.\n");
229 # Consider last line only becuase of bug in fedpkg
230 # <https://bugzilla.redhat.com/show_bug.cgi?id=721389>.
231 my @lines = (split qr{$/}, $nevra);
237 # Get current package SRPM name.
238 # If the SRPM file does not exist, it will be re-created.
239 # First argument is state lock where process of building SRPM including
240 # potential failure is logged.
241 # XXX: The state is not marked as failed in case of error,
242 # Return SRPM file name string or undef in case of error.
244 my ($self, $lock) = @_;
246 my $nevra = $self->get_nevra_from_git($lock);
247 if (! defined $nevra) {
251 my $srpmname = File
::Spec
->catfile($self->repodir, $nevra . '.src.rpm');
252 if (! -f
$srpmname ) {
253 $lock->log("SRPM package `" . $srpmname . "' is missing, " .
254 "trying to create SRPM again...\n");
255 if (!$self->srpm(1) || ! -f
$srpmname) {
256 $lock->log("`Could not recreate SRPM package '" . $srpmname .
264 # Create a directory. If it exists, it will remove it before.
265 # First argument is the directory, second argument is lock to log errors into.
266 # Return true, false in case of error.
267 # XXX: This is not a method
268 sub replace_directory
{
269 my ($lock, $directory) = @_;
270 if (-d
$directory) { File
::Path
::remove_tree
($directory); }
271 if (!File
::Path
::make_path
($directory)) {
272 $lock->log("Could not create directory `" . $directory . "': $!\n");
278 # Copy files into existing directory.
279 # First argument lock for logggin,
280 # second argument is destinatinon directory,
281 # The last is list of files to be copied.
282 # Return true in sucesss, false in case of error.
283 # XXX: This is not a method
284 sub copy_files_into_directory
{
285 my ($lock, $directory, @files) = @_;
286 for my $file (@files) {
288 if (!copy
($file, $directory)) {
289 $lock->log("Could not copy `". $file . "' into `". $directory .
293 $lock->log("`" . $file . "' copied into `" . $directory . "'\n");
298 # Destile BuildRequires from local SRPM and serialize them into file.
299 # Return true on success.
301 # FIXME: does not work after cleaning clone or doing update.
302 sub storebuildrequires
{
304 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
305 state => 'buildrequiresstore');
306 if ($lock->is_done) { return 1; }
308 my $nevra = $self->get_nevra_from_git($lock);
309 if (! defined $nevra) {
310 return $lock->mark_failed;
313 my $srpmname = File
::Spec
->catfile($self->repodir, $nevra . '.src.rpm');
314 if (! -f
$srpmname ) {
315 $lock->log("SRPM package `" . $srpmname . "' is missing, " .
316 "trying to create SRPM again...\n");
317 if (!$self->srpm(1) || ! -f
$srpmname) {
318 $lock->log("`Could not recreate SRPM package '" . $srpmname .
320 return $lock->mark_failed;
324 my $rpm = Fedora
::Rebuild
::RPM
->new(name
=> $srpmname);
325 my ($requires, $envra) = $rpm->requires;
326 if (! defined $requires) {
327 $lock->log("Could not get requires of SRPM `" . $srpmname . "': ". $@
329 return $lock->mark_failed;
332 if (! $lock->nstorereference($requires, $self->requiresstore)) {
333 $lock->log("Could not store requires of SRPM `". $srpmname .
334 "' into `" . $self->requiresstore . "' file: $@\n");
335 return $lock->mark_failed;
338 $lock->log(Data
::Dumper
::Dumper
($requires) . "\n");
339 return $lock->mark_done;
342 # Destile BuildRequires from local SRPM. Return true on success.
343 # Needs `buildrequiresstore'.
346 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
347 state => 'buildrequires');
348 if ($lock->is_done) { return 1; }
350 my $requires = $lock->retrievereference($self->requiresstore);
352 $lock->log("Could not load requires of `". $self->name .
353 "' package from `" . $self->requiresstore . "' file: $@\n");
354 return $lock->mark_failed;
356 $self->requires(shared_clone
($requires));
358 $lock->log(Data
::Dumper
::Dumper
($self->requires) . "\n");
359 return $lock->mark_done;
362 # Record verdict from dependency solver whether the package is rebuildable.
363 # This step is always redone.
364 sub log_is_rebuildable
{
365 my ($self, $is_rebuildable, $message) = @_;
366 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
367 state => 'is_rebuildable');
370 $lock->log("Solver result for possibility of rebuilding SRPM for `" .
371 $self->name . "': $message\n");
372 if (! $is_rebuildable) {
373 $lock->log("According dependency solver, this package is not " .
374 "rebuildable now.\n");
375 return $lock->mark_failed;
378 $lock->log("According dependency solver, this package is " .
379 "rebuildable now.\n");
380 return $lock->mark_done;
383 # Get binary RPM packages for the source package.
384 # If first argument is:
385 # 'koji' download them from Koji,
386 # 'local' from local build,
387 # 'mock' from mock result directory.
388 # Requires `clone'. Sould be called after `build'.
389 # Return true on success.
391 my ($self, $mode) = @_;
392 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
394 if ($lock->is_done) { return 1; }
396 if (!replace_directory
($lock, $self->rpmdir)) {
397 return $lock->mark_failed;
400 # TODO: Get current architecture by rpmGetArchInfo() from librpm
401 my @archs = qw(x86_64 noarch);
402 if ($mode eq 'koji') {
403 $lock->log("Getting binary RPM packages from Koji:\n");
405 my $nevra = $self->get_nevra_from_git($lock);
406 if (! defined $nevra) {
407 return $lock->mark_failed;
410 # TODO: Get all archs, remove SRPM
411 if (!$lock->do($self->rpmdir, 'koji', 'download-build',
412 (map {'--arch=' . $_ } @archs), $nevra)) {
413 $lock->log("Could get binary RPM packages for `" . $nevra . "'\n");
414 return $lock->mark_failed;
416 } elsif ($mode eq 'local') {
417 $lock->log("Getting binary RPM packages from local build:\n");
419 my @rpms = map { glob(File
::Spec
->catfile($self->repodir, $_,
422 $lock->log("No binary RPM packages found under `" .
423 $self->repodir . "'\n");
424 return $lock->mark_failed;
427 if (!copy_files_into_directory
($lock, $self->rpmdir, @rpms)) {
428 return $lock->mark_failed;
430 } elsif ($mode eq 'mock') {
431 $lock->log("Getting binary RPM packages from mock build:\n");
433 my @rpms = map { glob(File
::Spec
->catfile($self->mockdir,
434 ('*.' . $_ . '.rpm'))) } @archs;
436 $lock->log("No binary RPM packages found under `" .
437 $self->mockdir . "'\n");
438 return $lock->mark_failed;
441 if (!copy_files_into_directory
($lock, $self->rpmdir, @rpms)) {
442 return $lock->mark_failed;
445 $lock->log("Could get binary RPM packages for `" . $self->name .
446 "' source package because of unknown building mode `" . $mode .
448 return $lock->mark_failed;
451 return $lock->mark_done;
454 # Return list of binary RPM files relative to current working directory.
455 # XXX: Should be called after colleting the files from build process by
457 sub listbinaryrpmfiles
{
459 return (glob(File
::Spec
->catfile($self->rpmdir, '*.rpm')));
462 # Distill Requires from rebuilt binary packages and serialize them into file.
463 # Return true on success.
465 sub storebinaryrequires
{
467 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
468 state => 'runrequiresstore');
469 if ($lock->is_done) { return 1; }
471 my @rpms = glob(File
::Spec
->catfile($self->rpmdir, '*.rpm'));
473 $lock->log("No binary RPM packages found in `" . $self->rpmdir
475 return $lock->mark_failed;
478 my $allrequires = {};
479 for my $rpmname (@rpms) {
480 my $rpm = Fedora
::Rebuild
::RPM
->new(name
=> $rpmname);
482 my ($requires, $envr) = $rpm->requires;
484 if (! defined $requires || ! defined $envr) {
485 $lock->log("Could not get run-time requires of RPM `" . $rpmname .
487 return $lock->mark_failed;
489 $$allrequires{$envr} = $requires;
492 if (! $lock->nstorereference($allrequires, $self->runrequiresstore)) {
493 $lock->log("Could not store run-time requires of RPM `". $self->name .
494 "' into `" . $self->runrequiresstore . "' file: $@\n");
495 return $lock->mark_failed;
498 $lock->log(Data
::Dumper
::Dumper
($allrequires));
499 return $lock->mark_done;
502 # Distill Provides from rebuilt binary packages and serialize them into file.
503 # Return true on success.
505 sub storebinaryprovides
{
507 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
508 state => 'providesstore');
509 if ($lock->is_done) { return 1; }
511 my @rpms = glob(File
::Spec
->catfile($self->rpmdir, '*.rpm'));
513 $lock->log("No binary RPM packages found in `" . $self->rpmdir
515 return $lock->mark_failed;
518 my $allprovides = {};
519 for my $rpmname (@rpms) {
520 my $rpm = Fedora
::Rebuild
::RPM
->new(name
=> $rpmname);
522 my ($provides, $envr) = $rpm->provides;
524 if (! defined $provides || !defined $envr) {
525 $lock->log("Could not get provides of RPM `" . $rpmname . "': " .
527 return $lock->mark_failed;
529 $$allprovides{$envr} = $provides;
532 if (! $lock->nstorereference($allprovides, $self->providesstore)) {
533 $lock->log("Could not store provides of RPM `". $self->name .
534 "' into `" . $self->providesstore . "' file: $@\n");
535 return $lock->mark_failed;
538 $lock->log(Data
::Dumper
::Dumper
($allprovides));
539 return $lock->mark_done;
542 # Load run-time requires of already rebuilt binary packages from file.
543 # Return true on success.
544 # Needs `storebinaryrequires'.
545 sub loadbinaryrequires
{
547 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
548 state => 'runrequires');
549 if ($lock->is_done) { return 1; }
551 my $runrequires = $lock->retrievereference($self->runrequiresstore);
552 if (! $runrequires) {
553 $lock->log("Could not load run-time requires of `". $self->name .
554 "' package from `" . $self->runrequiresstore . "' file: $@\n");
555 return $lock->mark_failed;
557 $self->runrequires(shared_clone
($runrequires));
559 $lock->log(Data
::Dumper
::Dumper
($self->runrequires));
560 return $lock->mark_done;
563 # Load provides of already rebuilt binary packages from file.
564 # Return true on success.
565 # Needs `storebinaryprovides'.
566 sub loadbinaryprovides
{
568 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
569 state => 'provides');
570 if ($lock->is_done) { return 1; }
572 my $provides = $lock->retrievereference($self->providesstore);
574 $lock->log("Could not load provides of `". $self->name .
575 "' package from `" . $self->providesstore . "' file: $@\n");
576 return $lock->mark_failed;
578 $self->provides(shared_clone
($provides));
580 $lock->log(Data
::Dumper
::Dumper
($self->provides));
581 return $lock->mark_done;
584 # Increase package revision if not yet done. Commit change if first argument
586 # Return true on success.
589 my ($self, $mode) = @_;
590 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
592 if ($lock->is_done) { return 1; }
594 # Reset git repository
595 if (!$lock->do($self->repodir, 'git', 'reset', '--hard',
596 'origin/' . $self->branch)) {
597 $lock->log("Could not reset git repository in `" . $self->repodir .
599 return $lock->mark_failed;
602 # Pull git repository
603 if (!$lock->do($self->repodir, 'git', 'pull')) {
604 $lock->log("Could not pull git repository in `" . $self->repodir .
606 return $lock->mark_failed;
609 # Increase revision number
610 my $specfile = File
::Spec
->catfile($self->repodir, $self->name . '.spec');
611 if (!$lock->do(undef, 'rpmdev-bumpspec', '-c', $self->message, $specfile)) {
612 $lock->log("Could not increase revison number in `" . $specfile .
614 return $lock->mark_failed;
618 if (!$lock->do($self->repodir, 'git', 'commit', '-a',
619 '-m', $self->message)) {
620 $lock->log("Could not commit changes into git repository `" .
621 $self->repodir . "'.\n");
622 return $lock->mark_failed;
625 if ($mode eq 'koji') {
627 if (!$lock->do($self->repodir, 'git', 'push')) {
628 $lock->log("Could not push changes from repository `" .
629 $self->repodir . "' to server.\n");
630 return $lock->mark_failed;
633 $lock->log("Not pushing changes because of local build mode.\n");
636 return $lock->mark_done;
640 # Submit package for building into Koji and store task ID.
641 # This is pointless in local build mode.
642 # Requires `clone'. Sould be called after `update'.
643 # Return true on success.
646 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
647 state => 'submitbuild');
648 if ($lock->is_done) { return 1; }
650 # Get NEVRA of intended build
651 my $nevra = $self->get_nevra_from_git($lock);
652 if (! defined $nevra) {
653 return $lock->mark_failed;
656 # Check the build is not already in Koji (e.g. by concurrent packager
657 # or after this program restart) but do not conclude anything.
659 if (!$lock->dooutput($self->repodir, \
$buildinfo, 'koji', 'buildinfo',
661 $lock->log("Could not ask Koji for `" . $nevra . "' status " .
662 "before submitting new build.\n");
663 return $lock->mark_failed;
665 if ($buildinfo =~ /No such build/m) {
666 $lock->log("Package not yet submitted for building as expected.\n");
668 # Get task ID of already building package
669 if ($buildinfo =~ /Task:\s*(\d+)/m) {
670 # TODO: We could compare task target and consider as submitted if
671 # equaled to intended target.
673 $lock->log("Package `$nevra' already submitted as task " .
674 "`$task_id'. Previous build failed or somebody builds the " .
675 "package concurrently.\n");
677 $lock->log("Package `$nevra' already in Koji, but task ID " .
678 "could not been determined.\n");
680 $lock->log("Re-submitting the package.\n")
685 if (!$lock->dooutput($self->repodir, \
$task_id, 'fedpkg', 'build',
686 '--nowait', '--target', $self->target)) {
687 $lock->log("Could not submit `" . $nevra . "' into Koji.\n");
688 return $lock->mark_failed;
690 if (not $task_id =~ /Created task:\s*(\d+)/) {
691 $lock->log("Could not parse Koji task ID for `$nevra' build\n");
692 return $lock->mark_failed;
697 if (! $lock->nstorereference(\
$task_id, $self->taskstore)) {
698 $lock->log("Could not store task ID `" . $task_id . "' of `" . $nevra .
699 "' package into `" . $self->taskstore . "' file: $@\n");
700 return $lock->mark_failed;
702 $lock->log("Task ID `" . $task_id . "' stored into `" .
703 $self->taskstore . "' file sucessfully.\n");
706 return $lock->mark_done;
710 # If first argument is:
711 # "koji" wait for package build in Koji,
712 # "local" build locally using fedpkg.
713 # "mock" build locally using mock.
714 # Second argument is reference to array of repository URLs to use as package
715 # base when building the package.
716 # Requires `clone'. Sould be called after `update' or `submitbuild'.
717 # Return true on success.
719 my ($self, $mode, $repositories) = @_;
720 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
722 if ($lock->is_done) { return 1; }
724 my $nevra = $self->get_nevra_from_git($lock);
725 if (! defined $nevra) {
726 return $lock->mark_failed;
729 if ($mode eq 'local') {
730 if (!$lock->do($self->repodir, 'fedpkg', 'local')) {
731 $lock->log("Could not build `" . $nevra . "' locally.\n");
732 return $lock->mark_failed;
734 } elsif ($mode eq 'koji') {
735 # Retrieve task ID of submitted build
736 my $task_id = $lock->retrievereference($self->taskstore);
738 $lock->log("Could not load task ID for `". $nevra .
739 "' build from `" . $self->taskstore . "' file: $@\n");
740 return $lock->mark_failed;
742 $task_id = $$task_id;
744 # Wait for build task result
745 # TODO: How to recognize the process died for other reason
746 # than build failure?
747 if (!$lock->do($self->repodir, 'koji', 'watch-task', $task_id)) {
748 $lock->log("Could not get status of Koji task `" . $task_id .
749 "' for `$nevra' build, or the task failed.\n");
750 return $lock->mark_failed;
752 } elsif ($mode eq 'mock') {
753 my $srpm_name = $self->get_srpm_name($lock);
754 if (! defined $srpm_name) {
755 return $lock->mark_failed;
757 if (!replace_directory
($lock, $self->mockdir)) {
758 return $lock->mark_failed;
760 my ($mock_config_dir, $mock_config_root);
762 # FIXME: Parametrize architecture
763 ($mock_config_dir, $mock_config_root) =
764 Fedora
::Rebuild
::Mock
->new(
765 architecture
=> 'x86_64', repositories
=> $repositories
766 )->make_configuration;
769 $lock->log("Could not configure mock: $@\n");
770 File
::Path
::remove_tree
($mock_config_dir);
771 return $lock->mark_failed;
773 if (!$lock->do(undef, 'mock', '--resultdir', $self->mockdir,
774 '--configdir', $mock_config_dir, '--root', $mock_config_root,
775 '--rebuild', $srpm_name)) {
776 $lock->log("Could not build `" . $nevra . "' in mock.\n");
777 File
::Path
::remove_tree
($mock_config_dir);
778 return $lock->mark_failed;
780 File
::Path
::remove_tree
($mock_config_dir);
782 $lock->log("Could not build `" . $nevra .
783 "' because of unknown building mode `" . $mode . "'.\n");
784 return $lock->mark_failed;
787 return $lock->mark_done;
791 # Waits for build root rotation. Just built package will be available for
792 # other packages at build time after returning from this fuction.
793 # If first argument is "koji", it will wait for the Koji rotation.
794 # If first argument is "mock", it will create yum repository in directory with
796 # If first argument is "local", this function is void,
797 # Requires `update'. Sould be called after `build'.
798 # Return true on success.
799 sub dowaitforbuildroot
{
800 my ($self, $mode) = @_;
801 my $lock = Fedora
::Rebuild
::Package
::StateLock
->new(package => $self,
803 if ($lock->is_done) { return 1; }
805 my $nevra = $self->get_nevra_from_git($lock);
806 if (! defined $nevra) {
807 return $lock->mark_failed;
810 if ($mode eq 'koji') {
811 if (!$lock->do($self->repodir, 'koji', 'wait-repo',
812 '--build=' . $nevra, '--target', $self->target)) {
813 $lock->log("Koji does not contain `" . $nevra .
814 "' package in build root for `" . $self->target .
815 "' build target yet.\n");
816 return $lock->mark_failed;
818 } elsif ($mode eq 'mock') {
819 $lock->log("`" . $nevra .
820 "' built in mock, creating yum repository...\n");
821 if (!$lock->do($self->rpmdir, 'createrepo', '.')) {
822 $lock->log("Could not create yum repository for `" . $nevra .
824 return $lock->mark_failed;
826 $lock->log("`" . $nevra .
827 "' yum repository created successfully.\n");
829 $lock->log("`" . $nevra .
830 "' built locally, not waiting on Koji rotation.\n");
833 return $lock->mark_done;
836 # Set hash of build-time dependencies (requires attribute).
837 # Return undef in case of failure.
838 sub get_buildrequires
{
841 print "Getting BuildRequires for `" . $self->name . "'...\n";
843 # Procede all steps, each must be re-doable
845 $ok = $self->srpm if $ok;
846 $ok = $self->storebuildrequires if $ok;
847 $ok = $self->buildrequires if $ok;
852 print "BuildRequires for `" . $self->name .
853 "' package distilled successfully.\n";
856 print "Could not get BuildRequires for `" . $self->name .
862 # Set hash of run-time requires (Requires attribute).
863 # Return true on success, undef in case of failure.
864 # XXX: Requires `runrequiresstore'
865 sub get_binaryrequires
{
868 print "Getting run-time requires for `" . $self->name . "'...\n";
870 $ok = $self->storebinaryrequires;
871 $ok = $self->loadbinaryrequires if $ok;
874 print "Run-time requires for `" . $self->name .
875 "' package distilled successfully.\n";
878 print "Could not get run-time requires for `" . $self->name .
884 # Set hash of run-time provides (provides attribute).
885 # Return true on success, undef in case of failure.
886 # XXX: Requires `providesstore'
887 sub get_binaryprovides
{
890 print "Getting binary provides for `" . $self->name . "'...\n";
892 $ok = $self->storebinaryprovides;
893 $ok = $self->loadbinaryprovides if $ok;
896 print "Provides for `" . $self->name .
897 "' package distilled successfully.\n";
900 print "Could not get Provides for `" . $self->name . "' package.\n";
905 # Set hash of run-time requires (Requires attribute) and provides
906 # (provides attribute). Common wrapper for getbinaryrequires() and
907 # getbinaryprovides().
908 # Return true on success, undef in case of failure.
909 # XXX: Requires `runrequiresstore' and `providesstore'
910 sub get_binarydependencies
{
913 print "Getting binary dependencies for `" . $self->name . "'...\n";
915 $ok = $self->get_binaryrequires;
916 $ok = $self->get_binaryprovides if $ok;
919 print "Binary dependencies for `" . $self->name .
920 "' package distilled successfully.\n";
923 print "Could not get binary dependencies for `" . $self->name .
929 # Rebuild a package without waiting for propagation to next build root.
930 # First argument defines build mode:
931 # "koji" publish commit and build in Koji,
932 # "local" build locally without pushing commits to server,
933 # "mock" build in mock without pushing commits to server.
934 # Second argument is reference to array of repository URLs to use as package
935 # base when building the package.
937 my ($self, $mode, $repositories) = @_;
939 print "Rebuilding `" . $self->name . "'...\n";
941 # Proceed all steps, each must be re-doable
943 $ok = $self->update($mode) if $ok;
944 $ok = $self->submitbuild if ($ok and $mode eq 'koji');
945 $ok = $self->build($mode, $repositories) if $ok;
946 $ok = $self->binaryrpm($mode) if $ok;
947 $ok = $self->get_binaryprovides if $ok;
948 $ok = $self->get_binaryrequires if $ok;
951 print "`" . $self->name . "' rebuild finished successfully.\n";
953 print "`" . $self->name . "' rebuild failed.\n";
958 # Wait for the package propagated into new build root.
959 # If first argument is "koji", waits for Koji build root rotation,
960 # Otherwise waits locally (no-op).
961 # XXX: Requires `update', should be called after rebuilding package.
962 sub waitforbuildroot
{
963 my ($self, $mode) = @_;
965 print "Waiting for `" . $self->name . "' to get to build root...\n";
967 $ok = $self->dowaitforbuildroot($mode);
970 print "`" . $self->name . "' propagated successfully.\n";
972 print "`" . $self->name . "' propagation failed.\n";