[M6] populate Cargoxx.toml; add 'cargoxx linkdb add' CLI; codegen fixes for self-host
This commit is contained in:
@@ -64,6 +64,7 @@ target_sources(cargoxx
|
|||||||
src/cli/cmd_clean.cpp
|
src/cli/cmd_clean.cpp
|
||||||
src/cli/cmd_add.cpp
|
src/cli/cmd_add.cpp
|
||||||
src/cli/cmd_remove.cpp
|
src/cli/cmd_remove.cpp
|
||||||
|
src/cli/cmd_linkdb_add.cpp
|
||||||
src/cli/run.cpp
|
src/cli/run.cpp
|
||||||
PUBLIC
|
PUBLIC
|
||||||
FILE_SET CXX_MODULES FILES
|
FILE_SET CXX_MODULES FILES
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ sqlite3 = "*"
|
|||||||
reproc = "*"
|
reproc = "*"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
catch2 = "*"
|
catch2_3 = "*"
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
warnings_as_errors = false
|
warnings_as_errors = false
|
||||||
|
include_dirs = ["third_party"]
|
||||||
|
|||||||
@@ -53,6 +53,17 @@ auto cmd_add(const std::filesystem::path& project_root, const std::string& name,
|
|||||||
auto cmd_remove(const std::filesystem::path& project_root, const std::string& name)
|
auto cmd_remove(const std::filesystem::path& project_root, const std::string& name)
|
||||||
-> util::Result<void>;
|
-> util::Result<void>;
|
||||||
|
|
||||||
|
// Inserts a manual recipe into the SQLite linkdb overlay. Equivalent to
|
||||||
|
// the auto-discover path's confirmed row, but user-provided. Use it
|
||||||
|
// when nixpkgs ships a CMake FindModule (no <X>Config.cmake) or when the
|
||||||
|
// scanner can't pick the right target automatically.
|
||||||
|
auto cmd_linkdb_add(const std::string& package, const std::string& version_range,
|
||||||
|
const std::string& find_package_text,
|
||||||
|
std::vector<std::string> targets,
|
||||||
|
const std::string& nixpkgs_attr,
|
||||||
|
std::optional<std::filesystem::path> overlay_path = std::nullopt)
|
||||||
|
-> util::Result<void>;
|
||||||
|
|
||||||
auto run(int argc, char** argv) -> int;
|
auto run(int argc, char** argv) -> int;
|
||||||
|
|
||||||
} // namespace cargoxx::cli
|
} // namespace cargoxx::cli
|
||||||
|
|||||||
31
src/cli/cmd_linkdb_add.cpp
Normal file
31
src/cli/cmd_linkdb_add.cpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
module cargoxx.cli;
|
||||||
|
|
||||||
|
import std;
|
||||||
|
import cargoxx.linkdb;
|
||||||
|
import cargoxx.util;
|
||||||
|
|
||||||
|
namespace cargoxx::cli {
|
||||||
|
|
||||||
|
auto cmd_linkdb_add(const std::string& package, const std::string& version_range,
|
||||||
|
const std::string& find_package_text,
|
||||||
|
std::vector<std::string> targets,
|
||||||
|
const std::string& nixpkgs_attr,
|
||||||
|
std::optional<std::filesystem::path> overlay_path)
|
||||||
|
-> util::Result<void> {
|
||||||
|
auto db = linkdb::Database::open(std::move(overlay_path));
|
||||||
|
if (!db) {
|
||||||
|
return std::unexpected(db.error());
|
||||||
|
}
|
||||||
|
if (auto r = db->evict_auto_recipes(package); !r) {
|
||||||
|
return std::unexpected(r.error());
|
||||||
|
}
|
||||||
|
linkdb::Recipe r{
|
||||||
|
.nixpkgs_attr = nixpkgs_attr,
|
||||||
|
.find_package = find_package_text,
|
||||||
|
.targets = std::move(targets),
|
||||||
|
.source = "manual",
|
||||||
|
};
|
||||||
|
return db->add_manual(package, version_range, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cargoxx::cli
|
||||||
@@ -58,6 +58,28 @@ auto run(int argc, char** argv) -> int {
|
|||||||
std::string remove_name;
|
std::string remove_name;
|
||||||
remove_cmd->add_option("name", remove_name, "Package name to remove")->required();
|
remove_cmd->add_option("name", remove_name, "Package name to remove")->required();
|
||||||
|
|
||||||
|
auto* linkdb_cmd =
|
||||||
|
app.add_subcommand("linkdb", "Manage the link database");
|
||||||
|
linkdb_cmd->require_subcommand(1);
|
||||||
|
auto* linkdb_add_cmd =
|
||||||
|
linkdb_cmd->add_subcommand("add", "Insert a manual recipe");
|
||||||
|
std::string ldb_package;
|
||||||
|
std::string ldb_version = "*";
|
||||||
|
std::string ldb_find_package;
|
||||||
|
std::string ldb_targets;
|
||||||
|
std::string ldb_nixpkgs_attr;
|
||||||
|
linkdb_add_cmd->add_option("package", ldb_package, "Package name")->required();
|
||||||
|
linkdb_add_cmd->add_option("--version", ldb_version, "Version range (default: *)");
|
||||||
|
linkdb_add_cmd->add_option("--find-package", ldb_find_package,
|
||||||
|
"Body of the find_package(...) call (e.g. \"fmt CONFIG REQUIRED\")")
|
||||||
|
->required();
|
||||||
|
linkdb_add_cmd->add_option("--targets", ldb_targets,
|
||||||
|
"Comma-separated CMake targets (e.g. fmt::fmt)")
|
||||||
|
->required();
|
||||||
|
linkdb_add_cmd->add_option("--nixpkgs-attr", ldb_nixpkgs_attr,
|
||||||
|
"nixpkgs attribute name (e.g. fmt_10)")
|
||||||
|
->required();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
app.parse(argc, argv);
|
app.parse(argc, argv);
|
||||||
} catch (const CLI::ParseError& e) {
|
} catch (const CLI::ParseError& e) {
|
||||||
@@ -175,6 +197,31 @@ auto run(int argc, char** argv) -> int {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*linkdb_add_cmd) {
|
||||||
|
std::vector<std::string> targets;
|
||||||
|
std::size_t pos = 0;
|
||||||
|
while (pos <= ldb_targets.size()) {
|
||||||
|
auto comma = ldb_targets.find(',', pos);
|
||||||
|
auto piece = ldb_targets.substr(
|
||||||
|
pos, comma == std::string::npos ? ldb_targets.size() - pos : comma - pos);
|
||||||
|
if (!piece.empty()) {
|
||||||
|
targets.push_back(std::move(piece));
|
||||||
|
}
|
||||||
|
if (comma == std::string::npos) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos = comma + 1;
|
||||||
|
}
|
||||||
|
auto r = cmd_linkdb_add(ldb_package, ldb_version, ldb_find_package,
|
||||||
|
std::move(targets), ldb_nixpkgs_attr);
|
||||||
|
if (!r) {
|
||||||
|
std::cerr << util::format(r.error());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::cout << std::format(" Added manual recipe for {}\n", ldb_package);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ auto emit_library(const layout::Target& lib, const std::string& package_name,
|
|||||||
out += std::format("add_library({} STATIC)\n", package_name);
|
out += std::format("add_library({} STATIC)\n", package_name);
|
||||||
out += std::format("target_sources({}\n", package_name);
|
out += std::format("target_sources({}\n", package_name);
|
||||||
out += " PUBLIC\n";
|
out += " PUBLIC\n";
|
||||||
out += " FILE_SET CXX_MODULES FILES\n";
|
out += " FILE_SET CXX_MODULES BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/.. FILES\n";
|
||||||
for (const auto& m : lib.module_units) {
|
for (const auto& m : lib.module_units) {
|
||||||
out += std::format(" {}\n", rel_to_build(m, project_root));
|
out += std::format(" {}\n", rel_to_build(m, project_root));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,25 +59,24 @@ auto find_lockfile_ref(const lockfile::Lockfile& lock, const std::string& name,
|
|||||||
|
|
||||||
auto build_bindings(const GenerateInputs& in) -> std::vector<DepBinding> {
|
auto build_bindings(const GenerateInputs& in) -> std::vector<DepBinding> {
|
||||||
std::vector<DepBinding> out;
|
std::vector<DepBinding> out;
|
||||||
out.reserve(in.manifest.dependencies.size());
|
out.reserve(in.manifest.dependencies.size() + in.manifest.dev_dependencies.size());
|
||||||
for (std::size_t i = 0; i < in.manifest.dependencies.size(); ++i) {
|
auto push = [&](const manifest::Dependency& dep, const linkdb::Recipe& rec) {
|
||||||
const auto& dep = in.manifest.dependencies[i];
|
|
||||||
const auto& rec = in.recipes[i];
|
|
||||||
auto ref = find_lockfile_ref(in.lock, dep.name, dep.version_spec);
|
auto ref = find_lockfile_ref(in.lock, dep.name, dep.version_spec);
|
||||||
// For pinned deps the lockfile's nixpkgs_attr is authoritative
|
|
||||||
// (it came from devbox's attr_paths for this specific rev). The
|
|
||||||
// curated recipe's attr only applies to nixos-unstable, so it's
|
|
||||||
// wrong when the dep pulls from a different rev.
|
|
||||||
std::string attr = (ref.attr && !ref.attr->empty()) ? *ref.attr
|
std::string attr = (ref.attr && !ref.attr->empty()) ? *ref.attr
|
||||||
: rec.nixpkgs_attr;
|
: rec.nixpkgs_attr;
|
||||||
DepBinding b{
|
out.push_back(DepBinding{
|
||||||
.name = dep.name,
|
.name = dep.name,
|
||||||
.version = dep.version_spec,
|
.version = dep.version_spec,
|
||||||
.nixpkgs_attr = std::move(attr),
|
.nixpkgs_attr = std::move(attr),
|
||||||
.sanitized = sanitize_input_attr(dep.name, dep.version_spec),
|
.sanitized = sanitize_input_attr(dep.name, dep.version_spec),
|
||||||
.rev = std::move(ref.rev),
|
.rev = std::move(ref.rev),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
out.push_back(std::move(b));
|
for (std::size_t i = 0; i < in.manifest.dependencies.size(); ++i) {
|
||||||
|
push(in.manifest.dependencies[i], in.recipes[i]);
|
||||||
|
}
|
||||||
|
for (std::size_t i = 0; i < in.manifest.dev_dependencies.size(); ++i) {
|
||||||
|
push(in.manifest.dev_dependencies[i], in.dev_recipes[i]);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ TEST_CASE("cmake_lists for a library-only project", "[codegen][cmake]") {
|
|||||||
|
|
||||||
auto out = cmake_lists(in);
|
auto out = cmake_lists(in);
|
||||||
REQUIRE(out.find("add_library(widget STATIC)") != std::string::npos);
|
REQUIRE(out.find("add_library(widget STATIC)") != std::string::npos);
|
||||||
REQUIRE(out.find("FILE_SET CXX_MODULES FILES") != std::string::npos);
|
REQUIRE(out.find("FILE_SET CXX_MODULES") != std::string::npos);
|
||||||
REQUIRE(out.find("../src/lib.cppm") != std::string::npos);
|
REQUIRE(out.find("../src/lib.cppm") != std::string::npos);
|
||||||
REQUIRE(out.find("add_executable") == std::string::npos);
|
REQUIRE(out.find("add_executable") == std::string::npos);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user