aboutsummaryrefslogtreecommitdiff
path: root/bpkg/package.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-03-14 00:54:05 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-03-16 13:45:18 +0300
commitbc24eec7208187e171fd61ced7130fd8e2828257 (patch)
tree23e9076f0e06282001758ef5939db872eba214ff /bpkg/package.cxx
parent5f75406495f06b75eb10b3456a1ca550f4e55b61 (diff)
Add support for version iteration
Diffstat (limited to 'bpkg/package.cxx')
-rw-r--r--bpkg/package.cxx77
1 files changed, 76 insertions, 1 deletions
diff --git a/bpkg/package.cxx b/bpkg/package.cxx
index 2e5bffe..966be72 100644
--- a/bpkg/package.cxx
+++ b/bpkg/package.cxx
@@ -8,12 +8,14 @@
#include <algorithm> // find_if()
#include <bpkg/database.hxx>
+#include <bpkg/checksum.hxx>
+#include <bpkg/manifest-utility.hxx>
using namespace std;
namespace bpkg
{
- const version wildcard_version (0, "0", nullopt, 0);
+ const version wildcard_version (0, "0", nullopt, 0, 0);
// available_package_id
//
@@ -158,6 +160,79 @@ namespace bpkg
return os;
}
+ optional<version>
+ package_iteration (const common_options& o,
+ const dir_path& c,
+ transaction& t,
+ const dir_path& d,
+ const string& n,
+ const version& v,
+ bool check_external)
+ {
+ tracer trace ("package_iteration");
+
+ database& db (t.database ());
+ tracer_guard tg (db, trace);
+
+ if (check_external)
+ {
+ using query = query<package_repository>;
+
+ query q (
+ query::package::id.name == n &&
+ compare_version_eq (query::package::id.version, v, true, false));
+
+ for (const auto& pr: db.query<package_repository> (q))
+ {
+ const shared_ptr<repository>& r (pr.repository);
+
+ if (r->location.directory_based ())
+ fail << "external package " << n << '/' << v
+ << " is already available from "
+ << r->location.canonical_name ();
+ }
+ }
+
+ shared_ptr<selected_package> p (db.find<selected_package> (n));
+
+ if (p == nullptr || !p->src_root ||
+ compare_version_ne (v, p->version, true, false))
+ return nullopt;
+
+ string mc (sha256 (o, d / manifest_file));
+
+ assert (p->manifest_checksum);
+
+ bool changed (mc != *p->manifest_checksum);
+
+ // If the manifest didn't changed but the selected package points to an
+ // external source directory, then we also check if the directory have
+ // moved.
+ //
+ if (!changed && p->external ())
+ {
+ dir_path src_root (p->src_root->absolute ()
+ ? *p->src_root
+ : c / *p->src_root);
+
+ // We need to complete and normalize the source directory as it may
+ // generally be completed against the configuration directory (unlikely
+ // but possible), that can be relative and/or not normalized.
+ //
+ src_root.complete ().normalize ();
+
+ changed = src_root != dir_path (d).complete ().normalize ();
+ }
+
+ return !changed
+ ? p->version
+ : version (v.epoch,
+ v.upstream,
+ v.release,
+ v.revision,
+ p->version.iteration + 1);
+ }
+
// state
//
string