diff options
Diffstat (limited to 'libbpkg/manifest.hxx')
-rw-r--r-- | libbpkg/manifest.hxx | 706 |
1 files changed, 415 insertions, 291 deletions
diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx index 3b75830..feb3b96 100644 --- a/libbpkg/manifest.hxx +++ b/libbpkg/manifest.hxx @@ -10,8 +10,7 @@ #include <cassert> #include <cstdint> // uint*_t #include <ostream> -#include <utility> // move() -#include <stdexcept> // logic_error +#include <utility> // move(), pair #include <functional> #include <libbutl/url.hxx> @@ -102,7 +101,7 @@ namespace bpkg version (version&&) = default; version (const version&) = default; - version& operator= (version&&); + version& operator= (version&&) noexcept; version& operator= (const version&); // If the revision is ignored, then the iteration (that semantically @@ -111,23 +110,12 @@ namespace bpkg std::string string (bool ignore_revision = false, bool ignore_iteration = false) const; - bool - operator< (const version& v) const noexcept {return compare (v) < 0;} - - bool - operator> (const version& v) const noexcept {return compare (v) > 0;} - - bool - operator== (const version& v) const noexcept {return compare (v) == 0;} - - bool - operator<= (const version& v) const noexcept {return compare (v) <= 0;} - - bool - operator>= (const version& v) const noexcept {return compare (v) >= 0;} - - bool - operator!= (const version& v) const noexcept {return compare (v) != 0;} + bool operator< (const version& v) const noexcept; + bool operator> (const version& v) const noexcept; + bool operator== (const version& v) const noexcept; + bool operator<= (const version& v) const noexcept; + bool operator>= (const version& v) const noexcept; + bool operator!= (const version& v) const noexcept; // If the revision is ignored, then the iteration is also ignored, // regardless of the argument (see above for details). @@ -135,28 +123,7 @@ namespace bpkg int compare (const version& v, bool ignore_revision = false, - bool ignore_iteration = false) const noexcept - { - if (epoch != v.epoch) - return epoch < v.epoch ? -1 : 1; - - if (int c = canonical_upstream.compare (v.canonical_upstream)) - return c; - - if (int c = canonical_release.compare (v.canonical_release)) - return c; - - if (!ignore_revision) - { - if (revision != v.revision) - return revision < v.revision ? -1 : 1; - - if (!ignore_iteration && iteration != v.iteration) - return iteration < v.iteration ? -1 : 1; - } - - return 0; - } + bool ignore_iteration = false) const noexcept; bool empty () const noexcept @@ -207,33 +174,10 @@ namespace bpkg return os << (v.empty () ? "<empty-version>" : v.string ()); } - inline version::flags - operator&= (version::flags& x, version::flags y) - { - return x = static_cast<version::flags> ( - static_cast<std::uint16_t> (x) & - static_cast<std::uint16_t> (y)); - } - - inline version::flags - operator|= (version::flags& x, version::flags y) - { - return x = static_cast<version::flags> ( - static_cast<std::uint16_t> (x) | - static_cast<std::uint16_t> (y)); - } - - inline version::flags - operator& (version::flags x, version::flags y) - { - return x &= y; - } - - inline version::flags - operator| (version::flags x, version::flags y) - { - return x |= y; - } + version::flags operator& (version::flags, version::flags); + version::flags operator| (version::flags, version::flags); + version::flags operator&= (version::flags&, version::flags); + version::flags operator|= (version::flags&, version::flags); // priority // @@ -251,11 +195,17 @@ namespace bpkg operator value_type () const {return value;} }; - // description - // description-file - // change - // change-file + // language // + struct language + { + std::string name; + bool impl; // True if implementation-only. + + language (): impl (false) {} + language (std::string n, bool i): name (std::move (n)), impl (i) {} + }; + class LIBBPKG_EXPORT text_file { public: @@ -281,14 +231,80 @@ namespace bpkg text_file (path_type p, std::string c) : file (true), path (std::move (p)), comment (std::move (c)) {} - text_file (text_file&&); + text_file (text_file&&) noexcept; text_file (const text_file&); - text_file& operator= (text_file&&); + text_file& operator= (text_file&&) noexcept; text_file& operator= (const text_file&); ~text_file (); }; + enum class text_type + { + plain, + common_mark, + github_mark + }; + + LIBBPKG_EXPORT std::string + to_string (text_type); + + // Throw std::invalid_argument if the argument is not a well-formed text + // type. Otherwise, return nullopt for an unknown text variant. + // + LIBBPKG_EXPORT butl::optional<text_type> + to_text_type (const std::string&); + + inline std::ostream& + operator<< (std::ostream& os, text_type t) + { + return os << to_string (t); + } + + // description + // description-file + // description-type + // package-description + // package-description-file + // package-description-type + // change + // change-file + // change-type + // + class LIBBPKG_EXPORT typed_text_file: public text_file + { + public: + butl::optional<std::string> type; + + // File text constructor. + // + explicit + typed_text_file (std::string s = "", + butl::optional<std::string> t = butl::nullopt) + : text_file (std::move (s)), type (std::move (t)) {} + + // File reference constructor. + // + typed_text_file (path_type p, + std::string c, + butl::optional<std::string> t = butl::nullopt) + : text_file (std::move (p), std::move (c)), type (std::move (t)) {} + + // Return the type value if present, text_type::github_mark if it refers + // to a file with the .md or .markdown extension and text_type::plain if + // it refers to a file with the .txt extension or no extension or the text + // does not come from a file. Depending on the ignore_unknown value either + // throw std::invalid_argument or return nullopt if the type value or the + // file extension is unknown. + // + // Note: also throws std::invalid_argument if the type is not well-formed. + // This, however, may not happen for an object created by the package + // manifest parser since it has already verified that. + // + butl::optional<text_type> + effective_type (bool ignore_unknown = false) const; + }; + // license // class licenses: public butl::small_vector<std::string, 1> @@ -415,17 +431,10 @@ namespace bpkg } inline bool - operator== (const version_constraint& x, const version_constraint& y) - { - return x.min_version == y.min_version && x.max_version == y.max_version && - x.min_open == y.min_open && x.max_open == y.max_open; - } + operator== (const version_constraint&, const version_constraint&); inline bool - operator!= (const version_constraint& x, const version_constraint& y) - { - return !(x == y); - } + operator!= (const version_constraint&, const version_constraint&); struct LIBBPKG_EXPORT dependency { @@ -447,11 +456,8 @@ namespace bpkg string () const; }; - inline std::ostream& - operator<< (std::ostream& os, const dependency& d) - { - return os << d.string (); - } + std::ostream& + operator<< (std::ostream&, const dependency&); // depends // @@ -593,8 +599,13 @@ namespace bpkg // Return true if the string() function would return the single-line // representation. // - LIBBPKG_EXPORT bool - single_line () const; + bool + single_line () const + { + return !prefer && + !require && + (!reflect || reflect->find ('\n') == std::string::npos); + } }; inline std::ostream& @@ -650,7 +661,7 @@ namespace bpkg // Return true if there is a conditional alternative in the list. // - LIBBPKG_EXPORT bool + bool conditional () const; }; @@ -701,8 +712,11 @@ namespace bpkg // Return true if the string() function would return the single-line // representation. // - LIBBPKG_EXPORT bool - single_line () const; + bool + single_line () const + { + return !reflect || reflect->find ('\n') == std::string::npos; + } // Return true if this is a single requirement with an empty id or an // empty enable condition. @@ -755,7 +769,7 @@ namespace bpkg // Return true if there is a conditional alternative in the list. // - LIBBPKG_EXPORT bool + bool conditional () const; // Return true if this is a single simple requirement alternative. @@ -811,47 +825,31 @@ namespace bpkg // enum class package_manifest_flags: std::uint16_t { - none = 0x000, - - forbid_file = 0x001, // Forbid *-file manifest values. - forbid_location = 0x002, - forbid_sha256sum = 0x004, - forbid_fragment = 0x008, - forbid_incomplete_dependencies = 0x010, - - require_location = 0x020, - require_sha256sum = 0x040, - require_description_type = 0x080, - require_bootstrap_build = 0x100 + none = 0x000, + + forbid_file = 0x001, // Forbid *-file manifest values. + forbid_location = 0x002, + forbid_sha256sum = 0x004, + forbid_fragment = 0x008, + forbid_incomplete_values = 0x010, // depends, <distribution>-version, etc. + + require_location = 0x020, + require_sha256sum = 0x040, + require_text_type = 0x080, // description-type, changes-type, etc. + require_bootstrap_build = 0x100 }; - inline package_manifest_flags - operator&= (package_manifest_flags& x, package_manifest_flags y) - { - return x = static_cast<package_manifest_flags> ( - static_cast<std::uint16_t> (x) & - static_cast<std::uint16_t> (y)); - } + package_manifest_flags + operator& (package_manifest_flags, package_manifest_flags); - inline package_manifest_flags - operator|= (package_manifest_flags& x, package_manifest_flags y) - { - return x = static_cast<package_manifest_flags> ( - static_cast<std::uint16_t> (x) | - static_cast<std::uint16_t> (y)); - } + package_manifest_flags + operator| (package_manifest_flags, package_manifest_flags); - inline package_manifest_flags - operator& (package_manifest_flags x, package_manifest_flags y) - { - return x &= y; - } + package_manifest_flags + operator&= (package_manifest_flags&, package_manifest_flags); - inline package_manifest_flags - operator| (package_manifest_flags x, package_manifest_flags y) - { - return x |= y; - } + package_manifest_flags + operator|= (package_manifest_flags&, package_manifest_flags); // Target build configuration class term. // @@ -882,9 +880,9 @@ namespace bpkg build_class_term () : operation ('\0'), inverted (false), simple (true), name () {} - build_class_term (build_class_term&&); + build_class_term (build_class_term&&) noexcept; build_class_term (const build_class_term&); - build_class_term& operator= (build_class_term&&); + build_class_term& operator= (build_class_term&&) noexcept; build_class_term& operator= (const build_class_term&); ~build_class_term (); @@ -973,12 +971,7 @@ namespace bpkg bool& result) const; bool - match (const strings& cs, const build_class_inheritance_map& bs) const - { - bool r (false); - match (cs, bs, r); - return r; - } + match (const strings&, const build_class_inheritance_map&) const; }; inline std::ostream& @@ -987,12 +980,56 @@ namespace bpkg return os << bce.string (); } - // Package build configuration. Includes comment and optional target build - // configuration class expressions/constraints overrides. + // Build auxiliary configuration name-matching wildcard. Includes optional + // environment name (specified as a suffix in the [*-]build-auxiliary[-*] + // value name) and comment. + // + class LIBBPKG_EXPORT build_auxiliary + { + public: + std::string environment_name; + + // Filesystem wildcard pattern for the build auxiliary configuration name. + // + std::string config; + + std::string comment; + + build_auxiliary () = default; + build_auxiliary (std::string en, + std::string cf, + std::string cm) + : environment_name (std::move (en)), + config (std::move (cf)), + comment (std::move (cm)) {} + + // Parse a package manifest value name in the [*-]build-auxiliary[-*] form + // into the pair of the build package configuration name (first) and the + // build auxiliary environment name (second), with an unspecified name + // represented as an empty string. Return nullopt if the value name + // doesn't match this form. + // + static butl::optional<std::pair<std::string, std::string>> + parse_value_name (const std::string&); + }; + + // Package build configuration. Includes comment and optional overrides for + // target build configuration class expressions/constraints, auxiliaries, + // custom bot public keys, and notification emails. // - class build_package_config + // Note that in the package manifest the build bot keys list contains the + // public keys data (std::string type). However, for other use cases it may + // be convenient to store some other key representations (public key object + // pointers represented as key fingerprints, etc; see brep for such a use + // case). + // + template <typename K> + class build_package_config_template { public: + using email_type = bpkg::email; + using key_type = K; + std::string name; // Whitespace separated list of potentially double/single-quoted package @@ -1006,12 +1043,44 @@ namespace bpkg butl::small_vector<build_class_expr, 1> builds; std::vector<build_constraint> constraints; - build_package_config () = default; + // Note that all entries in this list must have distinct environment names + // (with empty name being one of the possibilities). + // + std::vector<build_auxiliary> auxiliaries; + + std::vector<key_type> bot_keys; + + butl::optional<email_type> email; + butl::optional<email_type> warning_email; + butl::optional<email_type> error_email; + + build_package_config_template () = default; + + build_package_config_template (std::string n, + std::string a, + std::string c, + butl::small_vector<build_class_expr, 1> bs, + std::vector<build_constraint> cs, + std::vector<build_auxiliary> as, + std::vector<key_type> bks, + butl::optional<email_type> e, + butl::optional<email_type> we, + butl::optional<email_type> ee) + : name (move (n)), + arguments (move (a)), + comment (move (c)), + builds (move (bs)), + constraints (move (cs)), + auxiliaries (move (as)), + bot_keys (move (bks)), + email (move (e)), + warning_email (move (we)), + error_email (move (ee)) {} // Built incrementally. // explicit - build_package_config (std::string n): name (move (n)) {} + build_package_config_template (std::string n): name (move (n)) {} // Return the configuration's build class expressions/constraints if they // override the specified common expressions/constraints and return the @@ -1031,29 +1100,53 @@ namespace bpkg { return !builds.empty () || !constraints.empty () ? constraints : common; } - }; - enum class text_type - { - plain, - common_mark, - github_mark - }; + // Return the configuration's auxiliaries, if specified, and the common + // ones otherwise. + // + const std::vector<build_auxiliary>& + effective_auxiliaries (const std::vector<build_auxiliary>& common) const + noexcept + { + return !auxiliaries.empty () ? auxiliaries : common; + } - LIBBPKG_EXPORT std::string - to_string (text_type); + // Return the configuration's custom bot public keys, if specified, and + // the common ones otherwise. + // + const std::vector<key_type>& + effective_bot_keys (const std::vector<key_type>& common) const noexcept + { + return !bot_keys.empty () ? bot_keys : common; + } - // Throw std::invalid_argument if the argument is not a well-formed text - // type. Otherwise, return nullopt for an unknown text variant. - // - LIBBPKG_EXPORT butl::optional<text_type> - to_text_type (const std::string&); // May throw std::invalid_argument. + // Return the configuration's build notification emails if they override + // the specified common build notification emails and return the latter + // otherwise (see package_manifest::override() for the override semantics + // details). + // + const butl::optional<email_type>& + effective_email (const butl::optional<email_type>& common) const noexcept + { + return email || warning_email || error_email ? email : common; + } - inline std::ostream& - operator<< (std::ostream& os, text_type t) - { - return os << to_string (t); - } + const butl::optional<email_type>& + effective_warning_email (const butl::optional<email_type>& common) const + noexcept + { + return email || warning_email || error_email ? warning_email : common; + } + + const butl::optional<email_type>& + effective_error_email (const butl::optional<email_type>& common) const + noexcept + { + return email || warning_email || error_email ? error_email : common; + } + }; + + using build_package_config = build_package_config_template<std::string>; enum class test_dependency_type { @@ -1080,6 +1173,7 @@ namespace bpkg { test_dependency_type type; bool buildtime; + butl::optional<std::string> enable; butl::optional<std::string> reflect; test_dependency () = default; @@ -1087,15 +1181,17 @@ namespace bpkg test_dependency_type t, bool b, butl::optional<version_constraint> c, + butl::optional<std::string> e, butl::optional<std::string> r) : dependency {std::move (n), std::move (c)}, type (t), buildtime (b), + enable (std::move (e)), reflect (std::move (r)) {} // Parse the test dependency string representation in the - // `[*] <name> [<version-constraint>] [<reflect-config>]` form. Throw - // std::invalid_argument if the value is invalid. + // `[*] <name> [<version-constraint>] ['?' <enable-condition>] [<reflect-config>]` + // form. Throw std::invalid_argument if the value is invalid. // // Verify that the reflect clause, if present, refers to the test // dependency package configuration variable. Note that such variable @@ -1130,6 +1226,40 @@ namespace bpkg content (std::move (c)) {} }; + // Binary distribution package information. + // + // The name is prefixed with the <distribution> id, typically name/version + // pair in the <name>[_<version>] form. For example: + // + // debian-name + // debian_10-name + // ubuntu_20.04-name + // + // Currently recognized names: + // + // <distribution>-name + // <distribution>-version + // <distribution>-to-downstream-version + // + // Note that the value format/semantics can be distribution-specific. + // + struct distribution_name_value + { + std::string name; + std::string value; + + distribution_name_value () = default; + distribution_name_value (std::string n, std::string v) + : name (std::move (n)), + value (std::move (v)) {} + + // Return the name's <distribution> component if the name has the + // specified suffix, which is assumed to be valid (-name, etc). + // + butl::optional<std::string> + distribution (const std::string& suffix) const; + }; + class LIBBPKG_EXPORT package_manifest { public: @@ -1140,16 +1270,18 @@ namespace bpkg package_name name; version_type version; butl::optional<std::string> upstream_version; + butl::optional<std::string> type; // <name>[, ...] + butl::small_vector<language, 1> languages; // <name>[=impl][, ...] butl::optional<package_name> project; butl::optional<priority_type> priority; std::string summary; - butl::small_vector<licenses, 1> license_alternatives; + butl::small_vector<std::string, 5> topics; butl::small_vector<std::string, 5> keywords; - butl::optional<text_file> description; - butl::optional<std::string> description_type; - butl::small_vector<text_file, 1> changes; + butl::optional<typed_text_file> description; + butl::optional<typed_text_file> package_description; + butl::small_vector<typed_text_file, 1> changes; butl::optional<manifest_url> url; butl::optional<manifest_url> doc_url; butl::optional<manifest_url> src_url; @@ -1163,11 +1295,16 @@ namespace bpkg std::vector<requirement_alternatives> requirements; butl::small_vector<test_dependency, 1> tests; - // Common build classes/constraints that apply to all configurations - // unless overridden. + // Common build classes, constraints, auxiliaries, and custom bot public + // keys that apply to all configurations unless overridden. + // + // Note that all entries in build_auxiliaries must have distinct + // environment names (with empty name being one of the possibilities). // butl::small_vector<build_class_expr, 1> builds; std::vector<build_constraint> build_constraints; + std::vector<build_auxiliary> build_auxiliaries; + strings build_bot_keys; // Note that the parsing constructor adds the implied (empty) default // configuration at the beginning of the list. Also note that serialize() @@ -1189,6 +1326,10 @@ namespace bpkg std::vector<buildfile> buildfiles; // Buildfiles content. std::vector<butl::path> buildfile_paths; + // The binary distributions package information. + // + std::vector<distribution_name_value> distribution_values; + // The following values are only valid in the manifest list (and only for // certain repository types). // @@ -1196,19 +1337,45 @@ namespace bpkg butl::optional<std::string> sha256sum; butl::optional<std::string> fragment; - const package_name& - effective_project () const noexcept {return project ? *project : name;} + // Extract the name from optional type, returning either `exe`, `lib`, or + // `other`. + // + // Specifically, if type is present but the name is not recognized, then + // return `other`. If type is absent and the package name starts with the + // `lib` prefix, then return `lib`. Otherwise, return `exe`. + // + std::string + effective_type () const; + + static std::string + effective_type (const butl::optional<std::string>&, const package_name&); - // Return the description type value if present, text_type::github_mark if - // the description refers to a file with the .md or .markdown extension - // and text_type::plain if it refers to a file with the .txt extension or - // no extension or the description does not come from a file. Depending on - // the ignore_unknown value either throw std::invalid_argument or return - // nullopt if the description value or the file extension is unknown. - // Throw std::logic_error if the description value is nullopt. + // Extract sub-options from optional type. // - butl::optional<text_type> - effective_description_type (bool ignore_unknown = false) const; + strings + effective_type_sub_options () const; + + static strings + effective_type_sub_options (const butl::optional<std::string>&); + + // Translate the potentially empty list of languages to a non-empty one. + // + // Specifically, if the list of languages is not empty, then return it as + // is. Otherwise, if the package name has an extension (as in, say, + // libbutl.bash), then return it as the language. Otherwise, return `cc` + // (unspecified c-common language). + // + butl::small_vector<language, 1> + effective_languages () const; + + static butl::small_vector<language, 1> + effective_languages (const butl::small_vector<language, 1>&, + const package_name&); + + // Return effective project name. + // + const package_name& + effective_project () const noexcept {return project ? *project : name;} public: package_manifest () = default; @@ -1220,7 +1387,7 @@ namespace bpkg // package_manifest (butl::manifest_parser&, bool ignore_unknown = false, - bool complete_dependencies = true, + bool complete_values = true, package_manifest_flags = package_manifest_flags::forbid_location | package_manifest_flags::forbid_sha256sum | @@ -1242,7 +1409,7 @@ namespace bpkg package_manifest (butl::manifest_parser&, const std::function<translate_function>&, bool ignore_unknown = false, - bool complete_depends = true, + bool complete_values = true, package_manifest_flags = package_manifest_flags::forbid_location | package_manifest_flags::forbid_sha256sum | @@ -1257,7 +1424,7 @@ namespace bpkg package_manifest (const std::string& name, std::vector<butl::manifest_name_value>&&, bool ignore_unknown = false, - bool complete_dependencies = true, + bool complete_values = true, package_manifest_flags = package_manifest_flags::forbid_location | package_manifest_flags::forbid_sha256sum | @@ -1267,7 +1434,7 @@ namespace bpkg std::vector<butl::manifest_name_value>&&, const std::function<translate_function>&, bool ignore_unknown = false, - bool complete_depends = true, + bool complete_values = true, package_manifest_flags = package_manifest_flags::forbid_location | package_manifest_flags::forbid_sha256sum | @@ -1278,20 +1445,38 @@ namespace bpkg package_manifest (butl::manifest_parser&, butl::manifest_name_value start, bool ignore_unknown, - bool complete_depends, + bool complete_values, package_manifest_flags); // Override manifest values with the specified. Throw manifest_parsing if // any value is invalid, cannot be overridden, or its name is not // recognized. // - // The specified values override the whole groups they belong to, - // resetting all the group values prior to being applied. Currently, only - // the following value groups can be overridden: + // The specified values other than [*-]build-auxiliary[-*] override the + // whole groups they belong to, resetting all the group values prior to + // being applied. The [*-]build-auxiliary[-*] values only override the + // matching values, which are expected to already be present in the + // manifest. Currently, only the following value groups/values can be + // overridden: // // {build-*email} // {builds, build-{include,exclude}} + // {build-bot} // {*-builds, *-build-{include,exclude}} + // {*-build-bot} + // {*-build-config} + // {*-build-*email} + // + // [*-]build-auxiliary[-*] + // + // Throw manifest_parsing if the configuration specified by the build + // package configuration-specific build constraint, email, auxiliary, or + // custom bot public key value override doesn't exists. In contrast, for + // the build config override add a new configuration if it doesn't exist + // and update the arguments of the existing configuration otherwise. In + // the former case, all the potential build constraint, email, auxiliary, + // and bot key overrides for such a newly added configuration must follow + // the respective *-build-config override. // // Note that the build constraints group values (both common and build // config-specific) are overridden hierarchically so that the @@ -1305,6 +1490,22 @@ namespace bpkg // constraints are overridden, then for the remaining configs the build // constraints are reset to `builds: none`. // + // Similar to the build constraints groups, the common and build + // config-specific custom bot key value overrides are mutually + // exclusive. If the common custom bot keys are overridden, then all the + // build config-specific custom bot keys are removed. Otherwise, if some + // build config-specific custom bot keys are overridden, then for the + // remaining configs the custom bot keys are left unchanged. + // + // Similar to the above, the common and build config-specific build emails + // group value overrides are mutually exclusive. If the common build + // emails are overridden, then all the build config-specific emails are + // reset to nullopt. Otherwise, if some build config-specific emails are + // overridden, then for the remaining configs the email is reset to the + // empty value and the warning and error emails are reset to nullopt + // (which effectively disables email notifications for such + // configurations). + // // If a non-empty source name is specified, then the specified values are // assumed to also include the line/column information and the possibly // thrown manifest_parsing exception will contain the invalid value's @@ -1350,9 +1551,10 @@ namespace bpkg // Load the *-file manifest values using the specified load function that // returns the file contents passing through any exception it may throw. // If nullopt is returned, then the respective *-file value is left - // unexpanded. Set the potentially absent description type value to the - // effective description type. If the effective type is nullopt then - // assign a synthetic unknown type. + // unexpanded. Set the potentially absent project description, package + // description, and changes type values to their effective types. If an + // effective type is nullopt then assign a synthetic unknown type if the + // ignore_unknown argument is true and throw manifest_parsing otherwise. // // Note that if the returned file contents is empty, load_files() makes // sure that this is allowed by the value's semantics throwing @@ -1370,13 +1572,10 @@ namespace bpkg // Create individual package manifest. // - inline package_manifest + package_manifest pkg_package_manifest (butl::manifest_parser& p, bool ignore_unknown = false, - bool complete_depends = true) - { - return package_manifest (p, ignore_unknown, complete_depends); - } + bool complete_values = true); LIBBPKG_EXPORT package_manifest dir_package_manifest (butl::manifest_parser&, bool ignore_unknown = false); @@ -1682,9 +1881,8 @@ namespace bpkg repository_type, const repository_location& base); - repository_location (const repository_location& l, - const repository_location& base) - : repository_location (l.url (), l.type (), base) {} + repository_location (const repository_location&, + const repository_location& base); // Note that relative locations have no canonical name. Canonical name of // an empty location is the empty name. @@ -1702,59 +1900,22 @@ namespace bpkg empty () const noexcept {return url_.empty ();} bool - local () const - { - if (empty ()) - throw std::logic_error ("empty location"); - - return url_.scheme == repository_protocol::file; - } + local () const; bool - remote () const - { - return !local (); - } + remote () const; bool - absolute () const - { - if (empty ()) - throw std::logic_error ("empty location"); - - // Note that in remote locations path is always relative. - // - return url_.path->absolute (); - } + absolute () const; bool - relative () const - { - return local () && url_.path->relative (); - } + relative () const; repository_type - type () const - { - if (empty ()) - throw std::logic_error ("empty location"); - - return type_; - } + type () const; repository_basis - basis () const - { - switch (type ()) - { - case repository_type::pkg: return repository_basis::archive; - case repository_type::dir: return repository_basis::directory; - case repository_type::git: return repository_basis::version_control; - } - - assert (false); // Can't be here. - return repository_basis::archive; - } + basis () const; // Note that the URL of an empty location is empty. // @@ -1768,69 +1929,30 @@ namespace bpkg // "directories" it always contains the trailing slash. // const butl::path& - path () const - { - if (empty ()) - throw std::logic_error ("empty location"); - - return *url_.path; - } + path () const; const std::string& - host () const - { - if (local ()) - throw std::logic_error ("local location"); - - return url_.authority->host; - } + host () const; // Value 0 indicated that no port was specified explicitly. // std::uint16_t - port () const - { - if (local ()) - throw std::logic_error ("local location"); - - return url_.authority->port; - } + port () const; repository_protocol - proto () const - { - if (empty ()) - throw std::logic_error ("empty location"); - - return url_.scheme; - } + proto () const; const butl::optional<std::string>& - fragment () const - { - if (relative ()) - throw std::logic_error ("relative filesystem path"); - - return url_.fragment; - } + fragment () const; bool - archive_based () const - { - return basis () == repository_basis::archive; - } + archive_based () const; bool - directory_based () const - { - return basis () == repository_basis::directory; - } + directory_based () const; bool - version_control_based () const - { - return basis () == repository_basis::version_control; - } + version_control_based () const; // Return an untyped URL if the correct type can be guessed just from // the URL. Otherwise, return the typed URL. @@ -2127,4 +2249,6 @@ namespace bpkg } } +#include <libbpkg/manifest.ixx> + #endif // LIBBPKG_MANIFEST_HXX |