From f3d3143aa67d1d038f5eee1103c2b783d54955c4 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 30 Nov 2018 13:28:04 +0300 Subject: Match build configuration names, targets and machine names as paths --- mod/build-config.cxx | 78 ++++++++++++++++++++++++++----- mod/build-config.hxx | 11 +++++ mod/mod-build-task.cxx | 17 +++++-- tests/load/1/math/libexp-+2-1.2+1.tar.gz | Bin 368 -> 388 bytes tests/load/1/math/packages.manifest | 6 +-- tests/load/driver.cxx | 6 +-- 6 files changed, 96 insertions(+), 22 deletions(-) diff --git a/mod/build-config.cxx b/mod/build-config.cxx index 5d3f46b..9368d33 100644 --- a/mod/build-config.cxx +++ b/mod/build-config.cxx @@ -6,7 +6,7 @@ #include #include -#include // find() +#include // replace() #include #include // throw_generic_error(), alpha(), etc. @@ -245,24 +245,78 @@ namespace brep // Now check if the configuration is excluded/included via the patterns. // - const string& cn (cfg.name); - string tg (cfg.target.string ()); - - for (const build_constraint& c: constrs) + // To implement matching of absent name components with wildcard-only name + // components we are going to convert names into paths (see + // from_build_config_name() for details). + // + // And if any of the build-{include,exclude} values (which is legal) or + // the build configuration name/target (illegal) are invalid paths, + // then we assume no match. + // + try { - if (path_match (c.config, cn) && - (!c.target || path_match (*c.target, tg))) + path cn (from_build_config_name (cfg.name)); + path tg (from_build_config_name (cfg.target.string ())); + + for (const build_constraint& c: constrs) { - if (!c.exclusion) - return false; + if (path_match (from_build_config_name (c.config), + cn, + dir_path () /* start */, + path_match_flags::match_absent) && + (!c.target || + path_match (from_build_config_name (*c.target), + tg, + dir_path () /* start */, + path_match_flags::match_absent))) + { + if (!c.exclusion) + return false; - if (reason != nullptr) - *reason = sanitize (c.comment); + if (reason != nullptr) + *reason = sanitize (c.comment); - return true; + return true; + } } } + catch (const invalid_path&) {} return false; } + + path + from_build_config_name (const string& s) + { + string r; + for (size_t i (0); i != s.size (); ++i) + { + char c (s[i]); + + switch (c) + { + case '-': + { + r += '/'; + break; + } + case '*': + { + if (s[i + 1] == '*') // Can be '\0'. + { + r += "*/**/*"; + ++i; + break; + } + } + default: + { + r += c; + break; + } + } + } + + return path (move (r)); + } } diff --git a/mod/build-config.hxx b/mod/build-config.hxx index e7ee9eb..a6f9902 100644 --- a/mod/build-config.hxx +++ b/mod/build-config.hxx @@ -80,6 +80,17 @@ namespace brep { return exclude (p.builds, p.constraints, c, r); } + + // Convert the build configuration name, target, machine name or their + // pattern into path, replacing dashes with slashes and double stars with + // the `*/**/*` substring for a subsequent match using our path_match() + // functionality. Throw invalid_path if the resulting path is invalid. + // + // Note that it is assumed that the match_absent path match flag will be + // used for matching for the double star replacement to make sense. + // + path + from_build_config_name (const string&); } #endif // MOD_BUILD_CONFIG_HXX diff --git a/mod/mod-build-task.cxx b/mod/mod-build-task.cxx index 03c053a..d66e90c 100644 --- a/mod/mod-build-task.cxx +++ b/mod/mod-build-task.cxx @@ -154,10 +154,19 @@ handle (request& rq, response& rs) { for (auto& m: tqm.machines) { - if (path_match (c.machine_pattern, m.name) && - cfg_machines.insert ( - make_pair (c.name.c_str (), config_machine ({&c, &m}))).second) - cfg_names.push_back (c.name.c_str ()); + // The same story as in exclude() from build-config.cxx. + // + try + { + if (path_match (from_build_config_name (c.machine_pattern), + from_build_config_name (m.name), + 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 ()); + } + catch (const invalid_path&) {} } } diff --git a/tests/load/1/math/libexp-+2-1.2+1.tar.gz b/tests/load/1/math/libexp-+2-1.2+1.tar.gz index e8b9183..c49541c 100644 Binary files a/tests/load/1/math/libexp-+2-1.2+1.tar.gz and b/tests/load/1/math/libexp-+2-1.2+1.tar.gz differ diff --git a/tests/load/1/math/packages.manifest b/tests/load/1/math/packages.manifest index df3b083..31baa82 100644 --- a/tests/load/1/math/packages.manifest +++ b/tests/load/1/math/packages.manifest @@ -13,10 +13,10 @@ email: users@exp.example.com build-email: builds@exp.example.com depends: libmisc depends: libpq >= 9.0.0 -build-exclude: *; Only supported on Linux. -build-include: linux* +build-include: windows**d/x86_64** +build-exclude: **; Only supported on Windows. location: libexp-+2-1.2+1.tar.gz -sha256sum: 9449cb008ca8cc3b91fbe5c44ae87f0e10fd24ff453bb88cf4504dabe2068eb3 +sha256sum: 6dc3ef269d7f50af2c234c51407eb5622e7395af8bf50a5f75880688c064b79b : name: libfoo version: +0-X.Y diff --git a/tests/load/driver.cxx b/tests/load/driver.cxx index 8a592d6..04e7368 100644 --- a/tests/load/driver.cxx +++ b/tests/load/driver.cxx @@ -829,12 +829,12 @@ test_pkg_repos (const cstrings& loader_args, assert ( epv->build_constraints == build_constraints ({ - build_constraint (true, "*", nullopt, "Only supported on Linux."), - build_constraint (false, "linux*", nullopt, "")})); + build_constraint (false, "windows**d", "x86_64**", ""), + build_constraint (true, "**", nullopt, "Only supported on Windows.")})); assert (check_location (epv)); assert (epv->sha256sum && *epv->sha256sum == - "9449cb008ca8cc3b91fbe5c44ae87f0e10fd24ff453bb88cf4504dabe2068eb3"); + "6dc3ef269d7f50af2c234c51407eb5622e7395af8bf50a5f75880688c064b79b"); // Verify libpq package version. // -- cgit v1.1