// file : libbbot/manifest.hxx -*- C++ -*- // license : MIT; see accompanying LICENSE file #ifndef LIBBBOT_MANIFEST_HXX #define LIBBBOT_MANIFEST_HXX #include #include #include #include #include #include #include #include // version, repository_location #include #include #include namespace bbot { using strings = std::vector; class LIBBBOT_EXPORT machine_header_manifest { public: std::string id; std::string name; std::string summary; machine_header_manifest (std::string i, std::string n, std::string s) : id (std::move (i)), name (std::move (n)), summary (std::move (s)) {} public: machine_header_manifest () = default; // VC export. machine_header_manifest ( butl::manifest_parser&, butl::manifest_unknown_mode = butl::manifest_unknown_mode::fail); machine_header_manifest ( butl::manifest_parser&, butl::manifest_name_value start, butl::manifest_unknown_mode = butl::manifest_unknown_mode::fail, butl::manifest_name_value* end = nullptr); // Wrapper-ctor. Primarily for use in template functions parameterized // with the manifest type. // machine_header_manifest (butl::manifest_parser& p, bool ignore_unknown) : machine_header_manifest (p, ignore_unknown ? butl::manifest_unknown_mode::skip : butl::manifest_unknown_mode::fail) {} void serialize (butl::manifest_serializer&, bool end_of_manifest = true) const; }; using machine_header_manifests = std::vector; class LIBBBOT_EXPORT task_request_manifest { public: std::string agent; std::string toolchain_name; butl::standard_version toolchain_version; // Agent's public key SHA256 fingerprint. // // @@ How the fingerpring for openssl public key will be produced? Seems // there is no "standard" for it. Possibly we will use the following // command result (plain SHA256). // // $ cat key.pub | openssl sha256 // butl::optional fingerprint; machine_header_manifests machines; task_request_manifest (std::string a, std::string n, butl::standard_version v, butl::optional f, machine_header_manifests m) : agent (std::move (a)), toolchain_name (std::move (n)), toolchain_version (std::move (v)), fingerprint (std::move (f)), machines (std::move (m)) {} public: task_request_manifest () = default; // VC export. task_request_manifest (butl::manifest_parser&, bool ignore_unknown = false); void serialize (butl::manifest_serializer&) const; }; class LIBBBOT_EXPORT task_manifest { public: // Package to build. // bpkg::package_name name; bpkg::version version; bpkg::repository_location repository; // Remote or absolute. // The SHA256 repositories certificates fingerprints to trust. The special // 'yes' value can be specified instead of fingerprint (in which case all // repositories will be trusted without authentication). // strings trust; std::string machine; // Build machine to use for building the package. butl::target_triplet target; // Build target. butl::optional environment; // Build environment name. // Build system configuration variables (in addition to build environment // configuration variables). // Note: could be quoted. // strings config; // Regular expressions for detecting warnings in the operation result logs // (in addition to the default list of expressions). // Note: could be quoted. // strings warning_regex; strings unquoted_config () const; strings unquoted_warning_regex () const; task_manifest (bpkg::package_name nm, bpkg::version vr, bpkg::repository_location rl, strings tr, std::string mn, butl::target_triplet tg, butl::optional en, strings cf, strings wr) : name (std::move (nm)), version (std::move (vr)), repository (std::move (rl)), trust (tr), machine (std::move (mn)), target (std::move (tg)), environment (std::move (en)), config (std::move (cf)), warning_regex (std::move (wr)){} public: task_manifest () = default; // VC export. task_manifest (butl::manifest_parser&, bool ignore_unknown = false); task_manifest (butl::manifest_parser&, butl::manifest_name_value start, bool ignore_unknown = false); void serialize (butl::manifest_serializer&) const; // Check that a string is a valid (ECMAScript) regular expression. Throw // invalid_argument if that's not the case. // static void validate_regex (const std::string&); }; class LIBBBOT_EXPORT task_response_manifest { public: // If empty then no task available. // std::string session; // Challenge, result url and task are absent if session is empty. // butl::optional challenge; butl::optional result_url; butl::optional task; task_response_manifest (std::string s, butl::optional c, butl::optional u, butl::optional t) : session (std::move (s)), challenge (std::move (c)), result_url (std::move (u)), task (std::move (t)) {} public: task_response_manifest () = default; // VC export. task_response_manifest (butl::manifest_parser&, bool ignore_unknown = false); void serialize (butl::manifest_serializer&) const; }; // Build task or operation result status. // enum class result_status: std::uint8_t { // The order of the enumerators is arranged so that their integral values // indicate whether one "overrides" the other in the "merge" operator| // (see below). // success, warning, error, abort, abnormal }; LIBBBOT_EXPORT std::string to_string (result_status); LIBBBOT_EXPORT result_status to_result_status (const std::string&); // May throw invalid_argument. inline std::ostream& operator<< (std::ostream& os, result_status s) {return os << to_string (s);} inline result_status& operator|= (result_status& l, result_status r) { if (static_cast (r) > static_cast (l)) l = r; return l; } // Return true if the result is "bad", that is, error or worse. // inline bool operator! (result_status s) { return static_cast (s) >= static_cast (result_status::error); } struct operation_result { std::string operation; // "configure", "update", "test", etc. result_status status; std::string log; }; using operation_results = std::vector; class LIBBBOT_EXPORT result_manifest { public: // Built package. // // If the version is 0 (which signifies a stub package that cannot be // possibly built) then both name and version are "unknown". This is used // by the worker to signal abnormal termination before being able to // obtain the package name/version. // bpkg::package_name name; bpkg::version version; result_status status; // Ordered (ascending) by operation value. May not contain all the // operations if the task failed in the middle, but should have no gaps // (operation can not start unless all previous ones succeeded). // operation_results results; result_manifest (bpkg::package_name n, bpkg::version v, result_status s, operation_results r) : name (std::move (n)), version (std::move (v)), status (s), results (std::move (r)) {} public: result_manifest () = default; // VC export. result_manifest (butl::manifest_parser&, bool ignore_unknown = false); result_manifest (butl::manifest_parser&, butl::manifest_name_value start, bool ignore_unknown = false); void serialize (butl::manifest_serializer&) const; }; class LIBBBOT_EXPORT result_request_manifest { public: std::string session; // The task response session. // The answer to challenge in the task response. // butl::optional> challenge; result_manifest result; result_request_manifest (std::string s, butl::optional> c, result_manifest r) : session (std::move (s)), challenge (std::move (c)), result (std::move (r)) {} public: result_request_manifest () = default; // VC export. result_request_manifest (butl::manifest_parser&, bool ignore_unknown = false); void serialize (butl::manifest_serializer&) const; }; } #endif // LIBBBOT_MANIFEST_HXX