diff options
Diffstat (limited to 'bpkg/manifest-utility.cxx')
-rw-r--r-- | bpkg/manifest-utility.cxx | 78 |
1 files changed, 55 insertions, 23 deletions
diff --git a/bpkg/manifest-utility.cxx b/bpkg/manifest-utility.cxx index 56da715..afcb1f7 100644 --- a/bpkg/manifest-utility.cxx +++ b/bpkg/manifest-utility.cxx @@ -24,7 +24,9 @@ namespace bpkg const path manifest_file ("manifest"); vector<package_info> - package_b_info (const common_options& o, const dir_paths& ds, bool ext_mods) + package_b_info (const common_options& o, + const dir_paths& ds, + b_info_flags fl) { path b (name_b (o)); @@ -33,7 +35,7 @@ namespace bpkg { b_info (r, ds, - ext_mods, + fl, verb, [] (const char* const args[], size_t n) { @@ -55,6 +57,8 @@ namespace bpkg if (r.size () < ds.size ()) dr << ds[r.size ()] << ' '; dr << "info: " << e << info << "produced by '" << b << "'; use --build to override" << endf; + + return vector<package_info> (); // Work around GCC 13.2.1 segfault. } } @@ -131,12 +135,16 @@ namespace bpkg if (s[n] == '\0') // No version (constraint) is specified? return nullopt; - const char* v (s + n); // Constraint or version including '/'. + const char* v (s + n); // Constraint or version including leading '/'. + + if (version_only && v[0] != '/') + fail << "exact package version expected instead of version constraint " + << "in '" << s << "'"; - // If only the version is allowed or the package name is followed by '/' - // then fallback to the version parsing. + // If the package name is followed by '/' then fallback to the version + // parsing. // - if (version_only || v[0] == '/') + if (v[0] == '/') try { return version_constraint ( @@ -309,9 +317,11 @@ namespace bpkg } package_version_infos - package_versions (const common_options& o, const dir_paths& ds) + package_versions (const common_options& o, + const dir_paths& ds, + b_info_flags fl) { - vector<b_project_info> pis (package_b_info (o, ds, false /* ext_mods */)); + vector<b_project_info> pis (package_b_info (o, ds, fl)); package_version_infos r; r.reserve (pis.size ()); @@ -346,7 +356,7 @@ namespace bpkg const vector<package_info::subproject>& sps ( pi != nullptr ? pi->subprojects - : package_b_info (o, d, false /* ext_mods */).subprojects); + : package_b_info (o, d, b_info_flags::subprojects).subprojects); for (const package_info::subproject& sp: sps) cs.append (sp.path.string ()); @@ -362,18 +372,18 @@ namespace bpkg // Return the sorted list of *.build files (first) which are present in the // package's build/config/ subdirectory (or their alternatives) together // with the *-build manifest value names they correspond to (second). Skip - // files which are already present in the specified list. Note: throws - // system_error on filesystem errors. + // files which are already present in the specified buildfile/path + // lists. Note: throws system_error on filesystem errors. // static vector<pair<path, path>> find_buildfiles (const dir_path& config, const string& ext, - const vector<buildfile>& bs) + const vector<buildfile>& bs, + const vector<path>& bps) { vector<pair<path, path>> r; - for (const dir_entry& de: - dir_iterator (config, false /* ignore_dangling */)) + for (const dir_entry& de: dir_iterator (config, dir_iterator::no_follow)) { if (de.type () == entry_type::regular) { @@ -386,7 +396,8 @@ namespace bpkg if (find_if (bs.begin (), bs.end (), [&f] (const auto& v) {return v.path == f;}) == - bs.end ()) + bs.end () && + find (bps.begin (), bps.end (), f) == bps.end ()) { r.emplace_back (config / p, move (f)); } @@ -405,6 +416,7 @@ namespace bpkg const optional<string>& rb, const vector<buildfile>& bs, const dir_path& d, + const vector<path>& bps, optional<bool> an) { if (d.empty ()) @@ -422,10 +434,10 @@ namespace bpkg return cs.string (); } - auto checksum = [&bb, &rb, &bs] (const path& b, - const path& r, - const dir_path& c, - const string& e) + auto checksum = [&bb, &rb, &bs, &bps] (const path& b, + const path& r, + const dir_path& c, + const string& e) { sha256 cs; @@ -464,10 +476,23 @@ namespace bpkg for (const buildfile& b: bs) cs.append (b.content); + if (!bps.empty ()) + { + dir_path bd (b.directory ()); + + for (const path& p: bps) + { + path f (bd / p); + f += '.' + e; + + append_file (f); + } + } + if (root && exists (c)) try { - for (auto& f: find_buildfiles (c, e, bs)) + for (auto& f: find_buildfiles (c, e, bs, bps)) append_file (f.first); } catch (const system_error& e) @@ -521,6 +546,8 @@ namespace bpkg void load_package_buildfiles (package_manifest& m, const dir_path& d, bool erp) { + assert (m.buildfile_paths.empty ()); // build-file values must be expanded. + auto load_buildfiles = [&m, &d, erp] (const path& b, const path& r, const dir_path& c, @@ -559,8 +586,13 @@ namespace bpkg if (m.root_build && exists (c)) try { - for (auto& f: find_buildfiles (c, ext, m.buildfiles)) + for (auto& f: find_buildfiles (c, + ext, + m.buildfiles, + m.buildfile_paths)) + { m.buildfiles.emplace_back (move (f.second), load (f.first)); + } } catch (const system_error& e) { @@ -587,7 +619,7 @@ namespace bpkg "package directory"); if (!erp) - e += " " + d.string (); + e += ' ' + d.string (); throw runtime_error (e); } @@ -619,7 +651,7 @@ namespace bpkg string e ("unable to find bootstrap.build file in package directory"); if (!erp) - e += " " + d.string (); + e += ' ' + d.string (); throw runtime_error (e); } |