1212 *
1313 */
1414#include < vix/cli/commands/CheckCommand.hpp>
15- #include < vix/cli/Style.hpp>
16-
1715#include < vix/cli/commands/check/CheckDetail.hpp>
16+ #include < vix/cli/Style.hpp>
17+ #include < vix/cli/util/Ui.hpp>
1818
1919#include < filesystem>
2020#include < iostream>
21-
22- using namespace vix ::cli::style;
23- namespace fs = std::filesystem;
21+ #include < system_error>
22+ #include < vector>
2423
2524namespace vix ::commands::CheckCommand
2625{
27- using namespace detail ;
26+ namespace fs = std::filesystem;
27+ namespace ui = vix::cli::util;
28+ namespace style = vix::cli::style;
2829
29- static bool exists_cmake_project (const fs::path &p)
30- {
31- std::error_code ec;
32- return fs::exists (p / " CMakeLists.txt" , ec);
33- }
30+ using namespace detail ;
3431
35- static fs::path resolve_project_dir_or_empty ( const Options &opt)
32+ namespace
3633 {
37- const fs::path cwd = fs::current_path ();
34+ static bool exists_cmake_project (const fs::path &p)
35+ {
36+ std::error_code ec;
37+ return fs::exists (p / " CMakeLists.txt" , ec);
38+ }
3839
39- if (! opt. dir . empty () )
40+ static fs::path resolve_project_dir_or_empty ( const Options & opt)
4041 {
41- fs::path d = fs::path (opt.dir );
42- if (exists_cmake_project (d))
43- return d;
42+ const fs::path cwd = fs::current_path ();
43+
44+ if (!opt.dir .empty ())
45+ {
46+ const fs::path d = fs::path (opt.dir );
47+ if (exists_cmake_project (d))
48+ return d;
49+ return {};
50+ }
51+
52+ if (exists_cmake_project (cwd))
53+ return cwd;
54+
55+ fs::path cur = cwd;
56+ for (int i = 0 ; i < 6 ; ++i)
57+ {
58+ if (exists_cmake_project (cur))
59+ return cur;
60+
61+ if (!cur.has_parent_path ())
62+ break ;
63+
64+ const fs::path parent = cur.parent_path ();
65+ if (parent == cur)
66+ break ;
67+
68+ cur = parent;
69+ }
70+
4471 return {};
4572 }
4673
47- if (exists_cmake_project (cwd))
48- return cwd;
49-
50- fs::path cur = cwd;
51- for (int i = 0 ; i < 6 ; ++i)
74+ static void print_project_resolution (const Options &opt, const fs::path &projectDir)
5275 {
53- if (exists_cmake_project (cur) )
54- return cur ;
76+ if (opt. quiet )
77+ return ;
5578
56- if (!cur.has_parent_path ())
57- break ;
79+ ui::section (std::cout, " Check" );
80+ ui::kv (std::cout, " mode" , " project" );
81+ ui::kv (std::cout, " project dir" , projectDir.string ());
82+ ui::one_line_spacer (std::cout);
83+ }
5884
59- fs::path parent = cur.parent_path ();
60- if (parent == cur)
61- break ;
85+ static void print_script_resolution (const Options &opt, const fs::path &scriptPath)
86+ {
87+ if (opt.quiet )
88+ return ;
6289
63- cur = parent;
90+ ui::section (std::cout, " Check" );
91+ ui::kv (std::cout, " mode" , " script" );
92+ ui::kv (std::cout, " script" , scriptPath.string ());
93+ ui::one_line_spacer (std::cout);
6494 }
6595
66- return {};
67- }
96+ static void print_help_section_header (std::ostream &out, const std::string &title)
97+ {
98+ out << title << " :\n " ;
99+ }
100+ } // namespace
68101
69102 int run (const std::vector<std::string> &args)
70103 {
71104 const Options opt = parse (args);
72105
73106 if (opt.singleCpp )
107+ {
108+ print_script_resolution (opt, opt.cppFile );
74109 return detail::check_single_cpp (opt);
110+ }
75111
76112 const fs::path projectDir = resolve_project_dir_or_empty (opt);
77-
78113 if (projectDir.empty ())
79114 {
80- error (" Unable to determine the project folder." );
81- hint (" Try: vix check --dir <path> or run from a CMake project directory." );
115+ style:: error (" Unable to determine the project folder." );
116+ style:: hint (" Try: vix check --dir <path> or run from a CMake project directory." );
82117 return 1 ;
83118 }
84119
85- info (" Using project directory:" );
86- step (projectDir.string ());
87-
120+ print_project_resolution (opt, projectDir);
88121 return detail::check_project (opt, projectDir);
89122 }
90123
@@ -95,51 +128,60 @@ namespace vix::commands::CheckCommand
95128 out << " Usage:\n " ;
96129 out << " vix check [path|file.cpp] [options]\n\n " ;
97130
98- out << " Description: \n " ;
131+ print_help_section_header ( out, " Description" ) ;
99132 out << " Validate a Vix/CMake project or a single-file C++ script.\n\n " ;
100133
101- out << " Project mode:\n " ;
102- out << " - Configure (via CMake presets)\n " ;
103- out << " - Build the project\n " ;
104- out << " - Optional: run tests (CTest)\n " ;
105- out << " - Optional: run the built binary (runtime check)\n\n " ;
134+ print_help_section_header (out, " Project mode" );
135+ out << " - Configure the project\n " ;
136+ out << " - Build the project\n " ;
137+ out << " - Optional: run tests with CTest\n " ;
138+ out << " - Optional: run the built executable\n " ;
139+ out << " - With --san / --ubsan, use an isolated check profile\n\n " ;
106140
107- out << " Script mode (.cpp file): \n " ;
108- out << " - Configure a temporary project\n " ;
109- out << " - Compile the file\n " ;
110- out << " - No execution (use `vix run` for execution) \n\n " ;
141+ print_help_section_header ( out, " Script mode" ) ;
142+ out << " - Create a temporary CMake project\n " ;
143+ out << " - Compile the file\n " ;
144+ out << " - With sanitizers enabled, also run the binary for runtime validation \n\n " ;
111145
112- out << " Options: \n " ;
113- out << " -d, --dir <path> Explicit project directory\n " ;
146+ print_help_section_header ( out, " Options" ) ;
147+ out << " -d, --dir <path> Explicit project directory\n " ;
114148 out << " --preset <name> Configure preset (default: dev-ninja)\n " ;
115- out << " --build-preset <name> Build preset override (optional)\n " ;
116- out << " -j, --jobs <n> Number of parallel build jobs\n\n " ;
117-
118- out << " --tests Run CTest after build (project mode)\n " ;
119- out << " --ctest-preset <name> CTest preset to use (optional)\n " ;
120- out << " --run Run the built binary after build\n\n " ;
121-
122- out << " Sanitizers:\n " ;
149+ out << " --build-preset <name> Build preset override\n " ;
150+ out << " -j, --jobs <n> Number of parallel build jobs\n " ;
151+ out << " --tests Run CTest after build\n " ;
152+ out << " --ctest-preset <name> CTest preset override\n " ;
153+ out << " --ctest-arg <arg> Extra argument forwarded to CTest (repeatable)\n " ;
154+ out << " --run Run the built executable after build\n " ;
155+ out << " --run-timeout <sec> Runtime timeout in seconds\n " ;
156+ out << " --quiet, -q Minimal output\n " ;
157+ out << " --verbose More verbose logging\n " ;
158+ out << " --log-level <level> Set VIX_LOG_LEVEL for the check session\n\n " ;
159+
160+ print_help_section_header (out, " Sanitizers" );
123161 out << " --san Enable AddressSanitizer + UBSan\n " ;
124162 out << " --ubsan Enable UBSan only\n\n " ;
125163
126- out << " Notes:\n " ;
127- out << " - In project mode, sanitizers are applied via presets\n " ;
128- out << " (e.g. dev-ninja-san, dev-ninja-ubsan)\n " ;
129- out << " - In script mode, sanitizers affect compilation only\n\n " ;
130-
131- out << " Examples:\n " ;
132- out << " vix check Check current project (configure + build)\n " ;
133- out << " vix check --tests Build project and run CTest\n " ;
134- out << " vix check --run Build project and run the compiled binary\n " ;
135- out << " vix check --tests --run Full validation: build, tests, runtime\n " ;
136- out << " vix check --san --tests --run Full validation with ASan + UBSan enabled\n\n " ;
137-
138- out << " vix check --dir ./examples/api Check a project located in a specific directory\n\n " ;
139-
140- out << " vix check main.cpp Compile a single C++ file (script mode)\n " ;
141- out << " vix check main.cpp --san Compile a script with ASan + UBSan\n " ;
142- out << " vix check main.cpp --ubsan Compile a script with UBSan only\n " ;
164+ print_help_section_header (out, " Notes" );
165+ out << " - Project checks use isolated build directories per profile.\n " ;
166+ out << " Example: build-ninja, build-ninja-san, build-ninja-ubsan.\n " ;
167+ out << " - If a dedicated sanitizer preset does not exist, Vix falls back to\n " ;
168+ out << " manual configure/build for that check profile.\n " ;
169+ out << " - In project mode, --san and --ubsan also trigger runtime validation.\n " ;
170+ out << " - In script mode, sanitizers validate both build and runtime.\n " ;
171+ out << " - Global packages installed by Vix are integrated into project checks.\n\n " ;
172+
173+ print_help_section_header (out, " Examples" );
174+ out << " vix check\n " ;
175+ out << " vix check --tests\n " ;
176+ out << " vix check --run\n " ;
177+ out << " vix check --tests --run\n " ;
178+ out << " vix check --san\n " ;
179+ out << " vix check --san --tests\n " ;
180+ out << " vix check --san --tests --run-timeout 20\n " ;
181+ out << " vix check --dir ./examples/api\n " ;
182+ out << " vix check main.cpp\n " ;
183+ out << " vix check main.cpp --san\n " ;
184+ out << " vix check main.cpp --ubsan\n " ;
143185
144186 return 0 ;
145187 }
0 commit comments