diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2022-08-25 20:54:40 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2022-08-29 17:18:19 +0300 |
commit | 6613fbc2a3fc96b491b6691145c72c5a9550dc84 (patch) | |
tree | bb1116efb5b475608458038240a4ba80e32b99af /mod | |
parent | 340cf0935a199240f6daaab8a347e22172f4d15b (diff) |
Add target to build configuration id
Diffstat (limited to 'mod')
-rw-r--r-- | mod/build-config-module.cxx | 14 | ||||
-rw-r--r-- | mod/build-config-module.hxx | 22 | ||||
-rw-r--r-- | mod/build-config.hxx | 23 | ||||
-rw-r--r-- | mod/build.cxx | 2 | ||||
-rw-r--r-- | mod/mod-build-force.cxx | 16 | ||||
-rw-r--r-- | mod/mod-build-log.cxx | 20 | ||||
-rw-r--r-- | mod/mod-build-result.cxx | 23 | ||||
-rw-r--r-- | mod/mod-build-task.cxx | 45 | ||||
-rw-r--r-- | mod/mod-builds.cxx | 94 | ||||
-rw-r--r-- | mod/mod-package-version-details.cxx | 38 | ||||
-rw-r--r-- | mod/module.cli | 4 |
11 files changed, 189 insertions, 112 deletions
diff --git a/mod/build-config-module.cxx b/mod/build-config-module.cxx index 1b1d53e..bf21fbb 100644 --- a/mod/build-config-module.cxx +++ b/mod/build-config-module.cxx @@ -137,22 +137,12 @@ namespace brep bot_agent_key_map_ = shared_bot_agent_keys (bo, bo.build_bot_agent_keys ()); - cstrings conf_names; - - using conf_map_type = map<const char*, - const build_config*, - compare_c_string>; - + using conf_map_type = map<build_config_id, const build_config*>; conf_map_type conf_map; for (const auto& c: *build_conf_) - { - const char* cn (c.name.c_str ()); - conf_map[cn] = &c; - conf_names.push_back (cn); - } + conf_map[build_config_id {c.name, c.target}] = &c; - build_conf_names_ = make_shared<cstrings> (move (conf_names)); build_conf_map_ = make_shared<conf_map_type> (move (conf_map)); } diff --git a/mod/build-config-module.hxx b/mod/build-config-module.hxx index 51813c0..b276d6c 100644 --- a/mod/build-config-module.hxx +++ b/mod/build-config-module.hxx @@ -6,7 +6,7 @@ #include <map> -#include <libbutl/utility.hxx> // compare_c_string +#include <libbutl/target-triplet.hxx> #include <libbpkg/manifest.hxx> @@ -64,15 +64,16 @@ namespace brep return belongs (cfg, cls.c_str ()); } - // Configuration/toolchain combination that, in particular, can be used as - // a set value. + // Configuration/target/toolchain combination that, in particular, can be + // used as a set value. // - // Note: contains shallow references to the configuration, toolchain name, - // and version. + // Note: contains shallow references to the configuration, target, + // toolchain name, and version. // struct config_toolchain { const string& configuration; + const butl::target_triplet& target; const string& toolchain_name; const bpkg::version& toolchain_version; @@ -85,7 +86,10 @@ namespace brep if (toolchain_version != ct.toolchain_version) return toolchain_version > ct.toolchain_version; - return configuration.compare (ct.configuration) < 0; + if (int r = configuration.compare (ct.configuration)) + return r < 0; + + return target.compare (ct.target) < 0; } }; @@ -93,11 +97,9 @@ namespace brep // Build configurations. // shared_ptr<const bbot::build_configs> build_conf_; - shared_ptr<const cstrings> build_conf_names_; - shared_ptr<const std::map<const char*, - const bbot::build_config*, - butl::compare_c_string>> build_conf_map_; + shared_ptr<const std::map<build_config_id, const bbot::build_config*>> + build_conf_map_; // Map of build bot agent public keys fingerprints to the key file paths. // diff --git a/mod/build-config.hxx b/mod/build-config.hxx index e8dfe07..4ef01f6 100644 --- a/mod/build-config.hxx +++ b/mod/build-config.hxx @@ -6,6 +6,8 @@ #include <map> +#include <libbutl/target-triplet.hxx> + #include <libbpkg/manifest.hxx> #include <libbbot/build-config.hxx> @@ -44,6 +46,27 @@ namespace brep // path dash_components_to_path (const string&); + + // Build configuration name/target combination that, in particular, + // identifies configurations in the buildtab and thus can be used as a + // set/map key. + // + // Note: contains shallow references to the configuration name and target. + // + struct build_config_id + { + reference_wrapper<const string> name; + reference_wrapper<const butl::target_triplet> target; + + bool + operator< (const build_config_id& x) const + { + if (int r = name.get ().compare (x.name.get ())) + return r < 0; + + return target.get ().compare (x.target.get ()) < 0; + } + }; } #endif // MOD_BUILD_CONFIG diff --git a/mod/build.cxx b/mod/build.cxx index 5b9d8aa..3b82aed 100644 --- a/mod/build.cxx +++ b/mod/build.cxx @@ -24,6 +24,7 @@ namespace brep mime_url_encode (b.package_name.string (), false) + '/' + b.package_version.string () + "/log/" + mime_url_encode (b.configuration, false /* query */) + '/' + + mime_url_encode (b.target.string (), false /* query */) + '/' + mime_url_encode (b.toolchain_name, false /* query */) + '/' + b.toolchain_version.string ()); @@ -48,6 +49,7 @@ namespace brep "?build-force&pn=" + mime_url_encode (b.package_name.string ()) + "&pv=" + b.package_version.string () + "&cf=" + mime_url_encode (b.configuration) + + "&tg=" + mime_url_encode (b.target.string ()) + "&tn=" + mime_url_encode (b.toolchain_name) + "&tv=" + b.toolchain_version.string () + "&reason="; diff --git a/mod/mod-build-force.cxx b/mod/mod-build-force.cxx index bd172e3..281c76c 100644 --- a/mod/mod-build-force.cxx +++ b/mod/mod-build-force.cxx @@ -120,6 +120,17 @@ handle (request& rq, response& rs) if (config.empty ()) throw invalid_argument ("no configuration name"); + target_triplet target; + + try + { + target = target_triplet (params.target ()); + } + catch (const invalid_argument& e) + { + throw invalid_argument (string ("invalid target: ") + e.what ()); + } + string& toolchain_name (params.toolchain_name ()); if (toolchain_name.empty ()) @@ -130,6 +141,7 @@ handle (request& rq, response& rs) id = build_id (package_id (move (tenant), move (p), package_version), move (config), + move (target), move (toolchain_name), toolchain_version); } @@ -149,7 +161,7 @@ handle (request& rq, response& rs) // Make sure the build configuration still exists. // - if (build_conf_map_->find (id.configuration.c_str ()) == + if (build_conf_map_->find (build_config_id {id.configuration, id.target}) == build_conf_map_->end ()) config_expired ("no configuration"); @@ -177,7 +189,7 @@ handle (request& rq, response& rs) l1 ([&]{trace << "force rebuild for " << b->tenant << ' ' << b->package_name << '/' << b->package_version << ' ' - << b->configuration << ' ' + << b->configuration << '/' << b->target << ' ' << b->toolchain_name << '-' << b->toolchain_version << ": " << reason;}); } diff --git a/mod/mod-build-log.cxx b/mod/mod-build-log.cxx index f106d4f..948c9c3 100644 --- a/mod/mod-build-log.cxx +++ b/mod/mod-build-log.cxx @@ -68,7 +68,7 @@ handle (request& rq, response& rs) // // Note that the URL path must be in the following form: // - // <pkg-name>/<pkg-version>/log/<cfg-name>/<toolchain-name>/<toolchain-version>[/<operation>] + // <pkg-name>/<pkg-version>/log/<cfg-name>/<target>/<toolchain-name>/<toolchain-version>[/<operation>] // // Also note that the presence of the first 3 components is guaranteed by // the repository_root module. @@ -132,6 +132,19 @@ handle (request& rq, response& rs) throw invalid_argument ("empty configuration name"); if (i == lpath.end ()) + throw invalid_argument ("no target"); + + target_triplet target; + try + { + target = target_triplet (*i++); + } + catch (const invalid_argument& e) + { + throw invalid_argument (string ("invalid target: ") + e.what ()); + } + + if (i == lpath.end ()) throw invalid_argument ("no toolchain name"); string toolchain_name (*i++); @@ -146,6 +159,7 @@ handle (request& rq, response& rs) id = build_id (package_id (tenant, move (name), package_version), move (config), + move (target), move (toolchain_name), toolchain_version); @@ -190,7 +204,7 @@ handle (request& rq, response& rs) // Make sure the build configuration still exists. // - if (build_conf_map_->find (id.configuration.c_str ()) == + if (build_conf_map_->find (build_config_id {id.configuration, id.target}) == build_conf_map_->end ()) config_expired ("no configuration"); @@ -233,9 +247,9 @@ handle (request& rq, response& rs) << "toolchain: " << b->toolchain_name << '-' << b->toolchain_version << endl << "config: " << b->configuration << endl + << "target: " << b->target << endl << "machine: " << b->machine << " (" << b->machine_summary << ")" << endl - << "target: " << b->target.string () << endl << "timestamp: "; butl::to_stream (os, diff --git a/mod/mod-build-result.cxx b/mod/mod-build-result.cxx index a55b41f..7eefe95 100644 --- a/mod/mod-build-result.cxx +++ b/mod/mod-build-result.cxx @@ -193,13 +193,29 @@ handle (request& rq, response&) p = s.find ('/', b); // End of configuration name. if (p == string::npos) - throw invalid_argument ("no toolchain name"); + throw invalid_argument ("no target"); string config (s, b, p - b); if (config.empty ()) throw invalid_argument ("empty configuration name"); + b = p + 1; // Start of target. + p = s.find ('/', b); // End of target. + + if (p == string::npos) + throw invalid_argument ("no toolchain name"); + + target_triplet target; + try + { + target = target_triplet (string (s, b, p - b)); + } + catch (const invalid_argument& e) + { + throw invalid_argument (string ("invalid target: ") + e.what ()); + } + b = p + 1; // Start of toolchain name. p = s.find ('/', b); // End of toolchain name. @@ -221,6 +237,7 @@ handle (request& rq, response&) id = build_id (package_id (move (tenant), move (name), package_version), move (config), + move (target), move (toolchain_name), toolchain_version); @@ -263,7 +280,8 @@ handle (request& rq, response&) // const bbot::build_config* cfg; { - auto i (build_conf_map_->find (id.configuration.c_str ())); + auto i (build_conf_map_->find (build_config_id {id.configuration, + id.target})); if (i == build_conf_map_->end ()) { @@ -541,6 +559,7 @@ handle (request& rq, response&) bld->package_name.string () + '/' + bld->package_version.string () + '/' + bld->configuration + '/' + + bld->target.string () + '/' + bld->toolchain_name + '-' + bld->toolchain_version.string ()); // Send notification emails to the interested parties. diff --git a/mod/mod-build-task.cxx b/mod/mod-build-task.cxx index 29c048d..137cf6a 100644 --- a/mod/mod-build-task.cxx +++ b/mod/mod-build-task.cxx @@ -13,7 +13,6 @@ #include <libbutl/regex.hxx> #include <libbutl/sha256.hxx> -#include <libbutl/utility.hxx> // compare_c_string #include <libbutl/openssl.hxx> #include <libbutl/fdstream.hxx> // nullfd #include <libbutl/process-io.hxx> @@ -157,8 +156,7 @@ handle (request& rq, response& rs) task_response_manifest tsm; // Map build configurations to machines that are capable of building them. - // The first matching machine is selected for each configuration. Also - // create the configuration name list for use in database queries. + // The first matching machine is selected for each configuration. // struct config_machine { @@ -166,10 +164,9 @@ handle (request& rq, response& rs) machine_header_manifest* machine; }; - using config_machines = map<const char*, config_machine, compare_c_string>; + using config_machines = map<build_config_id, config_machine>; - cstrings cfg_names; - config_machines cfg_machines; + config_machines conf_machines; for (const auto& c: *build_conf_) { @@ -182,10 +179,9 @@ handle (request& rq, response& rs) if (path_match (dash_components_to_path (m.name), dash_components_to_path (c.machine_pattern), dir_path () /* start */, - path_match_flags::match_absent) && - cfg_machines.insert ( - make_pair (c.name.c_str (), config_machine ({&c, &m}))).second) - cfg_names.push_back (c.name.c_str ()); + path_match_flags::match_absent)) + conf_machines.emplace (build_config_id {c.name, c.target}, + config_machine {&c, &m}); } catch (const invalid_path&) {} } @@ -203,7 +199,7 @@ handle (request& rq, response& rs) // rebuild. The rebuild preference is given in the following order: the // greater force state, the greater overall status, the lower timestamp. // - if (!cfg_machines.empty ()) + if (!conf_machines.empty ()) { vector<shared_ptr<build>> rebuilds; @@ -223,6 +219,7 @@ handle (request& rq, response& rs) b->package_name.string () + '/' + b->package_version.string () + '/' + b->configuration + '/' + + b->target.string () + '/' + b->toolchain_name + '/' + b->toolchain_version.string () + '/' + to_string (ts)); @@ -599,12 +596,14 @@ handle (request& rq, response& rs) package_id id; + bld_query sq (false); + for (const auto& cm: conf_machines) + sq = sq || (bld_query::id.configuration == cm.first.name && + bld_query::id.target == cm.first.target); + bld_query bq ( equal<build> (bld_query::id.package, id) && - - bld_query::id.configuration.in_range (cfg_names.begin (), - cfg_names.end ()) && - + sq && bld_query::id.toolchain_name == tqm.toolchain_name && compare_version_eq (bld_query::id.toolchain_version, @@ -714,12 +713,13 @@ handle (request& rq, response& rs) // Also save the built package configurations for which it's time to // be rebuilt. // - config_machines configs (cfg_machines); // Make a copy for this pkg. + config_machines configs (conf_machines); // Make a copy for this pkg. auto pkg_builds (bld_prep_query.execute ()); for (auto i (pkg_builds.begin ()); i != pkg_builds.end (); ++i) { - auto j (configs.find (i->id.configuration.c_str ())); + auto j (configs.find (build_config_id {i->id.configuration, + i->id.target})); // Outdated configurations are already excluded with the database // query. @@ -758,6 +758,7 @@ handle (request& rq, response& rs) build_id bid (move (id), cm.config->name, + cm.config->target, move (tqm.toolchain_name), toolchain_version); @@ -784,6 +785,7 @@ handle (request& rq, response& rs) move (bid.package.name), move (bp.version), move (bid.configuration), + move (bid.target), move (bid.toolchain_name), move (toolchain_version), move (login), @@ -791,7 +793,6 @@ handle (request& rq, response& rs) move (cl), mh.name, move (mh.summary), - cm.config->target, controller_checksum (*cm.config), machine_checksum (*cm.machine)); @@ -823,7 +824,6 @@ handle (request& rq, response& rs) b->agent_challenge = move (cl); b->machine = mh.name; b->machine_summary = move (mh.summary); - b->target = cm.config->target; string ccs (controller_checksum (*cm.config)); string mcs (machine_checksum (*cm.machine)); @@ -911,11 +911,12 @@ handle (request& rq, response& rs) b->state == build_state::built && needs_rebuild (*b)) { - auto i (cfg_machines.find (b->id.configuration.c_str ())); + auto i (conf_machines.find (build_config_id {b->configuration, + b->target})); // Only actual package configurations are loaded (see above). // - assert (i != cfg_machines.end ()); + assert (i != conf_machines.end ()); const config_machine& cm (i->second); // Rebuild the package if still present, is buildable, doesn't @@ -962,8 +963,6 @@ handle (request& rq, response& rs) b->machine = mh.name; b->machine_summary = mh.summary; - b->target = cm.config->target; - // Issue the hard rebuild if the timeout expired, rebuild is // forced, or the configuration or machine has changed. // diff --git a/mod/mod-builds.cxx b/mod/mod-builds.cxx index 596a5ef..b9d841d 100644 --- a/mod/mod-builds.cxx +++ b/mod/mod-builds.cxx @@ -11,6 +11,7 @@ #include <odb/database.hxx> #include <odb/transaction.hxx> +#include <libbutl/utility.hxx> // compare_c_string #include <libbutl/timestamp.hxx> // to_string() #include <libbutl/path-pattern.hxx> @@ -137,7 +138,7 @@ match (const C qc, const string& pattern) // template <typename T> static inline query<T> -build_query (const brep::cstrings* configs, +build_query (const brep::vector<brep::build_config_id>* config_ids, const brep::params::builds& params, const brep::optional<brep::string>& tenant, const brep::optional<bool>& archived) @@ -154,9 +155,15 @@ build_query (const brep::cstrings* configs, if (archived) q = q && qt::archived == *archived; - if (configs != nullptr) - q = q && qb::id.configuration.in_range (configs->begin (), - configs->end ()); + if (config_ids != nullptr) + { + query sq (false); + for (const auto& id: *config_ids) + sq = sq || (qb::id.configuration == id.name && + qb::id.target == id.target); + + q = q && sq; + } // Note that there is no error reported if the filter parameters parsing // fails. Instead, it is considered that no package builds match such a @@ -219,7 +226,7 @@ build_query (const brep::cstrings* configs, // Build target. // if (!params.target ().empty ()) - q = q && match<T> (qb::target, params.target ()); + q = q && match<T> (qb::id.target, params.target ()); // Build result. // @@ -461,15 +468,21 @@ handle (request& rq, response& rs) << DATALIST(ID="configs") << *OPTION(VALUE="*"); - for (const auto& c: *build_conf_names_) - s << *OPTION(VALUE=c); + // Print unique config names from the config map. + // + set<const char*, butl::compare_c_string> conf_names; + for (const auto& c: *build_conf_map_) + { + if (conf_names.insert (c.first.name.get ().c_str ()).second) + s << *OPTION(VALUE=c.first.name.get ()); + } s << ~DATALIST << ~TD << ~TR - << TR_INPUT ("machine", "mn", params.machine (), "*") << TR_INPUT ("target", "tg", params.target (), "*") + << TR_INPUT ("machine", "mn", params.machine (), "*") << TR_SELECT ("result", "rs", params.result (), build_results) << ~TBODY << ~TABLE @@ -497,18 +510,14 @@ handle (request& rq, response& rs) bool exclude_hidden (params.configuration ().empty () || path_pattern (params.configuration ())); - cstrings conf_names; + vector<build_config_id> conf_ids; + conf_ids.reserve (build_conf_map_->size ()); - if (exclude_hidden) + for (const auto& c: *build_conf_map_) { - for (const auto& c: *build_conf_map_) - { - if (belongs (*c.second, "all")) - conf_names.push_back (c.first); - } + if (!exclude_hidden || belongs (*c.second, "all")) + conf_ids.push_back (c.first); } - else - conf_names = *build_conf_names_; size_t count; size_t page (params.page ()); @@ -534,7 +543,7 @@ handle (request& rq, response& rs) using prep_query = prepared_query<package_build>; query q (build_query<package_build> ( - &conf_names, params, tn, nullopt /* archived */)); + &conf_ids, params, tn, nullopt /* archived */)); // Specify the portion. Note that we will be querying builds in chunks, // not to hold locks for too long. @@ -549,7 +558,7 @@ handle (request& rq, response& rs) // first). // q += "ORDER BY" + query::build::timestamp + "DESC" + - "OFFSET" + query::_ref (offset) + "LIMIT 500"; + "OFFSET" + query::_ref (offset) + "LIMIT 500"; connection_ptr conn (build_db_->connection ()); @@ -591,7 +600,8 @@ handle (request& rq, response& rs) { shared_ptr<build>& b (pb.build); - auto i (build_conf_map_->find (b->configuration.c_str ())); + auto i (build_conf_map_->find (build_config_id {b->configuration, + b->target})); assert (i != build_conf_map_->end ()); // Match the configuration against the package build @@ -610,8 +620,7 @@ handle (request& rq, response& rs) // same build multiple times. Let's skip the duplicates. Note: // we don't increment the counter in this case. // - if (find_if (builds.begin (), - builds.end (), + if (find_if (builds.begin (), builds.end (), [&b] (const shared_ptr<build>& pb) { return b->id == pb->id; @@ -672,8 +681,8 @@ handle (request& rq, response& rs) b.toolchain_name + '-' + b.toolchain_version.string ()) << TR_VALUE ("config", b.configuration) - << TR_VALUE ("machine", b.machine) << TR_VALUE ("target", b.target.string ()) + << TR_VALUE ("machine", b.machine) << TR_VALUE ("timestamp", ts); if (b.interactive) // Note: can only be present for the building state. @@ -766,7 +775,8 @@ handle (request& rq, response& rs) // Filter by toolchain. // if (tc == "*" || (t.first == tc_name && t.second == tc_version)) - config_toolchains.insert ({c.name, t.first, t.second}); + config_toolchains.insert ( + config_toolchain {c.name, c.target, t.first, t.second}); } } } @@ -784,15 +794,14 @@ handle (request& rq, response& rs) // due to the build configuration target or class set change. We should // deduct such builds count from the number of existing package builds. // - size_t nmax ( - config_toolchains.size () * - build_db_->query_value<buildable_package_count> ( - package_query<buildable_package_count> ( - params, tn, false /* archived */))); + size_t nmax (config_toolchains.size () * + build_db_->query_value<buildable_package_count> ( + package_query<buildable_package_count> ( + params, tn, false /* archived */))); size_t ncur = build_db_->query_value<package_build_count> ( build_query<package_build_count> ( - &conf_names, bld_params, tn, false /* archived */)); + &conf_ids, bld_params, tn, false /* archived */)); // From now we will be using specific package name and version for each // build database query. @@ -812,21 +821,23 @@ handle (request& rq, response& rs) package_id id; string config; + target_triplet target; const auto& bid (bld_query::build::id); bld_query bq ( equal<package_build_count> (bid.package, id) && bid.configuration == bld_query::_ref (config) && + bid.target == bld_query::_ref (target) && // Note that the query already constrains configurations via the - // configuration name. + // configuration name and target. // // Also note that while the query already constrains the tenant via // the build package id, we still need to pass the tenant not to // erroneously filter out the private tenants. // - build_query<package_build_count> (nullptr /* configs */, + build_query<package_build_count> (nullptr /* config_ids */, bld_params, tn, false /* archived */)); @@ -858,6 +869,7 @@ handle (request& rq, response& rs) nmax -= nt; config = c->name; + target = c->target; ncur -= bld_prep_query.execute_value (); } } @@ -882,6 +894,7 @@ handle (request& rq, response& rs) // 4: toolchain name // 5: toolchain version (descending) // 6: configuration name + // 7: configuration target // // Prepare the build package prepared query. // @@ -941,7 +954,7 @@ handle (request& rq, response& rs) // filter out the private tenants. // build_query<package_build> ( - &conf_names, bld_params, tn, false /* archived */)); + &conf_ids, bld_params, tn, false /* archived */)); prep_bld_query bld_prep_query ( conn->prepare_query<package_build> ("mod-builds-build-query", bq)); @@ -982,7 +995,9 @@ handle (request& rq, response& rs) for (const auto& ct: config_toolchains) { - auto i (build_conf_map_->find (ct.configuration.c_str ())); + auto i (build_conf_map_->find (build_config_id {ct.configuration, + ct.target})); + assert (i != build_conf_map_->end ()); if (!exclude (p->builds, p->constraints, *i->second)) @@ -997,8 +1012,10 @@ handle (request& rq, response& rs) { const build& b (*pb.build); - unbuilt_configs.erase ({ - b.id.configuration, b.toolchain_name, b.toolchain_version}); + unbuilt_configs.erase (config_toolchain {b.id.configuration, + b.id.target, + b.toolchain_name, + b.toolchain_version}); } // Print unbuilt package configurations. @@ -1011,9 +1028,6 @@ handle (request& rq, response& rs) continue; } - auto i (build_conf_map_->find (ct.configuration.c_str ())); - assert (i != build_conf_map_->end ()); - s << TABLE(CLASS="proplist build") << TBODY << TR_NAME (id.name, string (), root, id.tenant) @@ -1022,7 +1036,7 @@ handle (request& rq, response& rs) string (ct.toolchain_name) + '-' + ct.toolchain_version.string ()) << TR_VALUE ("config", ct.configuration) - << TR_VALUE ("target", i->second->target.string ()); + << TR_VALUE ("target", ct.target.string ()); // In the global view mode add the tenant builds link. Note that // the global view (and the link) makes sense only in the diff --git a/mod/mod-package-version-details.cxx b/mod/mod-package-version-details.cxx index 4a1f0c1..8ea0b01 100644 --- a/mod/mod-package-version-details.cxx +++ b/mod/mod-package-version-details.cxx @@ -568,10 +568,13 @@ handle (request& rq, response& rs) toolchains.emplace_back (move (t.name), move (t.version)); } - // Collect configuration names and unbuilt configurations, skipping those - // that are hidden or excluded by the package. + // Compose the configuration filtering sub-query and collect unbuilt + // configurations, skipping those that are hidden or excluded by the + // package. // - cstrings conf_names; + using query = query<build>; + + query sq (false); set<config_toolchain> unbuilt_configs; for (const auto& c: *build_conf_map_) @@ -580,26 +583,24 @@ handle (request& rq, response& rs) if (belongs (cfg, "all") && !exclude (cfg)) { - conf_names.push_back (c.first); + const build_config_id& id (c.first); + + sq = sq || (query::id.configuration == id.name && + query::id.target == id.target); // Note: we will erase built configurations from the unbuilt // configurations set later (see below). // for (const auto& t: toolchains) - unbuilt_configs.insert ({cfg.name, t.first, t.second}); + unbuilt_configs.insert ( + config_toolchain {cfg.name, cfg.target, t.first, t.second}); } } // Print the package built configurations in the time-descending order. // - using query = query<build>; - for (auto& b: build_db_->query<build> ( - (query::id.package == pkg->id && - - query::id.configuration.in_range (conf_names.begin (), - conf_names.end ())) + - + (query::id.package == pkg->id && sq) + "ORDER BY" + query::timestamp + "DESC")) { string ts (butl::to_string (b.timestamp, @@ -630,9 +631,10 @@ handle (request& rq, response& rs) // While at it, erase the built configuration from the unbuilt // configurations set. // - unbuilt_configs.erase ({b.id.configuration, - b.toolchain_name, - b.toolchain_version}); + unbuilt_configs.erase (config_toolchain {b.configuration, + b.target, + b.toolchain_name, + b.toolchain_version}); } // Print the package unbuilt configurations with the following sort @@ -644,17 +646,13 @@ handle (request& rq, response& rs) // for (const auto& ct: unbuilt_configs) { - auto i (build_conf_map_->find (ct.configuration.c_str ())); - assert (i != build_conf_map_->end ()); - s << TABLE(CLASS="proplist build") << TBODY << TR_VALUE ("toolchain", ct.toolchain_name + '-' + ct.toolchain_version.string ()) << TR_VALUE ("config", - ct.configuration + " / " + - i->second->target.string ()) + ct.configuration + " / " + ct.target.string ()) << TR_VALUE ("result", "unbuilt") << ~TBODY << ~TABLE; diff --git a/mod/module.cli b/mod/module.cli index bd61873..3ac8b30 100644 --- a/mod/module.cli +++ b/mod/module.cli @@ -769,6 +769,10 @@ namespace brep // string configuration | cf; + // Package build target. + // + string target | tg; + // Toolchain name. // string toolchain_name | tn; |