aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/package25
-rw-r--r--bpkg/pkg-build.cxx25
-rwxr-xr-xtests/test.sh22
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
#