[M5] cargoxx add without version (wildcard)
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -78,11 +78,15 @@ All notable changes to cargoxx will be documented in this file.
|
|||||||
and `[build]` honoring `warnings_as_errors` and `sanitizers`. Source
|
and `[build]` honoring `warnings_as_errors` and `sanitizers`. Source
|
||||||
paths emitted relative to `build/` (i.e. prefixed with `../`).
|
paths emitted relative to `build/` (i.e. prefixed with `../`).
|
||||||
Output is deterministic. `tests/codegen_cmake.cpp` covers 11 cases.
|
Output is deterministic. `tests/codegen_cmake.cpp` covers 11 cases.
|
||||||
- `cargoxx add <pkg>@<version> [--components a,b]` edits `Cargoxx.toml`,
|
- `cargoxx add <pkg>[@<version>] [--components a,b]` edits `Cargoxx.toml`,
|
||||||
validates the new dep against the curated linkdb (so unknown packages
|
validates the new dep against the curated linkdb (so unknown packages
|
||||||
and missing components fail before any disk write), and rejects
|
and missing components fail before any disk write), and rejects
|
||||||
already-declared deps. Auto-resolution against nixhub.io/lazamar is
|
already-declared deps. Version is now optional; an omitted version
|
||||||
deferred — for v0.1 the version is required.
|
is stored as `"*"` and resolves against the linkdb's first matching
|
||||||
|
recipe. Generated `flake.nix` continues to track the `nixos-unstable`
|
||||||
|
branch when the lockfile carries no rev.
|
||||||
|
- `util::satisfies` treats `version == "*"` as a match against any
|
||||||
|
range, mirroring the existing `range == "*"` shortcut.
|
||||||
- `cargoxx remove <pkg>` drops a declared dep from `Cargoxx.toml`,
|
- `cargoxx remove <pkg>` drops a declared dep from `Cargoxx.toml`,
|
||||||
errors when the dep is not declared. Other deps are preserved.
|
errors when the dep is not declared. Other deps are preserved.
|
||||||
- End-to-end verified on a freshly-scaffolded project. `tests/cmd_add.cpp`
|
- End-to-end verified on a freshly-scaffolded project. `tests/cmd_add.cpp`
|
||||||
|
|||||||
@@ -19,15 +19,10 @@ auto cmd_add(const fs::path& project_root, const std::string& name,
|
|||||||
"", std::nullopt, std::nullopt,
|
"", std::nullopt, std::nullopt,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (version_spec.empty()) {
|
// Empty version → wildcard. The generated flake.nix tracks `nixos-unstable`
|
||||||
return std::unexpected(util::Error{
|
// and the linkdb resolver picks whichever recipe is listed first for the
|
||||||
util::ErrorCode::ManifestVersionInvalid,
|
// package. Concrete versions land when the resolver against nixhub.io ships.
|
||||||
std::format("version required for '{}'", name),
|
const std::string effective_version = version_spec.empty() ? std::string{"*"} : version_spec;
|
||||||
"use the form 'cargoxx add <pkg>@<version>' "
|
|
||||||
"(auto-resolve against nixhub is deferred)",
|
|
||||||
std::nullopt, std::nullopt,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
auto manifest_path = project_root / "Cargoxx.toml";
|
auto manifest_path = project_root / "Cargoxx.toml";
|
||||||
auto m = manifest::parse(manifest_path);
|
auto m = manifest::parse(manifest_path);
|
||||||
@@ -50,13 +45,13 @@ auto cmd_add(const fs::path& project_root, const std::string& name,
|
|||||||
if (!db) {
|
if (!db) {
|
||||||
return std::unexpected(db.error());
|
return std::unexpected(db.error());
|
||||||
}
|
}
|
||||||
if (auto check = db->resolve(name, version_spec, components); !check) {
|
if (auto check = db->resolve(name, effective_version, components); !check) {
|
||||||
return std::unexpected(check.error());
|
return std::unexpected(check.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
m->dependencies.push_back(manifest::Dependency{
|
m->dependencies.push_back(manifest::Dependency{
|
||||||
.name = name,
|
.name = name,
|
||||||
.version_spec = version_spec,
|
.version_spec = effective_version,
|
||||||
.components = std::move(components),
|
.components = std::move(components),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -113,11 +113,12 @@ auto check(const Clause& c, const Version& v) -> bool {
|
|||||||
|
|
||||||
auto satisfies(std::string_view version, std::string_view range) -> bool {
|
auto satisfies(std::string_view version, std::string_view range) -> bool {
|
||||||
range = trim(range);
|
range = trim(range);
|
||||||
if (range == "*") {
|
version = trim(version);
|
||||||
|
if (range == "*" || version == "*") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto v = parse_version(trim(version));
|
auto v = parse_version(version);
|
||||||
if (!v) {
|
if (!v) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,13 +61,28 @@ TEST_CASE("cmd_add stores components when provided", "[cli][add]") {
|
|||||||
std::vector<std::string>{"filesystem", "system"});
|
std::vector<std::string>{"filesystem", "system"});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("cmd_add rejects an empty version", "[cli][add]") {
|
TEST_CASE("cmd_add accepts an empty version and stores '*'", "[cli][add]") {
|
||||||
auto parent = fresh_dir();
|
auto parent = fresh_dir();
|
||||||
auto root = scaffold(parent);
|
auto root = scaffold(parent);
|
||||||
|
|
||||||
auto r = cmd_add(root, "fmt", "", {}, overlay_path(parent));
|
auto r = cmd_add(root, "fmt", "", {}, overlay_path(parent));
|
||||||
|
REQUIRE(r.has_value());
|
||||||
|
|
||||||
|
auto m = manifest::parse(root / "Cargoxx.toml");
|
||||||
|
REQUIRE(m.has_value());
|
||||||
|
REQUIRE(m->dependencies.size() == 1);
|
||||||
|
REQUIRE(m->dependencies[0].name == "fmt");
|
||||||
|
REQUIRE(m->dependencies[0].version_spec == "*");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("cmd_add with wildcard version still rejects unknown packages",
|
||||||
|
"[cli][add]") {
|
||||||
|
auto parent = fresh_dir();
|
||||||
|
auto root = scaffold(parent);
|
||||||
|
|
||||||
|
auto r = cmd_add(root, "obscurelib", "", {}, overlay_path(parent));
|
||||||
REQUIRE_FALSE(r.has_value());
|
REQUIRE_FALSE(r.has_value());
|
||||||
REQUIRE(r.error().code == ErrorCode::ManifestVersionInvalid);
|
REQUIRE(r.error().code == ErrorCode::LinkdbUnknownPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("cmd_add rejects an unknown package", "[cli][add]") {
|
TEST_CASE("cmd_add rejects an unknown package", "[cli][add]") {
|
||||||
|
|||||||
@@ -52,3 +52,11 @@ TEST_CASE("satisfies returns false on malformed inputs", "[util][semver]") {
|
|||||||
REQUIRE_FALSE(satisfies("not-a-version", ">=1.0.0"));
|
REQUIRE_FALSE(satisfies("not-a-version", ">=1.0.0"));
|
||||||
REQUIRE_FALSE(satisfies("1.0.0", "garbage"));
|
REQUIRE_FALSE(satisfies("1.0.0", "garbage"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("satisfies treats version='*' as a match for any range",
|
||||||
|
"[util][semver]") {
|
||||||
|
REQUIRE(satisfies("*", ">=10.0.0"));
|
||||||
|
REQUIRE(satisfies("*", "<2.0.0"));
|
||||||
|
REQUIRE(satisfies("*", "==1.2.3"));
|
||||||
|
REQUIRE(satisfies("*", "*"));
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user