aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/auth.cxx137
-rw-r--r--bpkg/buildfile11
-rwxr-xr-xbpkg/odb.sh11
-rw-r--r--bpkg/pkg-build-collect.cxx124
-rw-r--r--bpkg/rep-fetch.cxx4
-rw-r--r--bpkg/rep-mask.cxx11
-rw-r--r--bpkg/rep-remove.cxx55
-rw-r--r--bpkg/rep-remove.hxx7
-rw-r--r--bpkg/version.hxx.in8
-rw-r--r--manifest3
-rw-r--r--repositories.manifest12
11 files changed, 225 insertions, 158 deletions
diff --git a/bpkg/auth.cxx b/bpkg/auth.cxx
index 663054d..191da0a 100644
--- a/bpkg/auth.cxx
+++ b/bpkg/auth.cxx
@@ -23,15 +23,15 @@ using namespace butl;
namespace bpkg
{
- static const string openssl_version ("version");
- static const string openssl_pkeyutl ("pkeyutl");
- static const string openssl_rsautl ("rsautl");
- static const string openssl_x509 ("x509");
-
- const char* openssl_commands[5] = {openssl_version.c_str (),
- openssl_pkeyutl.c_str (),
- openssl_rsautl.c_str (),
- openssl_x509.c_str (),
+ static const string openssl_version_cmd ("version");
+ static const string openssl_pkeyutl_cmd ("pkeyutl");
+ static const string openssl_rsautl_cmd ("rsautl");
+ static const string openssl_x509_cmd ("x509");
+
+ const char* openssl_commands[5] = {openssl_version_cmd.c_str (),
+ openssl_pkeyutl_cmd.c_str (),
+ openssl_rsautl_cmd.c_str (),
+ openssl_x509_cmd.c_str (),
nullptr};
// Print process command line.
@@ -43,9 +43,42 @@ namespace bpkg
print_process (args, n);
}
+ // Query the openssl information and return the openssl version. Cache the
+ // version on the first function call. Fail on the underlying process and IO
+ // error. Return the 0.0.0 version if unable to parse the openssl stdout.
+ //
+ static optional<semantic_version> openssl_ver;
+
+ static const semantic_version&
+ openssl_version (const common_options& co)
+ {
+ const path& openssl_path (co.openssl ()[openssl_version_cmd]);
+
+ if (!openssl_ver)
+ try
+ {
+ optional<openssl_info> oi (
+ openssl::info (print_command, 2, openssl_path));
+
+ openssl_ver = (oi && oi->name == "OpenSSL"
+ ? move (oi->version)
+ : semantic_version ());
+ }
+ catch (const process_error& e)
+ {
+ fail << "unable to execute " << openssl_path << ": " << e << endf;
+ }
+ catch (const io_error& e)
+ {
+ fail << "unable to read '" << openssl_path << "' output: " << e
+ << endf;
+ }
+
+ return *openssl_ver;
+ }
+
// Return true if the openssl version is greater or equal to 3.0.0 and so
- // pkeyutl needs to be used instead of rsautl. Cache the result on the first
- // function call.
+ // pkeyutl needs to be used instead of rsautl.
//
// Note that openssl 3.0.0 deprecates rsautl in favor of pkeyutl.
//
@@ -54,37 +87,28 @@ namespace bpkg
// (see the 'pkeyutl -verifyrecover error "input data too long to be a
// hash"' issue report for details).
//
- static optional<bool> use_pkeyutl;
-
- static bool
+ static inline bool
use_openssl_pkeyutl (const common_options& co)
{
- if (!use_pkeyutl)
- {
- const path& openssl_path (co.openssl ()[openssl_version]);
-
- try
- {
- optional<openssl_info> oi (
- openssl::info (print_command, 2, openssl_path));
-
- use_pkeyutl = oi &&
- oi->name == "OpenSSL" &&
- oi->version >= semantic_version {3, 0, 0};
- }
- catch (const process_error& e)
- {
- fail << "unable to execute " << openssl_path << ": " << e << endf;
- }
- catch (const io_error& e)
- {
- fail << "unable to read '" << openssl_path << "' output: " << e
- << endf;
- }
- }
+ return openssl_version (co) >= semantic_version {3, 0, 0};
+ }
- return *use_pkeyutl;
+ // Return true if some openssl commands (openssl x509 -fingerprint, etc) may
+ // issue the 'Reading certificate from stdin since no -in or -new option is
+ // given' warning. This is the case for the openssl version in the [3.2.0
+ // 3.3.0) range (see GH issue #353 for details).
+ //
+ // Note that there is no easy way to suppress this warning on Windows and
+ // thus we don't define this function there.
+ //
+#ifndef _WIN32
+ static inline bool
+ openssl_warn_stdin (const common_options& co)
+ {
+ const semantic_version& v (openssl_version (co));
+ return v >= semantic_version {3, 2, 0} && v < semantic_version {3, 3, 0};
}
+#endif
// Find the repository location prefix that ends with the version component.
// We consider all repositories under this location to be related.
@@ -190,15 +214,25 @@ namespace bpkg
dr << ": " << *e;
};
- const path& openssl_path (co.openssl ()[openssl_x509]);
- const strings& openssl_opts (co.openssl_option ()[openssl_x509]);
+ const path& openssl_path (co.openssl ()[openssl_x509_cmd]);
+ const strings& openssl_opts (co.openssl_option ()[openssl_x509_cmd]);
try
{
openssl os (print_command,
fdstream_mode::text, fdstream_mode::text, 2,
- openssl_path, openssl_x509,
- openssl_opts, "-sha256", "-noout", "-fingerprint");
+ openssl_path, openssl_x509_cmd,
+ openssl_opts,
+ "-sha256",
+ "-noout",
+ "-fingerprint"
+#ifndef _WIN32
+ ,
+ (openssl_warn_stdin (co)
+ ? cstrings ({"-in", "/dev/stdin"})
+ : cstrings ())
+#endif
+ );
os.out << pem;
os.out.close ();
@@ -288,8 +322,8 @@ namespace bpkg
dr << ": " << *e;
};
- const path& openssl_path (co.openssl ()[openssl_x509]);
- const strings& openssl_opts (co.openssl_option ()[openssl_x509]);
+ const path& openssl_path (co.openssl ()[openssl_x509_cmd]);
+ const strings& openssl_opts (co.openssl_option ()[openssl_x509_cmd]);
try
{
@@ -315,7 +349,7 @@ namespace bpkg
openssl os (
print_command,
fdstream_mode::text, fdstream_mode::text, 2,
- openssl_path, openssl_x509,
+ openssl_path, openssl_x509_cmd,
openssl_opts, "-noout", "-subject", "-dates", "-email",
// Previously we have used "RFC2253,sep_multiline" format to display
@@ -347,6 +381,13 @@ namespace bpkg
// sep_multiline - display field per line.
//
"-nameopt", "utf8,esc_ctrl,dump_nostr,dump_der,sname,sep_multiline"
+
+#ifndef _WIN32
+ ,
+ (openssl_warn_stdin (co)
+ ? cstrings ({"-in", "/dev/stdin"})
+ : cstrings ())
+#endif
);
// We unset failbit to provide the detailed error description (which
@@ -877,7 +918,7 @@ namespace bpkg
};
bool ku (use_openssl_pkeyutl (co));
- const string& cmd (ku ? openssl_pkeyutl : openssl_rsautl);
+ const string& cmd (ku ? openssl_pkeyutl_cmd : openssl_rsautl_cmd);
const path& openssl_path (co.openssl ()[cmd]);
const strings& openssl_opts (co.openssl_option ()[cmd]);
@@ -973,8 +1014,8 @@ namespace bpkg
};
const string& cmd (use_openssl_pkeyutl (co)
- ? openssl_pkeyutl
- : openssl_rsautl);
+ ? openssl_pkeyutl_cmd
+ : openssl_rsautl_cmd);
const path& openssl_path (co.openssl ()[cmd]);
const strings& openssl_opts (co.openssl_option ()[cmd]);
diff --git a/bpkg/buildfile b/bpkg/buildfile
index 0ba60dc..8836712 100644
--- a/bpkg/buildfile
+++ b/bpkg/buildfile
@@ -15,15 +15,12 @@ import libs = build2%lib{build2}
for m: bash bin c cc cli cxx in version
import libs += build2%lib{build2-$m}
+# @@ TMP we require libsqlite3 to be interface dependency of libbut-odb only
+# for the database migrations to schema versions 13 and 14.
+#
import libs += libbpkg%lib{bpkg}
import libs += libbutl%lib{butl}
-import libs += libodb%lib{odb}
-import libs += libodb-sqlite%lib{odb-sqlite}
-
-# @@ TMP Only required for the database migrations to schema versions 13 and
-# 14.
-#
-import libs += libsqlite3%lib{sqlite3}
+import libs += libbutl%lib{butl-odb}
options_topics = \
bpkg-options \
diff --git a/bpkg/odb.sh b/bpkg/odb.sh
index 75c6d2d..1387773 100755
--- a/bpkg/odb.sh
+++ b/bpkg/odb.sh
@@ -16,8 +16,9 @@ if test -d ../.bdep; then
sed -r -ne 's#^(@[^ ]+ )?([^ ]+)/ .*default.*$#\2#p')"
fi
- inc+=("-I$(echo "$cfg"/libodb-[1-9]*/)")
- inc+=("-I$(echo "$cfg"/libodb-sqlite-[1-9]*/)")
+ # Note: there is nothing generated in libbutl-odb.
+ #
+ inc+=("-I../../libbutl/libbutl-odb")
inc+=("-I$cfg/libbutl")
inc+=("-I../../libbutl")
@@ -30,11 +31,7 @@ sed -r -ne 's#^(@[^ ]+ )?([^ ]+)/ .*default.*$#\2#p')"
else
- inc+=("-I$HOME/work/odb/builds/default/libodb-sqlite-default")
- inc+=("-I$HOME/work/odb/libodb-sqlite")
-
- inc+=("-I$HOME/work/odb/builds/default/libodb-default")
- inc+=("-I$HOME/work/odb/libodb")
+ inc+=("-I../../libbutl/libbutl-odb")
inc+=(-I.. -I../../libbpkg -I../../libbutl)
diff --git a/bpkg/pkg-build-collect.cxx b/bpkg/pkg-build-collect.cxx
index 6f1195c..436d629 100644
--- a/bpkg/pkg-build-collect.cxx
+++ b/bpkg/pkg-build-collect.cxx
@@ -1490,78 +1490,87 @@ namespace bpkg
// applied. Ignore the replacement if its version doesn't satisfy the
// dependency constraints specified by the caller. Also ignore if this is
// a drop and the required-by package names of the specified build package
- // object have the "required by dependents" semantics
+ // object have the "required by dependents" semantics.
//
auto vi (replaced_vers.find (pk));
+ const version* replacement_version (nullptr);
- if (vi != replaced_vers.end () && !vi->second.replaced)
+ if (vi != replaced_vers.end ())
{
- l5 ([&]{trace << "apply version replacement for "
- << pkg.available_name_version_db ();});
-
replaced_version& v (vi->second);
if (v.available != nullptr)
+ replacement_version = (v.system
+ ? v.available->system_version (pk.db)
+ : &v.available->version);
+
+ if (!vi->second.replaced)
{
- const version& rv (v.system
- ? *v.available->system_version (pk.db)
- : v.available->version);
+ l5 ([&]{trace << "apply version replacement for "
+ << pkg.available_name_version_db ();});
- bool replace (true);
- for (const constraint_type& c: pkg.constraints)
+ if (v.available != nullptr)
{
- if (!satisfies (rv, c.value))
+ assert (replacement_version != nullptr);
+
+ const version& rv (*replacement_version);
+
+ bool replace (true);
+ for (const constraint_type& c: pkg.constraints)
{
- replace = false;
+ if (!satisfies (rv, c.value))
+ {
+ replace = false;
- l5 ([&]{trace << "replacement to " << rv << " is denied since "
- << c.dependent << " depends on (" << pk.name << ' '
- << c.value << ')';});
+ l5 ([&]{trace << "replacement to " << rv << " is denied since "
+ << c.dependent << " depends on (" << pk.name << ' '
+ << c.value << ')';});
+ }
}
- }
- if (replace)
- {
- v.replaced = true;
+ if (replace)
+ {
+ v.replaced = true;
- pkg.available = v.available;
- pkg.repository_fragment = v.repository_fragment;
- pkg.system = v.system;
+ pkg.available = v.available;
+ pkg.repository_fragment = v.repository_fragment;
+ pkg.system = v.system;
- l5 ([&]{trace << "replacement: "
- << pkg.available_name_version_db ();});
+ l5 ([&]{trace << "replacement: "
+ << pkg.available_name_version_db ();});
+ }
}
- }
- else
- {
- if (!pkg.required_by_dependents)
+ else
{
- v.replaced = true;
+ if (!pkg.required_by_dependents)
+ {
+ v.replaced = true;
- l5 ([&]{trace << "replacement: drop";});
+ l5 ([&]{trace << "replacement: drop";});
- // We shouldn't be replacing a package build with the drop if someone
- // depends on this package.
- //
- assert (pkg.selected != nullptr);
+ // We shouldn't be replacing a package build with the drop if someone
+ // depends on this package.
+ //
+ assert (pkg.selected != nullptr);
- collect_drop (options, pkg.db, pkg.selected, replaced_vers);
- return nullptr;
- }
- else
- {
- assert (!pkg.required_by.empty ());
+ collect_drop (options, pkg.db, pkg.selected, replaced_vers);
+ return nullptr;
+ }
+ else
+ {
+ assert (!pkg.required_by.empty ());
- l5 ([&]
- {
- diag_record dr (trace);
- dr << "replacement to drop is denied since " << pk
- << " is required by ";
- for (auto b (pkg.required_by.begin ()), i (b);
- i != pkg.required_by.end ();
- ++i)
- dr << (i != b ? ", " : "") << *i;
- });
+ l5 ([&]
+ {
+ diag_record dr (trace);
+ dr << "replacement to drop is denied since " << pk
+ << " is required by ";
+ for (auto b (pkg.required_by.begin ()), i (b);
+ i != pkg.required_by.end ();
+ ++i)
+ dr << (i != b ? ", " : "") << *i;
+ });
+ }
}
}
}
@@ -1629,19 +1638,28 @@ namespace bpkg
build_package* p2 (&pkg);
// Pick with the following preference order: user selection over
- // implicit one, source package over a system one, newer version over
- // an older one. So get the preferred into p1 and the other into p2.
+ // implicit one, source package over a system one, replacement version
+ // over a non-replacement one, newer version over an older one. So get
+ // the preferred into p1 and the other into p2.
//
{
+ const version& v1 (p1->available_version ());
+ const version& v2 (p2->available_version ());
+
int us (p1->user_selection () - p2->user_selection ());
int sf (p1->system - p2->system);
+ int rv (replacement_version != nullptr
+ ? (v1 == *replacement_version) - (v2 == *replacement_version)
+ : 0);
if (us < 0 ||
(us == 0 && sf > 0) ||
(us == 0 &&
sf == 0 &&
- p2->available_version () > p1->available_version ()))
+ (rv < 0 || (rv == 0 && v2 > v1))))
+ {
swap (p1, p2);
+ }
}
// If the versions differ, pick the satisfactory one and if both are
diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx
index d02a064..fe25b86 100644
--- a/bpkg/rep-fetch.cxx
+++ b/bpkg/rep-fetch.cxx
@@ -1552,6 +1552,10 @@ namespace bpkg
}
}
+#ifndef NDEBUG
+ rep_remove_verify (db, t);
+#endif
+
// Make sure that the external packages are available from a single
// directory-based repository.
//
diff --git a/bpkg/rep-mask.cxx b/bpkg/rep-mask.cxx
index d7f9c6a..e670005 100644
--- a/bpkg/rep-mask.cxx
+++ b/bpkg/rep-mask.cxx
@@ -6,6 +6,7 @@
#include <bpkg/package.hxx>
#include <bpkg/package-odb.hxx>
#include <bpkg/database.hxx>
+#include <bpkg/rep-remove.hxx> // rep_remove_verify()
#include <bpkg/diagnostics.hxx>
#include <bpkg/package-query.hxx> // repo_configs
#include <bpkg/manifest-utility.hxx> // repository_name()
@@ -273,6 +274,16 @@ namespace bpkg
for (database& db: repo_configs)
{
+ // While at it, verify that the repository information has stayed
+ // consistent after the potential repository removals.
+ //
+ // Note that rep_remove() doesn't remove the available packages in the
+ // mask mode and thus we don't verify them.
+ //
+#ifndef NDEBUG
+ rep_remove_verify (db, t, false /* verify_packages */);
+#endif
+
// Add the repository location canonical name to the database-specific
// unmasked repositories or repository fragments lists. Note that
// repository location is used only for tracing.
diff --git a/bpkg/rep-remove.cxx b/bpkg/rep-remove.cxx
index ad10f56..22702a5 100644
--- a/bpkg/rep-remove.cxx
+++ b/bpkg/rep-remove.cxx
@@ -178,12 +178,6 @@ namespace bpkg
for (const repository::fragment_type& fr: r->fragments)
rep_remove_fragment (db, t, fr.fragment.load (), mask);
- // If there are no repositories stayed in the database then no repository
- // fragments should stay either.
- //
- if (db.query_value<repository_count> () == 0)
- assert (db.query_value<repository_fragment_count> () == 0);
-
// Unless in the mask repositories mode, cleanup the repository state if
// present and there are no more repositories referring this state.
//
@@ -272,20 +266,6 @@ namespace bpkg
//
db.erase (rf);
- // If there are no repository fragments stayed in the database then no
- // repositories nor packages should stay either.
- //
- // Note that a repository is removed prior to the removal of fragments it
- // contains (see rep_remove()). Also note that the packages contained in a
- // repository fragment are removed, if this is the only containing
- // fragment, prior to the fragment removal (see above).
- //
- if (db.query_value<repository_fragment_count> () == 0)
- {
- assert (db.query_value<repository_count> () == 0);
- assert (mask || db.query_value<available_package_count> () == 0);
- }
-
// Remove dangling complements and prerequisites.
//
// Prior to removing a prerequisite/complement we need to make sure it
@@ -521,6 +501,10 @@ namespace bpkg
text << "removed " << r.object_id ();
}
+#ifndef NDEBUG
+ rep_remove_verify (db, t);
+#endif
+
// If the --all option is specified then no user-added repositories should
// remain.
//
@@ -538,4 +522,35 @@ namespace bpkg
return 0;
}
+
+ void
+ rep_remove_verify (database& db, transaction&, bool verify_packages)
+ {
+ size_t rn (db.query_value<repository_count> ());
+ size_t fn (db.query_value<repository_fragment_count> ());
+
+ // If there are no repositories stayed in the database then no repository
+ // fragments should stay either.
+ //
+ assert (rn != 0 || fn == 0);
+
+ // If there are no repository fragments stayed in the database then no
+ // repositories with fragments nor packages should stay either.
+ //
+ // Note that repositories may not have any fragments if they are not
+ // fetched yet or due to the refname exclusions in the repository URL
+ // fragments (see repository-types(1) for details).
+ //
+ if (fn == 0)
+ {
+ // If there are some repositories have stayed, then make sure that none
+ // of them have any fragments.
+ //
+ assert (rn == 0 ||
+ db.query_value<fragment_repository_count> ("repository!=''") == 0);
+
+ if (verify_packages)
+ assert (db.query_value<available_package_count> () == 0);
+ }
+ }
}
diff --git a/bpkg/rep-remove.hxx b/bpkg/rep-remove.hxx
index 0fc82e8..94a38c6 100644
--- a/bpkg/rep-remove.hxx
+++ b/bpkg/rep-remove.hxx
@@ -57,6 +57,13 @@ namespace bpkg
rep_remove_package_locations (database&,
transaction&,
const string& fragment_name);
+
+ // Verify that after all the repository/fragment removals the repository
+ // information is consistent in the database (if no repositories stayed then
+ // no fragments stayed either, etc).
+ //
+ void
+ rep_remove_verify (database&, transaction&, bool verify_packages = true);
}
#endif // BPKG_REP_REMOVE_HXX
diff --git a/bpkg/version.hxx.in b/bpkg/version.hxx.in
index 22da973..603a5f7 100644
--- a/bpkg/version.hxx.in
+++ b/bpkg/version.hxx.in
@@ -43,14 +43,6 @@ $libbutl.check(LIBBUTL_VERSION, LIBBUTL_SNAPSHOT)$
$libbpkg.check(LIBBPKG_VERSION, LIBBPKG_SNAPSHOT)$
-#include <odb/version.hxx>
-
-$libodb.check(LIBODB_VERSION, LIBODB_SNAPSHOT)$
-
-#include <odb/sqlite/version.hxx>
-
-$libodb_sqlite.check(LIBODB_SQLITE_VERSION, LIBODB_SQLITE_SNAPSHOT)$
-
// User agent.
//
#if defined(_WIN32)
diff --git a/manifest b/manifest
index e826689..07e97ff 100644
--- a/manifest
+++ b/manifest
@@ -18,9 +18,6 @@ depends: * build2 >= 0.16.0-
depends: * bpkg >= 0.16.0-
# @@ DEP Should probably become conditional dependency.
#requires: ? cli ; Only required if changing .cli files.
-depends: libodb [2.5.0-b.26.1 2.5.0-b.27)
-depends: libodb-sqlite [2.5.0-b.26.1 2.5.0-b.27)
-depends: libsqlite3 ^3.21.0 ; ATTACH in transaction
depends: libbutl [0.17.0-a.0.1 0.17.0-a.1)
depends: libbpkg [0.17.0-a.0.1 0.17.0-a.1)
depends: build2 [0.17.0-a.0.1 0.17.0-a.1)
diff --git a/repositories.manifest b/repositories.manifest
index 29cb1cf..5adbbe4 100644
--- a/repositories.manifest
+++ b/repositories.manifest
@@ -12,15 +12,3 @@ location: ../libbutl.git##HEAD
:
role: prerequisite
location: ../libbpkg.git##HEAD
-
-:
-role: prerequisite
-location: https://git.build2.org/packaging/sqlite/sqlite.git##HEAD
-
-:
-role: prerequisite
-location: https://git.codesynthesis.com/odb/libodb.git##HEAD
-
-:
-role: prerequisite
-location: https://git.codesynthesis.com/odb/libodb-sqlite.git##HEAD