[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
|
||||
paths emitted relative to `build/` (i.e. prefixed with `../`).
|
||||
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
|
||||
and missing components fail before any disk write), and rejects
|
||||
already-declared deps. Auto-resolution against nixhub.io/lazamar is
|
||||
deferred — for v0.1 the version is required.
|
||||
already-declared deps. Version is now optional; an omitted version
|
||||
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`,
|
||||
errors when the dep is not declared. Other deps are preserved.
|
||||
- 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,
|
||||
});
|
||||
}
|
||||
if (version_spec.empty()) {
|
||||
return std::unexpected(util::Error{
|
||||
util::ErrorCode::ManifestVersionInvalid,
|
||||
std::format("version required for '{}'", name),
|
||||
"use the form 'cargoxx add <pkg>@<version>' "
|
||||
"(auto-resolve against nixhub is deferred)",
|
||||
std::nullopt, std::nullopt,
|
||||
});
|
||||
}
|
||||
// Empty version → wildcard. The generated flake.nix tracks `nixos-unstable`
|
||||
// and the linkdb resolver picks whichever recipe is listed first for the
|
||||
// package. Concrete versions land when the resolver against nixhub.io ships.
|
||||
const std::string effective_version = version_spec.empty() ? std::string{"*"} : version_spec;
|
||||
|
||||
auto manifest_path = project_root / "Cargoxx.toml";
|
||||
auto m = manifest::parse(manifest_path);
|
||||
@@ -50,13 +45,13 @@ auto cmd_add(const fs::path& project_root, const std::string& name,
|
||||
if (!db) {
|
||||
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());
|
||||
}
|
||||
|
||||
m->dependencies.push_back(manifest::Dependency{
|
||||
.name = name,
|
||||
.version_spec = version_spec,
|
||||
.version_spec = effective_version,
|
||||
.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 {
|
||||
range = trim(range);
|
||||
if (range == "*") {
|
||||
version = trim(version);
|
||||
if (range == "*" || version == "*") {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto v = parse_version(trim(version));
|
||||
auto v = parse_version(version);
|
||||
if (!v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -61,13 +61,28 @@ TEST_CASE("cmd_add stores components when provided", "[cli][add]") {
|
||||
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 root = scaffold(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(r.error().code == ErrorCode::ManifestVersionInvalid);
|
||||
REQUIRE(r.error().code == ErrorCode::LinkdbUnknownPackage);
|
||||
}
|
||||
|
||||
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("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