diff options
-rw-r--r-- | bpkg/package | 25 | ||||
-rw-r--r-- | bpkg/pkg-build.cxx | 25 | ||||
-rwxr-xr-x | tests/test.sh | 22 |
3 files changed, 62 insertions, 10 deletions
diff --git a/bpkg/package b/bpkg/package index f70a198..6f1d955 100644 --- a/bpkg/package +++ b/bpkg/package @@ -384,6 +384,31 @@ namespace bpkg return system_version_ ? &*system_version_ : nullptr; } + // As above but also return an indication if the version information is + // authoritative. + // + pair<const version_type*, bool> + system_version_authoritative () const + { + const system_package* sp (system_repository.find (id.name)); + + if (!system_version_) + { + if (sp != nullptr) + { + // Only cache if it is authoritative. + // + if (sp->authoritative) + system_version_ = sp->version; + else + return make_pair (&sp->version, false); + } + } + + return make_pair (system_version_ ? &*system_version_ : nullptr, + sp != nullptr ? sp->authoritative : false); + } + // Database mapping. // #pragma db member(id) id column("") diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index d88e312..a022130 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -536,8 +536,15 @@ namespace bpkg // If all that's available is a stub then we need to make sure the // package is present in the system repository and it's version - // satisfies the constraint. + // satisfies the constraint. If a source package is available but there + // is an optional system package specified on the command line and it's + // version satisfies the constraint then the system package should be + // preferred. To recognize such a case we just need to check if the + // authoritative system version is set and it satisfies the constraint. + // If the corresponding system package is non-optional it will be + // preferred anyway. // + bool system (false); if (dap->stub ()) { if (dap->system_version () == nullptr) @@ -553,6 +560,17 @@ namespace bpkg info << "sys:" << d.name << "/" << *dap->system_version () << " does not satisfy the constrains"; } + + system = true; + } + else + { + auto p (dap->system_version_authoritative ()); + + if (p.first != nullptr && + p.second && // Authoritative. + satisfies (*p.first, d.constraint)) + system = true; } // Next see if this package is already selected. If we already @@ -569,7 +587,10 @@ namespace bpkg info << "use 'pkg-purge --force' to remove"; if (satisfies (dsp->version, d.constraint)) + { rp = make_available (options, cd, db, dsp); + system = dsp->system (); + } else // Remember that we may be forcing up/downgrade; we will deal // with it below. @@ -584,7 +605,7 @@ namespace bpkg nullopt, // Hold package. nullopt, // Hold version. {}, // Constraints. - dap->stub (), // System. + system, // System. {name}, // Required by. false}; // Reconfigure. diff --git a/tests/test.sh b/tests/test.sh index f6cd89a..85fde8e 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -1823,13 +1823,12 @@ stat libbaz 'configured 2; available sys:?' test pkg-drop -y foo libbar build foo ?sys:libbar<<EOF -build libbaz/2 (required by libbar) -build libbar/2 (required by foo) +configure sys:libbar/* (required by foo) build foo/2 EOF stat foo 'configured 2 hold_package; available sys:?' -stat libbar 'configured 2; available sys:?' -stat libbaz 'configured 2; available sys:?' +stat libbar 'configured,system *; available 2 1 sys:?' +stat libbaz 'available 2 sys:?' # Drop all, configure libbar/1, then fail to build foo and foo ?sys:libbar/2, # but succeed to build foo sys:libbar/2. @@ -1841,18 +1840,25 @@ build libbaz/2 (required by libbar) build libbar/1 EOF stat libbar 'configured 1 hold_package hold_version; available 2 sys:?' +stat libbaz 'configured 2; available sys:?' fail build foo -# libbar/2 is picked up (not optional sys:libbar/2) as a foo dependent and so -# fail to upgrade held version 1. -# -fail build foo ?sys:libbar/2 +build foo ?sys:libbar/2<<EOF +reconfigure sys:libbar/2 (required by foo) +build foo/2 +EOF +stat foo 'configured 2 hold_package; available sys:?' +stat libbar 'configured,system 2 hold_package hold_version; available sys:?' +stat libbaz 'available 2 sys:?' build foo sys:libbar/2 <<EOF reconfigure sys:libbar/2 build foo/2 EOF +stat foo 'configured 2 hold_package; available sys:?' +stat libbar 'configured,system 2 hold_package hold_version; available sys:?' +stat libbaz 'available 2 sys:?' # Fetch system/t2 repository: foo/2 (->libbar>=2), libbar/0+1 # |