From 9a010b9201bf291fa668de1b625c3d6a24b31d94 Mon Sep 17 00:00:00 2001 From: Gaspard Kirira Date: Sat, 21 Mar 2026 14:58:37 +0300 Subject: [PATCH] refactor(cli): simplify install output + introduce cache command + improve UX --- .../{InstallCommand.hpp => CacheCommand.hpp} | 8 +- src/CLI.cpp | 119 ++++++++--------- .../{InstallCommand.cpp => CacheCommand.cpp} | 90 ++++++------- src/commands/DepsCommand.cpp | 122 ++++++++++-------- src/commands/Dispatch.cpp | 18 ++- src/commands/RemoveCommand.cpp | 6 +- 6 files changed, 191 insertions(+), 172 deletions(-) rename include/vix/cli/commands/{InstallCommand.hpp => CacheCommand.hpp} (73%) rename src/commands/{InstallCommand.cpp => CacheCommand.cpp} (91%) diff --git a/include/vix/cli/commands/InstallCommand.hpp b/include/vix/cli/commands/CacheCommand.hpp similarity index 73% rename from include/vix/cli/commands/InstallCommand.hpp rename to include/vix/cli/commands/CacheCommand.hpp index e18d4eb..8be10b7 100644 --- a/include/vix/cli/commands/InstallCommand.hpp +++ b/include/vix/cli/commands/CacheCommand.hpp @@ -1,6 +1,6 @@ /** * - * @file InstallCommand.hpp + * @file CacheCommand.hpp * @author Gaspard Kirira * * Copyright 2025, Gaspard Kirira. All rights reserved. @@ -10,13 +10,13 @@ * * Vix.cpp */ -#ifndef VIX_INSTALL_COMMAND_HPP -#define VIX_INSTALL_COMMAND_HPP +#ifndef VIX_CACHE_COMMAND_HPP +#define VIX_CACHE_COMMAND_HPP #include #include -namespace vix::commands::InstallCommand +namespace vix::commands::CacheCommand { int run(const std::vector &args); int help(); diff --git a/src/CLI.cpp b/src/CLI.cpp index 96f6be7..892e12d 100644 --- a/src/CLI.cpp +++ b/src/CLI.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -150,8 +150,8 @@ namespace vix { return commands::TestsCommand::run(args); }; commands_["repl"] = [](auto args) { return commands::ReplCommand::run(args); }; - commands_["install"] = [](auto args) - { return commands::InstallCommand::run(args); }; + commands_["cache"] = [](auto args) + { return commands::CacheCommand::run(args); }; commands_["-h"] = [this](auto args) { return help(args); }; @@ -344,8 +344,8 @@ namespace vix return commands::TestsCommand::help(); if (cmd == "repl") return commands::ReplCommand::help(); - if (cmd == "install") - return commands::InstallCommand::help(); + if (cmd == "cache") + return commands::CacheCommand::help(); if (cmd == "registry") return commands::RegistryCommand::help(); if (cmd == "registry") @@ -362,7 +362,7 @@ namespace vix return commands::StoreCommand::help(); if (cmd == "publish") return commands::PublishCommand::help(); - if (cmd == "deps") + if (cmd == "deps" || cmd == "install") return commands::DepsCommand::help(); if (cmd == "modules") return commands::ModulesCommand::help(); @@ -393,87 +393,78 @@ namespace vix out << indent(2) << "Docs: " << link(url) << "\n"; }; - out << "Vix.cpp - Modern C++ backend runtime\n"; + out << "Vix.cpp\n"; + out << "Fast. Simple. Built for real apps.\n"; out << "Version: " << VIX_CLI_VERSION << "\n\n"; - out << indent(1) << "Usage:\n"; - out << indent(2) << "vix [options] [args...]\n"; - out << indent(2) << "vix help \n\n"; - - out << indent(1) << "Quick start:\n"; + out << indent(1) << "Start in seconds:\n"; out << indent(2) << "vix new api\n"; - out << indent(2) << "cd api && vix dev\n"; - out << indent(2) << "vix pack --version 1.0.0 && vix verify\n"; - out << indent(2) << "vix doctor --online\n"; - out << indent(2) << "vix upgrade\n\n"; + out << indent(2) << "cd api\n"; + out << indent(2) << "vix install\n"; + out << indent(2) << "vix dev\n\n"; + + out << indent(1) << "Core workflow:\n"; + out << indent(2) << "add Add a dependency\n"; + out << indent(2) << "install Install project dependencies\n"; + out << indent(2) << "run Run your app\n"; + out << indent(2) << "deploy Deploy your app (coming soon)\n\n"; out << indent(1) << "Commands:\n\n"; // Project out << indent(2) << "Project:\n"; docs("https://vixcpp.com/docs/modules/cli/new"); - out << indent(3) << "new Create a new Vix project in ./\n"; - out << indent(3) << "build [name] Configure + build (root project or app)\n"; - out << indent(3) << "run [name] [--args] Build (if needed) then run\n"; - out << indent(3) << "dev [name] Dev mode (watch, rebuild, reload)\n"; - out << indent(3) << "check [path] Validate a project or compile a single .cpp (no execution)\n"; - out << indent(3) << "tests [path] Run project tests (alias of check --tests)\n"; - out << indent(3) << "repl Start interactive Vix REPL\n"; - out << indent(3) << "modules Opt-in module system (init/add/check)\n\n"; + out << indent(3) << "new Create a new project\n"; + out << indent(3) << "dev Start dev server (hot reload)\n"; + out << indent(3) << "run Build and run\n"; + out << indent(3) << "build Build project\n"; + out << indent(3) << "check Validate build or file\n"; + out << indent(3) << "tests Run tests\n"; + out << indent(3) << "repl Interactive REPL\n\n"; // Registry - out << indent(2) << "Registry:\n"; + out << indent(2) << "Dependencies:\n"; docs("https://vixcpp.com/docs/modules/cli/search"); - out << indent(3) << "registry Sync/search registry index (git-based)\n"; - out << indent(3) << "registry unpublish Remove a package from the registry (opens PR, destructive)\n"; - out << indent(3) << "search Search packages in local registry index (offline)\n"; - out << indent(3) << "add @ Add a dependency from registry (pins commit)\n"; - out << indent(3) << "remove Remove a dependency from vix.lock\n"; - out << indent(3) << "list List project dependencies from vix.lock\n"; - out << indent(3) << "store Manage local store cache (gc/path)\n"; - out << indent(3) << "publish Publish current repo to registry (JSON + PR)\n"; - out << indent(3) << "deps Install deps from vix.lock (generate .vix/vix_deps.cmake)\n\n"; - - // Packaging & security - out << indent(2) << "Packaging & security:\n"; + out << indent(3) << "add @ Add dependency\n"; + out << indent(3) << "install Install dependencies\n"; + out << indent(3) << "deps Alias of install\n"; + out << indent(3) << "remove Remove dependency\n"; + out << indent(3) << "list List dependencies\n\n"; + + // Packaging + out << indent(2) << "Build & share:\n"; docs("https://vixcpp.com/docs/modules/cli/pack"); - out << indent(3) << "pack [options] Create dist/@ (+ optional .vixpkg)\n"; - out << indent(3) << "verify [options] Verify dist/@ or a .vixpkg artifact\n"; - out << indent(3) << "install [options] Install dist/@ or a .vixpkg into the local store\n\n"; - - // Database - out << indent(2) << "Database:\n"; - docs("https://vixcpp.com/docs/modules/cli/orm"); - out << indent(3) << "orm Migrations/status/rollback\n\n"; + out << indent(3) << "pack Build distributable package\n"; + out << indent(3) << "verify Verify package integrity\n"; + out << indent(3) << "cache Store package locally\n\n"; - // Network - out << indent(2) << "Network:\n"; - docs("https://vixcpp.com/docs/modules/cli/p2p"); - out << indent(3) << "p2p [options] Run P2P node (tcp + discovery + bootstrap)\n\n"; + // Advanced + out << indent(2) << "Advanced:\n"; + out << indent(3) << "registry Sync/search packages\n"; + out << indent(3) << "store Manage local cache\n"; + out << indent(3) << "orm Database migrations\n"; + out << indent(3) << "p2p Run P2P node\n\n"; // Maintenance - out << indent(2) << "Maintenance:\n"; - docs("https://vixcpp.com/docs/modules/cli/doctor"); - out << indent(3) << "doctor [options] Check environment and install health\n"; - out << indent(3) << "upgrade [options] Upgrade Vix binary (writes install.json)\n"; - out << indent(3) << "uninstall [options] Remove Vix CLI (use --all, --purge)\n\n"; + out << indent(2) << "System:\n"; + out << indent(3) << "doctor Check environment\n"; + out << indent(3) << "upgrade Update Vix\n"; + out << indent(3) << "uninstall Remove Vix\n\n"; // Info - out << indent(2) << "Info:\n"; - docs("https://vixcpp.com/docs/modules/cli/index"); - out << indent(3) << "help [command] Show help for CLI or a specific command\n"; - out << indent(3) << "version Show version information\n\n"; + out << indent(2) << "Help:\n"; + out << indent(3) << "help [command] Show command help\n"; + out << indent(3) << "version Show version\n\n"; out << indent(1) << "Global options:\n"; - out << indent(2) << "--verbose Enable debug logs (same as: --log-level debug)\n"; - out << indent(2) << "-q, --quiet Only show warnings and errors\n"; - out << indent(2) << "--log-level trace|debug|info|warn|error|critical\n"; - out << indent(2) << "-h, --help Show CLI help (or: vix help)\n"; - out << indent(2) << "-v, --version Show version info\n\n"; + out << indent(2) << "--verbose Debug logs\n"; + out << indent(2) << "-q, --quiet Only warnings/errors\n"; + out << indent(2) << "--log-level trace|debug|info|warn|error|critical\n"; + out << indent(2) << "-h, --help Show help\n"; + out << indent(2) << "-v, --version Show version\n\n"; out << indent(1) << "Docs: " << link("https://vixcpp.com/docs") << "\n"; out << indent(1) << "Registry: " << link("https://vixcpp.com/registry") << "\n"; - out << indent(1) << "Bugs: " << link("https://github.com/vixcpp/vix/issues") << "\n"; out << indent(1) << "GitHub: " << link("https://github.com/vixcpp/vix") << "\n\n"; return 0; diff --git a/src/commands/InstallCommand.cpp b/src/commands/CacheCommand.cpp similarity index 91% rename from src/commands/InstallCommand.cpp rename to src/commands/CacheCommand.cpp index 3545e4d..3b4be26 100644 --- a/src/commands/InstallCommand.cpp +++ b/src/commands/CacheCommand.cpp @@ -1,6 +1,6 @@ /** * - * @file InstallCommand.cpp + * @file CacheCommand.cpp * @author Gaspard Kirira * * Copyright 2025, Gaspard Kirira. All rights reserved. @@ -12,17 +12,17 @@ * */ // ============================================================================ -// InstallCommand.cpp — Install a Vix package into a local store (Vix.cpp CLI) +// CacheCommand.cpp — Cache a Vix package into a local store (Vix.cpp CLI) // ---------------------------------------------------------------------------- // Features: // - --path // - --store (override store root) -// - --force (overwrite installed package) +// - --force (overwrite cached package) // - --no-verify (skip verification; NOT recommended) // - --require-signature, --pubkey (signature verification) // - extraction of .vixpkg (POSIX: unzip) // - verifies: manifest minimal + payload digest + checksums + minisign signature -// - atomic install: copy to tmp dir then rename() into final destination +// - atomic cache: copy to tmp dir then rename() into final destination // // Default store (POSIX): // 1) $VIX_STORE if set @@ -31,12 +31,12 @@ // store path becomes: /packs///-/ // // Usage: -// vix install --path ./dist/blog@1.0.0.vixpkg -// vix install --path ./dist/blog@1.0.0 --force -// vix install --path ./blog@1.0.0.vixpkg --require-signature --pubkey ./keys/vix-pack.pub +// vix cache --path ./dist/blog@1.0.0.vixpkg +// vix cache --path ./dist/blog@1.0.0 --force +// vix cache --path ./blog@1.0.0.vixpkg --require-signature --pubkey ./keys/vix-pack.pub // ============================================================================ -#include +#include #include #include #include @@ -314,7 +314,7 @@ namespace return std::nullopt; const int pid = static_cast(::getpid()); - const fs::path tmp = dir / (".vix_install_tmp_" + std::to_string(pid) + ".txt"); + const fs::path tmp = dir / (".vix_cache_tmp_" + std::to_string(pid) + ".txt"); write_text_file(tmp, data); @@ -357,7 +357,7 @@ namespace return std::nullopt; const int pid = static_cast(::getpid()); - fs::path tmp = fs::temp_directory_path() / ("vix_install_" + std::to_string(pid)); + fs::path tmp = fs::temp_directory_path() / ("vix_cache_" + std::to_string(pid)); std::error_code ec; fs::remove_all(tmp, ec); @@ -784,8 +784,8 @@ namespace } } - // Atomic install (copy -> rename) - void atomic_install_folder( + // Atomic cache (copy -> rename) + void atomic_cache_folder( const fs::path &packRoot, const fs::path &dstFinal, bool force, @@ -795,7 +795,7 @@ namespace if (has_dir(dstFinal) || has_file(dstFinal)) { if (!force) - throw std::runtime_error("Package already installed: " + dstFinal.string() + " (use --force)"); + throw std::runtime_error("Package already cached: " + dstFinal.string() + " (use --force)"); std::error_code ec; fs::remove_all(dstFinal, ec); if (ec) @@ -936,7 +936,7 @@ namespace // If user didn't provide --path, try a sane default: // - if ./dist exists, pick latest dist/* by manifest.json mtime? (optional) // For now keep strict: require --path. - throw std::runtime_error("Missing --path. Try: vix install --path "); + throw std::runtime_error("Missing --path. Try: vix cache --path "); } // Extract package identity from manifest (name/version/os/arch) @@ -993,7 +993,7 @@ namespace } // namespace -namespace vix::commands::InstallCommand +namespace vix::commands::CacheCommand { int run(const std::vector &args) { @@ -1005,8 +1005,8 @@ namespace vix::commands::InstallCommand } catch (const std::exception &ex) { - vix::cli::style::error(std::string("install: ") + ex.what()); - vix::cli::style::hint("Try: vix install --help"); + vix::cli::style::error(std::string("cache: ") + ex.what()); + vix::cli::style::hint("Try: vix cache --help"); return 1; } @@ -1020,7 +1020,7 @@ namespace vix::commands::InstallCommand catch (const std::exception &ex) { vix::cli::style::error(ex.what()); - vix::cli::style::hint("Example: vix install --path ./dist/blog@1.0.0.vixpkg"); + vix::cli::style::hint("Example: vix cache --path ./dist/blog@1.0.0.vixpkg"); return {}; } }(); @@ -1028,7 +1028,7 @@ namespace vix::commands::InstallCommand if (input.empty()) return 1; - vix::cli::style::section_title(std::cout, "vix install"); + vix::cli::style::section_title(std::cout, "vix cache"); // resolve package root (folder or extracted temp) std::optional tmp; @@ -1141,28 +1141,24 @@ namespace vix::commands::InstallCommand vix::cli::style::info("Target store:"); vix::cli::style::step(storeRoot.string()); - vix::cli::style::info("Installing:"); + vix::cli::style::info("Caching:"); vix::cli::style::step(pkg.name + "@" + pkg.version + " (" + pkg.abi_tag() + ")"); vix::cli::style::step(dstFinal.string()); try { - // atomic install: copy -> rename - // NOTE: if input is a folder inside dist/, and store is elsewhere, - // we still do copy into storeRoot and then atomic rename within same parent. - // The "atomic" part is for finalization of the install. - atomic_install_folder(packRoot, dstFinal, opt.force, opt.verbose); + atomic_cache_folder(packRoot, dstFinal, opt.force, opt.verbose); } catch (const std::exception &ex) { - vix::cli::style::error(std::string("install failed: ") + ex.what()); + vix::cli::style::error(std::string("cache failed: ") + ex.what()); cleanup_temp_dir(tmp); return 1; } cleanup_temp_dir(tmp); - vix::cli::style::success("Package installed:"); + vix::cli::style::success("Package cached:"); vix::cli::style::step(dstFinal.string()); vix::cli::style::hint("Next: vix get " + pkg.name + "@" + pkg.version + " --out ./ (coming soon)"); @@ -1174,31 +1170,37 @@ namespace vix::commands::InstallCommand std::ostream &out = std::cout; out << "Usage:\n"; - out << " vix install --path [options]\n\n"; + out << " vix cache --path [options]\n\n"; - out << "Description:\n"; - out << " Install a Vix package into a local store (cache/store).\n"; - out << " By default, it verifies payload digest, checksums, and signature (if present).\n\n"; + out << "What this does:\n"; + out << " Cache a Vix package locally so it can be reused instantly.\n"; + out << " Ideal before running, sharing, or deploying applications.\n\n"; + + out << "Why it matters:\n"; + out << " • No rebuilds — reuse prebuilt artifacts\n"; + out << " • Safe — integrity and signature verification\n"; + out << " • Fast — optimized local storage\n\n"; out << "Options:\n"; out << " -p, --path Package folder or .vixpkg artifact (required)\n"; - out << " --store Override store root (default: VIX_STORE, XDG_DATA_HOME/vix, ~/.local/share/vix)\n"; - out << " --force Overwrite if already installed\n"; - out << " --no-verify Skip verification (NOT recommended)\n"; - out << " --verbose Print detailed checks and copied files\n"; - out << " --require-signature Fail if signature is missing or cannot be verified\n"; - out << " --pubkey minisign public key (or set VIX_MINISIGN_PUBKEY)\n"; + out << " --store Custom store location\n"; + out << " --force Overwrite if already cached\n"; + out << " --no-verify Skip verification (not recommended)\n"; + out << " --verbose Show detailed operations\n"; + out << " --require-signature Require valid signature\n"; + out << " --pubkey Minisign public key\n"; out << " -h, --help Show this help\n\n"; - out << "Store layout:\n"; - out << " /packs///-/\n\n"; - out << "Examples:\n"; - out << " vix install --path ./dist/blog@1.0.0.vixpkg\n"; - out << " vix install --path ./dist/blog@1.0.0 --force\n"; - out << " vix install --path ./blog@1.0.0.vixpkg --require-signature --pubkey ./keys/vix-pack.pub\n"; + out << " vix cache --path ./dist/blog@1.0.0.vixpkg\n"; + out << " vix cache --path ./dist/blog@1.0.0 --force\n"; + out << " vix cache --path ./blog@1.0.0.vixpkg --require-signature --pubkey ./keys/vix-pack.pub\n\n"; + + out << "Next step:\n"; + out << " Once cached, you'll soon be able to deploy instantly with:\n"; + out << " vix deploy @\n"; return 0; } -} // namespace vix::commands::InstallCommand +} // namespace vix::commands::CacheCommand diff --git a/src/commands/DepsCommand.cpp b/src/commands/DepsCommand.cpp index e1d0f61..e78feed 100644 --- a/src/commands/DepsCommand.cpp +++ b/src/commands/DepsCommand.cpp @@ -313,20 +313,20 @@ namespace vix::commands { vix::cli::util::one_line_spacer(std::cout); - vix::cli::util::ok_line(std::cout, "Dependencies installed"); - vix::cli::util::kv(std::cout, "deps", std::to_string(deps.size())); - vix::cli::util::kv(std::cout, "dir", project_deps_dir().string()); - vix::cli::util::kv(std::cout, "cmake", project_deps_cmake().string()); + vix::cli::util::ok_line(std::cout, "Dependencies ready"); + vix::cli::util::info(std::cout, std::to_string(deps.size()) + " package(s) installed"); + vix::cli::util::info(std::cout, "CMake integration generated"); std::cout << "\n"; - vix::cli::util::warn_line(std::cout, "Next steps (CMake):"); - vix::cli::util::warn_line(std::cout, "If you edit vix.lock, run 'vix deps' again to refresh CMake."); - std::cout << " " << GRAY << "• " << RESET << "Add this to your CMakeLists.txt:\n\n"; + vix::cli::util::warn_line(std::cout, "Next:"); + std::cout << " " << GRAY << "• " << RESET + << "Add this to your " + << CYAN << BOLD << "CMakeLists.txt" << RESET + << ":\n\n"; std::cout << " include(.vix/vix_deps.cmake)\n"; std::cout << " add_executable(app main.cpp)\n"; - // Generate target list: ns::name std::cout << " target_link_libraries(app PRIVATE"; for (const auto &d : deps) std::cout << " " << cmake_alias_target(d.id); @@ -339,12 +339,10 @@ namespace vix::commands { (void)args; - vix::cli::util::section(std::cout, "Deps"); + bool all_cached = true; + bool printed_header = false; const fs::path lp = lock_path(); - vix::cli::util::kv(std::cout, "lock", lp.string()); - vix::cli::util::kv(std::cout, "depsDir", project_deps_dir().string()); - vix::cli::util::kv(std::cout, "cmake", project_deps_cmake().string()); if (!fs::exists(lp)) { @@ -370,10 +368,10 @@ namespace vix::commands return 1; } - const auto depsArr = lock["dependencies"]; + const auto &depsArr = lock["dependencies"]; if (depsArr.empty()) { - vix::cli::util::warn_line(std::cout, "No dependencies in vix.lock"); + vix::cli::util::warn_line(std::cout, "No dependencies to install"); return 0; } @@ -386,17 +384,17 @@ namespace vix::commands { DepResolved dep = resolve_dep_from_lock_entry(d); - vix::cli::util::info_line(std::cout, dep.id + "@" + dep.version); - const bool cached = fs::exists(dep.checkout); - if (cached) - { - vix::cli::util::kv(std::cout, "status", "cached"); - } - else + if (!cached) { - vix::cli::util::kv(std::cout, "status", "fetching"); - vix::cli::util::kv(std::cout, "repo", dep.repo); + all_cached = false; + + if (!printed_header) + { + vix::cli::util::section(std::cout, "Installing dependencies"); + vix::cli::util::one_line_spacer(std::cout); + printed_header = true; + } const int rc = ensure_checkout_present(dep.repo, dep.id, dep.commit); if (rc != 0) @@ -405,11 +403,8 @@ namespace vix::commands vix::cli::util::warn_line(std::cerr, "Check git access, network, or re-add with a valid version."); return rc; } - - vix::cli::util::kv(std::cout, "status", "fetched"); } - // Verify hash if present in lockfile if (!dep.hash.empty()) { const auto actualHashOpt = vix::cli::util::sha256_directory(dep.checkout); @@ -418,16 +413,12 @@ namespace vix::commands if (*actualHashOpt != dep.hash) { vix::cli::util::err_line(std::cerr, "integrity check failed: " + dep.id); - vix::cli::util::err_line(std::cerr, " expected: " + dep.hash); - vix::cli::util::err_line(std::cerr, " actual: " + *actualHashOpt); - vix::cli::util::warn_line(std::cerr, "The checkout in store has been modified or is corrupt."); - vix::cli::util::warn_line(std::cerr, "Try: vix store gc && vix deps"); + vix::cli::util::err_line(std::cerr, "expected: " + dep.hash); + vix::cli::util::err_line(std::cerr, "actual: " + *actualHashOpt); + vix::cli::util::warn_line(std::cerr, "The cached checkout appears modified or corrupt."); + vix::cli::util::warn_line(std::cerr, "Try: vix store gc && vix install"); return 1; } - else - { - vix::cli::util::kv(std::cout, "verify", "ok"); - } } else { @@ -436,26 +427,41 @@ namespace vix::commands } load_dep_manifest(dep); - vix::cli::util::kv(std::cout, "commit", dep.commit); - // Create stable project-local link const fs::path link = project_deps_dir() / sanitize_id_dot(dep.id); ensure_symlink_or_copy_dir(dep.checkout, link); dep.linkDir = link; - // Affiche link seulement si on a vraiment fait quelque chose + resolved.push_back(dep); + if (!cached) - vix::cli::util::kv(std::cout, "link", dep.linkDir.string()); + { + std::cout << " " << CYAN << "•" << RESET << " " + << CYAN << BOLD << dep.id << RESET + << GRAY << "@" << RESET + << YELLOW << BOLD << dep.version << RESET + << " " + << GRAY << "installed" << RESET + << "\n"; + } + } - // Create a stable project-local link: - // .vix/deps/. -> ~/.vix/store/git/./ - ensure_symlink_or_copy_dir(dep.checkout, link); - dep.linkDir = link; - vix::cli::util::kv(std::cout, "link", dep.linkDir.string()); - resolved.push_back(std::move(dep)); + try + { + generate_cmake(resolved); + } + catch (const std::exception &ex) + { + vix::cli::util::err_line(std::cerr, std::string("failed to generate CMake integration: ") + ex.what()); + return 1; + } + + if (all_cached) + { + vix::cli::util::ok_line(std::cout, "Dependencies already up to date"); + return 0; } - generate_cmake(resolved); print_next_steps(resolved); return 0; } @@ -464,17 +470,29 @@ namespace vix::commands { std::cout << "Usage:\n" + << " vix install\n" << " vix deps\n\n" - << "Description:\n" - << " Install dependencies listed in vix.lock.\n" - << " Packages are fetched into ./.vix/deps.\n" - << " Generates ./.vix/vix_deps.cmake.\n\n" + << "What this does:\n" + << " Install project dependencies from vix.lock.\n" + << " Packages are fetched and linked into ./.vix/deps.\n\n" + + << "Why it matters:\n" + << " • One command to set up your project\n" + << " • Reuses cached packages when available\n" + << " • Generates CMake integration automatically\n\n" + + << "Outputs:\n" + << " ./.vix/deps/\n" + << " ./.vix/vix_deps.cmake\n\n" << "Examples:\n" - << " vix add gaspardkirira/tree@0.4.0\n" - << " vix add gaspardkirira/binary_search@0.1.1\n" - << " vix deps\n"; + << " vix add @rix/io\n" + << " vix add @gk/jwt\n" + << " vix install\n\n" + + << "Compatibility:\n" + << " vix deps is an alias of vix install.\n"; return 0; } diff --git a/src/commands/Dispatch.cpp b/src/commands/Dispatch.cpp index 86ca6b7..0b112a1 100644 --- a/src/commands/Dispatch.cpp +++ b/src/commands/Dispatch.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -146,13 +146,13 @@ namespace vix::cli::dispatch { return vix::commands::VerifyCommand::run(a); }, []() { return vix::commands::VerifyCommand::help(); }}); - add({"install", + add({"cache", "Packaging", - "Install a package into the local store", + "Cache a package into the local store", [](const Args &a) - { return vix::commands::InstallCommand::run(a); }, + { return vix::commands::CacheCommand::run(a); }, []() - { return vix::commands::InstallCommand::help(); }}); + { return vix::commands::CacheCommand::help(); }}); // Registry add({"registry", @@ -231,6 +231,14 @@ namespace vix::cli::dispatch []() { return vix::commands::DepsCommand::help(); }}); + add({"install", + "Registry", + "Install project dependencies from vix.lock", + [](const Args &a) + { return vix::commands::DepsCommand::run(a); }, + []() + { return vix::commands::DepsCommand::help(); }}); + add({"upgrade", "Info", "Upgrade the Vix CLI binary", diff --git a/src/commands/RemoveCommand.cpp b/src/commands/RemoveCommand.cpp index 0361b21..5604a39 100644 --- a/src/commands/RemoveCommand.cpp +++ b/src/commands/RemoveCommand.cpp @@ -338,9 +338,9 @@ namespace vix::commands << " - The registry is never modified.\n\n" << "Examples:\n" - << " vix remove gaspardkirira/strings\n" - << " vix remove gaspardkirira/strings@0.1.4\n" - << " vix remove gaspardkirira/strings --purge\n"; + << " vix remove @gk/jwt\n" + << " vix remove rix/fs@0.1.0\n" + << " vix remove @vix/app --purge\n"; return 0; }