Skip to content

Commit b792d6d

Browse files
committed
refactor(cli): extract new and modules command internals
1 parent 5b57348 commit b792d6d

16 files changed

Lines changed: 3419 additions & 2840 deletions
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* @file ModulesCommands.hpp
3+
* @author Gaspard Kirira
4+
*
5+
* Copyright 2025, Gaspard Kirira. All rights reserved.
6+
* https://github.com/vixcpp/vix
7+
* Use of this source code is governed by a MIT license
8+
* that can be found in the License file.
9+
*
10+
* Business-logic handlers for the `vix modules` subcommands.
11+
* Each function is self-contained: it prints its own output
12+
* and returns true on success.
13+
*/
14+
15+
#ifndef VIX_CLI_MODULES_COMMANDS_HPP
16+
#define VIX_CLI_MODULES_COMMANDS_HPP
17+
18+
#include <filesystem>
19+
#include <string>
20+
21+
namespace vix::commands::modules_cmd::commands
22+
{
23+
24+
/// `vix modules init` — creates modules/ + cmake/vix_modules.cmake,
25+
/// optionally patches root CMakeLists.txt.
26+
bool cmd_init(const std::filesystem::path &root, bool patchRoot);
27+
28+
/// `vix modules add <module>` — scaffolds a new module skeleton under
29+
/// modules/<module>/, optionally auto-links it in the root CMakeLists.txt.
30+
bool cmd_add(
31+
const std::filesystem::path &root,
32+
const std::string &project,
33+
const std::string &module,
34+
bool patchRootLink);
35+
36+
/// `vix modules check` — validates module safety rules:
37+
/// - no public header includes a private src/ path
38+
/// - every cross-module include has a declared CMake dependency
39+
bool cmd_check(const std::filesystem::path &root, const std::string &project);
40+
41+
} // namespace vix::commands::modules_cmd::commands
42+
43+
#endif
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/**
2+
* @file ModulesContent.hpp
3+
* @author Gaspard Kirira
4+
*
5+
* Copyright 2025, Gaspard Kirira. All rights reserved.
6+
* https://github.com/vixcpp/vix
7+
* Use of this source code is governed by a MIT license
8+
* that can be found in the License file.
9+
*
10+
* Module naming / validation, CMake and C++ content generators,
11+
* and static analysis helpers for `vix modules`.
12+
*/
13+
#ifndef VIX_CLI_MODULES_CONTENT_HPP
14+
#define VIX_CLI_MODULES_CONTENT_HPP
15+
16+
#include <filesystem>
17+
#include <set>
18+
#include <string>
19+
#include <unordered_set>
20+
21+
namespace vix::commands::modules_cmd::content
22+
{
23+
/// Replaces '-' with '_' and trims the name.
24+
std::string normalize_module_id(std::string name);
25+
26+
/// Returns "<project>_<normalized_module>" (CMake target name).
27+
std::string module_target_name(const std::string &project, const std::string &module);
28+
29+
/// Returns "<project>::<normalized_module>" (CMake alias / link name).
30+
std::string module_alias_name(const std::string &project, const std::string &module);
31+
32+
// ------------------------------------------------------------------
33+
// Validation
34+
// ------------------------------------------------------------------
35+
36+
/// Accepts [A-Za-z0-9_-], non-empty.
37+
bool is_valid_module_name(const std::string &name);
38+
39+
/// Returns true if name conflicts with a well-known tool/library name.
40+
bool is_reserved_module_name(std::string name);
41+
42+
// ------------------------------------------------------------------
43+
// CMake content generators
44+
// ------------------------------------------------------------------
45+
46+
/// cmake/vix_modules.cmake — the central include file added by `init`.
47+
std::string cmake_vix_modules_cmake_app_first();
48+
49+
/// modules/<m>/CMakeLists.txt for a new module.
50+
std::string module_cmakelists_txt_app_first(const std::string &project, const std::string &module);
51+
52+
// ------------------------------------------------------------------
53+
// C++ content generators
54+
// ------------------------------------------------------------------
55+
56+
/// modules/<m>/include/<m>/api.hpp stub.
57+
std::string module_public_header_app_first(const std::string &project, const std::string &module);
58+
59+
/// modules/<m>/src/<m>.cpp stub.
60+
std::string module_impl_cpp_app_first(const std::string &project, const std::string &module);
61+
62+
// ------------------------------------------------------------------
63+
// CMakeLists.txt patching
64+
// ------------------------------------------------------------------
65+
66+
/// Inserts the vix_modules.cmake include block after the project() call
67+
/// (idempotent via begin/end markers).
68+
bool patch_root_cmakelists_include(const std::filesystem::path &root);
69+
70+
/// Inserts a conditional target_link_libraries block for the given module
71+
/// inside the VIX_MODULE_LINKS section (idempotent per-module).
72+
bool patch_root_cmakelists_link_module(
73+
const std::filesystem::path &root,
74+
const std::string &project,
75+
const std::string &module);
76+
77+
// ------------------------------------------------------------------
78+
// Static analysis helpers (used by cmd_check)
79+
// ------------------------------------------------------------------
80+
81+
/// Extracts all "<project>::<mod>" aliases declared in a module's
82+
/// CMakeLists.txt as explicit dependencies.
83+
std::unordered_set<std::string> parse_declared_deps_from_module_cmake(
84+
const std::filesystem::path &moduleCmake,
85+
const std::string &project);
86+
87+
/// Returns module names referenced via "#include <other/...>" in a
88+
/// public header, filtering to modules that actually exist on disk.
89+
std::set<std::string> parse_public_includes_for_cross_module(
90+
const std::filesystem::path &publicHeader,
91+
const std::filesystem::path &modulesDir);
92+
93+
/// Returns true if a public header includes a private src/ path.
94+
bool header_includes_private_impl(
95+
const std::filesystem::path &publicHeader,
96+
const std::filesystem::path &moduleDir);
97+
98+
} // namespace vix::commands::modules_cmd::content
99+
100+
#endif
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @file ModulesTypes.hpp
3+
* @author Gaspard Kirira
4+
*
5+
* Copyright 2025, Gaspard Kirira. All rights reserved.
6+
* https://github.com/vixcpp/vix
7+
* Use of this source code is governed by a MIT license
8+
* that can be found in the License file.
9+
*
10+
* Shared types for the `vix modules` command.
11+
*/
12+
#ifndef VIX_CLI_MODULES_TYPES_HPP
13+
#define VIX_CLI_MODULES_TYPES_HPP
14+
15+
#include <string>
16+
17+
namespace vix::commands::modules_cmd
18+
{
19+
20+
/// Parsed CLI arguments for `vix modules`.
21+
struct Options
22+
{
23+
std::string subcmd; ///< "init" | "add" | "check" | "help"
24+
std::string dir; ///< --dir value (empty = cwd)
25+
std::string project; ///< --project override (empty = auto-detect)
26+
std::string module; ///< module name for `add`
27+
28+
bool patchRoot = true; ///< patch root CMakeLists.txt on init
29+
bool patchLink = true; ///< auto-link module into main target on add
30+
bool showHelp = false;
31+
};
32+
33+
} // namespace vix::commands::modules_cmd
34+
35+
#endif
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @file ModulesUtils.hpp
3+
* @author Gaspard Kirira
4+
*
5+
* Copyright 2025, Gaspard Kirira. All rights reserved.
6+
* https://github.com/vixcpp/vix
7+
* Use of this source code is governed by a MIT license
8+
* that can be found in the License file.
9+
*
10+
* Generic string and filesystem helpers for `vix modules`.
11+
* No dependency on CMake content or module business logic.
12+
*/
13+
14+
#ifndef VIX_CLI_MODULES_UTILS_HPP
15+
#define VIX_CLI_MODULES_UTISL_HPP
16+
17+
#include <filesystem>
18+
#include <optional>
19+
#include <string>
20+
#include <string_view>
21+
#include <vector>
22+
23+
namespace vix::commands::modules_cmd::utils
24+
{
25+
26+
// String helpers
27+
bool starts_with(std::string_view s, std::string_view pfx);
28+
bool ends_with(std::string_view s, std::string_view suf);
29+
std::string trim(std::string s);
30+
std::string to_lower(std::string s);
31+
32+
// Filesystem helpers
33+
bool exists_dir(const std::filesystem::path &p);
34+
bool exists_file(const std::filesystem::path &p);
35+
36+
/// Creates all directories (like mkdir -p). Returns true if the path
37+
/// already exists or was created successfully.
38+
bool ensure_dir(const std::filesystem::path &p);
39+
40+
/// Reads an entire file into a string. Returns nullopt on failure.
41+
std::optional<std::string> read_file(const std::filesystem::path &p);
42+
43+
/// Writes content to p only if p does not already exist.
44+
bool write_file_if_missing(const std::filesystem::path &p, const std::string &content);
45+
46+
/// Writes content to p, truncating any existing content.
47+
bool write_file_overwrite(const std::filesystem::path &p, const std::string &content);
48+
49+
/// Returns all regular files under dir, recursively.
50+
std::vector<std::filesystem::path> list_files_recursive(const std::filesystem::path &dir);
51+
52+
/// Resolves a raw --dir option to an absolute path (defaults to cwd).
53+
std::filesystem::path resolve_root(const std::string &dirOpt);
54+
55+
/// Parses the project name from the first project() call in CMakeLists.txt.
56+
/// Falls back to "myproj" if not found.
57+
std::string detect_project_name_from_cmake(const std::filesystem::path &root);
58+
59+
} // namespace vix::commands::modules_cmd::utils
60+
61+
#endif
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#pragma once
2+
3+
/**
4+
* @file NewGenerator.hpp
5+
* @author Gaspard Kirira
6+
*
7+
* Copyright 2025, Gaspard Kirira. All rights reserved.
8+
* https://github.com/vixcpp/vix
9+
* Use of this source code is governed by a MIT license
10+
* that can be found in the License file.
11+
*
12+
* File-system helpers and project scaffolding routines for `vix new`.
13+
*/
14+
15+
#include <filesystem>
16+
#include <string>
17+
18+
#include <vix/cli/commands/new/NewTypes.hpp>
19+
20+
namespace vix::commands::new_cmd::generator
21+
{
22+
23+
namespace fs = std::filesystem;
24+
25+
// ------------------------------------------------------------------
26+
// File-system helpers
27+
// ------------------------------------------------------------------
28+
29+
bool dir_exists(const fs::path &p);
30+
bool dir_is_empty(const fs::path &p);
31+
32+
/// Creates all directories in p (like mkdir -p). Returns false and sets err on failure.
33+
bool ensure_dir(const fs::path &p, std::string &err);
34+
35+
/// Writes content to p, creating parent directories as needed.
36+
bool write_text_file(const fs::path &p, const std::string &content, std::string &err);
37+
38+
// ------------------------------------------------------------------
39+
// Path helpers
40+
// ------------------------------------------------------------------
41+
42+
bool is_dot_path(const std::string &s);
43+
std::string current_dir_name();
44+
45+
// ------------------------------------------------------------------
46+
// Project scaffolding
47+
// ------------------------------------------------------------------
48+
49+
/// Generates all files for an Application project under projectDir.
50+
bool generate_app_project(
51+
const fs::path &projectDir,
52+
const std::string &projName,
53+
const FeaturesSelection &features,
54+
std::string &err);
55+
56+
/// Generates all files for a header-only Library project under projectDir.
57+
bool generate_lib_project(
58+
const fs::path &projectDir,
59+
const std::string &projName,
60+
std::string &err);
61+
62+
// ------------------------------------------------------------------
63+
// Post-generation output
64+
// ------------------------------------------------------------------
65+
66+
void print_next_steps_app(const fs::path &projectDir, const std::string &projName);
67+
void print_next_steps_lib(const fs::path &projectDir, const std::string &projName);
68+
69+
} // namespace vix::commands::new_cmd::generator

0 commit comments

Comments
 (0)