Compares installed packages against cached indexes to find newer versions. kappa upgrade shows available upgrades and updates the system config with new version constraints. --dry-run shows what would change without applying.
This commit is contained in:
+106
-1
@@ -58,6 +58,7 @@ Subcommands:
|
||||
--features "key=on,key2=off" Set feature flags
|
||||
--config "key=val,key2=val2" Set config values
|
||||
remove <pkg> Remove a package from system config
|
||||
upgrade Check indexes for newer versions of installed packages
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message
|
||||
@@ -226,7 +227,8 @@ int main(int argc, char* argv[]) {
|
||||
|| (subcommand == "index")
|
||||
|| (subcommand == "search")
|
||||
|| (subcommand == "add")
|
||||
|| (subcommand == "remove");
|
||||
|| (subcommand == "remove")
|
||||
|| (subcommand == "upgrade");
|
||||
|
||||
if (!valid_subcommand) {
|
||||
std::cerr << "error: unknown subcommand '" << subcommand << "'\n\n";
|
||||
@@ -540,6 +542,109 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (subcommand == "upgrade") {
|
||||
auto installed = install::read_installed();
|
||||
if (installed.empty()) {
|
||||
std::cout << "no packages installed\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Build a map of latest versions from cached indexes
|
||||
std::unordered_map<std::string, std::string> latest;
|
||||
auto idx_dir = paths::cache_dir() / "indexes";
|
||||
std::error_code ec;
|
||||
if (std::filesystem::exists(idx_dir)) {
|
||||
for (auto& entry : std::filesystem::directory_iterator(idx_dir, ec)) {
|
||||
if (ec) break;
|
||||
if (entry.path().extension() != ".kap") continue;
|
||||
std::ifstream in(entry.path());
|
||||
if (!in) continue;
|
||||
std::ostringstream buf;
|
||||
buf << in.rdbuf();
|
||||
try {
|
||||
auto idx = dsl::parse_index(buf.str());
|
||||
for (auto& pkg : idx.packages) {
|
||||
auto it = latest.find(pkg.name);
|
||||
if (it == latest.end() || pkg.version > it->second) {
|
||||
latest[pkg.name] = pkg.version;
|
||||
}
|
||||
}
|
||||
} catch (...) { continue; }
|
||||
}
|
||||
}
|
||||
|
||||
if (latest.empty()) {
|
||||
std::cout << "no cached indexes — run kappa fetch-package <name> first\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> upgrades;
|
||||
for (auto& e : installed) {
|
||||
auto it = latest.find(e.name);
|
||||
if (it != latest.end() && it->second > e.version) {
|
||||
upgrades.emplace_back(e.name, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
if (upgrades.empty()) {
|
||||
std::cout << "all " << installed.size() << " packages up to date\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cout << upgrades.size() << " upgrade(s) available:\n";
|
||||
for (auto& [name, ver] : upgrades) {
|
||||
// Find old version
|
||||
std::string old_ver;
|
||||
for (auto& e : installed) {
|
||||
if (e.name == name) { old_ver = e.version; break; }
|
||||
}
|
||||
std::cout << " " << name << " " << old_ver << " → " << ver << "\n";
|
||||
}
|
||||
|
||||
if (dry_run) {
|
||||
std::cout << "run kappa add <pkg> <version> for each to apply\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Apply: update system config with new versions
|
||||
auto config_path = std::filesystem::path(paths::system_dir()) / "config.kap";
|
||||
dsl::SystemConfig cfg;
|
||||
if (std::filesystem::exists(config_path)) {
|
||||
auto src = read_file(config_path.c_str());
|
||||
try {
|
||||
cfg = dsl::parse_system_config(src);
|
||||
} catch (...) { cfg = {}; }
|
||||
}
|
||||
|
||||
for (auto& [name, ver] : upgrades) {
|
||||
bool found = false;
|
||||
for (auto& p : cfg.packages) {
|
||||
if (p.name == name) {
|
||||
p.version = ver;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
dsl::PackageRef pref;
|
||||
pref.name = name;
|
||||
pref.version = ver;
|
||||
cfg.packages.push_back(std::move(pref));
|
||||
}
|
||||
}
|
||||
|
||||
std::filesystem::create_directories(paths::system_dir(), ec);
|
||||
std::ofstream out(config_path);
|
||||
if (!out) {
|
||||
std::cerr << "error: cannot write config\n";
|
||||
return 1;
|
||||
}
|
||||
tools::format_config(out, cfg);
|
||||
|
||||
std::cout << "config updated — run kappa rebuild to apply\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (subcommand == "fetch-package") {
|
||||
if (file_arg == nullptr) {
|
||||
std::cerr << "error: no package name specified\n";
|
||||
|
||||
Reference in New Issue
Block a user