fix: review fixes + feat: imports, assertions, merge engine, per-package overrides
Review fixes (8 blocking issues):
- Extract ParseError to shared error.hpp (ODR fix)
- Remove dead package.cpp/package.hpp + tomlplusplus dep
- Safe parse_int() helper replacing crash-prone std::stoi
- consume_string() now accepts bare numbers and idents
- line_at() fixed for post-EOF line numbers
- Subcommand validation before file read in CLI
- KwService/KwAssert/KwImport added to consume_ident()
- root partition promoted to first-class BootBlock field
New features:
- Imports: imports = [...] with recursive merge resolution
- Assertions: assert { "msg" : field op value } in both parsers
- Merge engine: resolve_package() with features/config merge + force support
- Per-package overrides: /kappa/system/builds/<name>.kap
- .gitignore: added vcpkg_installed/ and kappa binary
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "kappa/dsl/ast.hpp"
|
||||
#include "kappa/dsl/system.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
namespace kappa::config {
|
||||
|
||||
struct ResolvedPackage {
|
||||
dsl::PackageDef original;
|
||||
std::unordered_map<std::string, dsl::FeatureDef> features;
|
||||
std::unordered_map<std::string, std::string> config;
|
||||
};
|
||||
|
||||
ResolvedPackage resolve_package(
|
||||
const dsl::PackageDef& pkg,
|
||||
const dsl::SystemBlock& system,
|
||||
const std::optional<dsl::PackageRef>& overrides);
|
||||
|
||||
std::unordered_map<std::string, std::string> resolve_config(
|
||||
const dsl::PackageDef& pkg,
|
||||
const dsl::SystemBlock& system,
|
||||
const std::optional<dsl::PackageRef>& overrides);
|
||||
|
||||
} // namespace kappa::config
|
||||
@@ -52,6 +52,13 @@ struct ServiceInit {
|
||||
std::unordered_map<std::string, std::string> env;
|
||||
};
|
||||
|
||||
struct Assertion {
|
||||
std::string message;
|
||||
std::string field;
|
||||
std::string op; // "==" or "!="
|
||||
std::string value;
|
||||
};
|
||||
|
||||
struct PackageDef {
|
||||
std::string name;
|
||||
std::string version;
|
||||
@@ -65,6 +72,7 @@ struct PackageDef {
|
||||
std::vector<Patch> patches;
|
||||
std::vector<EnvEntry> env_entries;
|
||||
std::unordered_map<std::string, ServiceInit> service;
|
||||
std::vector<Assertion> assertions;
|
||||
std::unordered_set<std::string> const_keys;
|
||||
Phase prepare;
|
||||
Phase build;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <format>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace kappa::dsl {
|
||||
|
||||
class ParseError : public std::runtime_error {
|
||||
public:
|
||||
ParseError(int line, int col, const std::string& msg)
|
||||
: std::runtime_error(std::format("{}:{}: {}", line, col, msg)) {}
|
||||
};
|
||||
|
||||
inline int parse_int(int line, int col, const std::string& lexeme) {
|
||||
try {
|
||||
std::size_t pos = 0;
|
||||
int val = std::stoi(lexeme, &pos);
|
||||
if (pos != lexeme.size()) {
|
||||
throw ParseError(line, col,
|
||||
std::format("expected integer, got '{}'", lexeme));
|
||||
}
|
||||
return val;
|
||||
} catch (const std::invalid_argument&) {
|
||||
throw ParseError(line, col,
|
||||
std::format("expected integer, got '{}'", lexeme));
|
||||
} catch (const std::out_of_range&) {
|
||||
throw ParseError(line, col,
|
||||
std::format("integer out of range: '{}'", lexeme));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace kappa::dsl
|
||||
@@ -34,6 +34,7 @@ struct BootBlock {
|
||||
std::string init;
|
||||
std::string efi;
|
||||
std::string swap;
|
||||
std::string root;
|
||||
std::string bootloader;
|
||||
std::unordered_map<std::string, std::string> params;
|
||||
};
|
||||
@@ -52,13 +53,16 @@ struct ServiceRef {
|
||||
};
|
||||
|
||||
struct SystemConfig {
|
||||
std::vector<std::string> imports;
|
||||
SystemBlock system;
|
||||
std::vector<PackageRef> packages;
|
||||
std::vector<ServiceRef> services;
|
||||
BootBlock boot;
|
||||
std::vector<UserRef> users;
|
||||
std::vector<Assertion> assertions;
|
||||
};
|
||||
|
||||
SystemConfig parse_system_config(std::string_view source);
|
||||
SystemConfig resolve_imports(const SystemConfig& cfg, const std::string& base_dir);
|
||||
|
||||
} // namespace kappa::dsl
|
||||
|
||||
@@ -35,6 +35,8 @@ enum class TokenType {
|
||||
KwPatches,
|
||||
KwEnv,
|
||||
KwService,
|
||||
KwAssert,
|
||||
KwImport,
|
||||
KwPrepare,
|
||||
KwBuild,
|
||||
KwCheck,
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace kappa {
|
||||
|
||||
struct PackageConfig {
|
||||
std::string name;
|
||||
std::string version;
|
||||
std::string description;
|
||||
std::string source_url;
|
||||
std::string source_extension;
|
||||
std::string source_hash;
|
||||
std::vector<std::string> dependencies;
|
||||
std::string build_system;
|
||||
};
|
||||
|
||||
PackageConfig parse_package(const std::string& toml_path);
|
||||
void print_package(std::ostream& os, const PackageConfig& pkg);
|
||||
|
||||
} // namespace kappa
|
||||
Reference in New Issue
Block a user