[M1] add manifest::write
This commit is contained in:
@@ -9,11 +9,15 @@ struct Dependency {
|
||||
std::string name;
|
||||
std::string version_spec;
|
||||
std::vector<std::string> components;
|
||||
|
||||
bool operator==(const Dependency&) const = default;
|
||||
};
|
||||
|
||||
struct BuildSettings {
|
||||
bool warnings_as_errors = false;
|
||||
std::vector<std::string> sanitizers;
|
||||
|
||||
bool operator==(const BuildSettings&) const = default;
|
||||
};
|
||||
|
||||
enum class Edition { Cpp20, Cpp23, Cpp26 };
|
||||
@@ -24,14 +28,19 @@ struct Package {
|
||||
Edition edition = Edition::Cpp23;
|
||||
std::vector<std::string> authors;
|
||||
std::optional<std::string> license;
|
||||
|
||||
bool operator==(const Package&) const = default;
|
||||
};
|
||||
|
||||
struct Manifest {
|
||||
Package package;
|
||||
std::vector<Dependency> dependencies;
|
||||
BuildSettings build;
|
||||
|
||||
bool operator==(const Manifest&) const = default;
|
||||
};
|
||||
|
||||
auto parse(const std::filesystem::path& path) -> util::Result<Manifest>;
|
||||
auto write(const Manifest& m, const std::filesystem::path& path) -> util::Result<void>;
|
||||
|
||||
} // namespace cargoxx::manifest
|
||||
|
||||
103
src/manifest/writer.cpp
Normal file
103
src/manifest/writer.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
module;
|
||||
|
||||
#include <toml.hpp>
|
||||
|
||||
module cargoxx.manifest;
|
||||
|
||||
import std;
|
||||
import cargoxx.util;
|
||||
|
||||
namespace cargoxx::manifest {
|
||||
|
||||
namespace {
|
||||
|
||||
auto edition_to_string(Edition e) -> std::string_view {
|
||||
switch (e) {
|
||||
case Edition::Cpp20:
|
||||
return "cpp20";
|
||||
case Edition::Cpp23:
|
||||
return "cpp23";
|
||||
case Edition::Cpp26:
|
||||
return "cpp26";
|
||||
}
|
||||
return "cpp23";
|
||||
}
|
||||
|
||||
auto to_array(const std::vector<std::string>& xs) -> toml::array {
|
||||
toml::array out;
|
||||
for (const auto& x : xs) {
|
||||
out.push_back(x);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
auto build_table(const Manifest& m) -> toml::table {
|
||||
toml::table root;
|
||||
|
||||
toml::table package;
|
||||
package.insert_or_assign("name", m.package.name);
|
||||
package.insert_or_assign("version", m.package.version);
|
||||
package.insert_or_assign("edition", std::string{edition_to_string(m.package.edition)});
|
||||
if (!m.package.authors.empty()) {
|
||||
package.insert_or_assign("authors", to_array(m.package.authors));
|
||||
}
|
||||
if (m.package.license) {
|
||||
package.insert_or_assign("license", *m.package.license);
|
||||
}
|
||||
root.insert_or_assign("package", std::move(package));
|
||||
|
||||
if (!m.dependencies.empty()) {
|
||||
toml::table deps;
|
||||
for (const auto& dep : m.dependencies) {
|
||||
if (dep.components.empty()) {
|
||||
deps.insert_or_assign(dep.name, dep.version_spec);
|
||||
} else {
|
||||
toml::table dep_tbl;
|
||||
dep_tbl.insert_or_assign("version", dep.version_spec);
|
||||
dep_tbl.insert_or_assign("components", to_array(dep.components));
|
||||
dep_tbl.is_inline(true);
|
||||
deps.insert_or_assign(dep.name, std::move(dep_tbl));
|
||||
}
|
||||
}
|
||||
root.insert_or_assign("dependencies", std::move(deps));
|
||||
}
|
||||
|
||||
if (m.build.warnings_as_errors || !m.build.sanitizers.empty()) {
|
||||
toml::table build;
|
||||
if (m.build.warnings_as_errors) {
|
||||
build.insert_or_assign("warnings_as_errors", true);
|
||||
}
|
||||
if (!m.build.sanitizers.empty()) {
|
||||
build.insert_or_assign("sanitizers", to_array(m.build.sanitizers));
|
||||
}
|
||||
root.insert_or_assign("build", std::move(build));
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
auto write(const Manifest& m, const std::filesystem::path& path) -> util::Result<void> {
|
||||
auto tbl = build_table(m);
|
||||
|
||||
std::ofstream out{path};
|
||||
if (!out) {
|
||||
return std::unexpected(util::Error{
|
||||
util::ErrorCode::Internal,
|
||||
std::format("cannot open manifest for writing: {}", path.string()),
|
||||
"", path, std::nullopt});
|
||||
}
|
||||
|
||||
out << tbl << '\n';
|
||||
if (!out) {
|
||||
return std::unexpected(util::Error{
|
||||
util::ErrorCode::Internal,
|
||||
std::format("write failed: {}", path.string()),
|
||||
"", path, std::nullopt});
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace cargoxx::manifest
|
||||
Reference in New Issue
Block a user