Skip to content

Commit 45e57e2

Browse files
committed
refactor(cli): prepare dev mode build flow
1 parent 3c417aa commit 45e57e2

9 files changed

Lines changed: 352 additions & 72 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
*
3+
* @file BuildContext.hpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2026, Gaspard Kirira. All rights reserved.
7+
* https://github.com/vixcpp/vix
8+
* Use of this source code is governed by a MIT license
9+
* that can be found in the License file.
10+
*
11+
* Vix.cpp
12+
*
13+
* Shared build context helpers
14+
*
15+
*/
16+
17+
#ifndef VIX_CLI_BUILD_BUILD_CONTEXT_HPP
18+
#define VIX_CLI_BUILD_BUILD_CONTEXT_HPP
19+
20+
#include <filesystem>
21+
#include <optional>
22+
#include <string>
23+
24+
#include <vix/cli/process/Process.hpp>
25+
26+
namespace vix::cli::build
27+
{
28+
namespace fs = std::filesystem;
29+
namespace process = vix::cli::process;
30+
31+
std::optional<process::Preset> resolve_builtin_preset(
32+
const std::string &name);
33+
34+
std::string default_build_target_name(
35+
const process::Options &opt,
36+
const process::Plan &plan);
37+
38+
std::string default_graph_target_name(
39+
const process::Options &opt,
40+
const process::Plan &plan);
41+
42+
fs::path default_project_executable_path(
43+
const process::Options &opt,
44+
const process::Plan &plan);
45+
46+
} // namespace vix::cli::build
47+
48+
#endif

include/vix/cli/commands/run/RunDetail.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ namespace vix::commands::RunCommand::detail
164164
std::string warnedArg;
165165

166166
bool localCache = false;
167+
bool devMode{false};
167168
};
168169

169170
/**

src/build/BuildContext.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
*
3+
* @file BuildContext.cpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2026, Gaspard Kirira. All rights reserved.
7+
* https://github.com/vixcpp/vix
8+
* Use of this source code is governed by a MIT license
9+
* that can be found in the License file.
10+
*
11+
* Vix.cpp
12+
*
13+
* Shared build context helpers
14+
*
15+
*/
16+
17+
#include <vix/cli/build/BuildContext.hpp>
18+
19+
#include <map>
20+
21+
namespace vix::cli::build
22+
{
23+
namespace
24+
{
25+
static std::map<std::string, process::Preset> builtin_presets()
26+
{
27+
std::map<std::string, process::Preset> presets;
28+
29+
presets.emplace(
30+
"dev",
31+
process::Preset{"dev", "Ninja", "Debug", "build-dev"});
32+
33+
presets.emplace(
34+
"dev-ninja",
35+
process::Preset{"dev-ninja", "Ninja", "Debug", "build-ninja"});
36+
37+
presets.emplace(
38+
"release",
39+
process::Preset{"release", "Ninja", "Release", "build-release"});
40+
41+
return presets;
42+
}
43+
} // namespace
44+
45+
std::optional<process::Preset> resolve_builtin_preset(
46+
const std::string &name)
47+
{
48+
const auto presets = builtin_presets();
49+
const auto it = presets.find(name);
50+
51+
if (it == presets.end())
52+
return std::nullopt;
53+
54+
return it->second;
55+
}
56+
57+
std::string default_build_target_name(
58+
const process::Options &opt,
59+
const process::Plan &plan)
60+
{
61+
if (!opt.buildTarget.empty())
62+
return opt.buildTarget;
63+
64+
return plan.projectDir.filename().string();
65+
}
66+
67+
std::string default_graph_target_name(
68+
const process::Options &opt,
69+
const process::Plan &plan)
70+
{
71+
if (!opt.buildTarget.empty())
72+
return opt.buildTarget;
73+
74+
return plan.projectDir.filename().string();
75+
}
76+
77+
fs::path default_project_executable_path(
78+
const process::Options &opt,
79+
const process::Plan &plan)
80+
{
81+
const std::string target = default_build_target_name(opt, plan);
82+
83+
#ifdef _WIN32
84+
return plan.buildDir / (target + ".exe");
85+
#else
86+
return plan.buildDir / target;
87+
#endif
88+
}
89+
90+
} // namespace vix::cli::build

src/cmake/CMakeBuild.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ namespace vix::cli::build
571571
return false;
572572

573573
if (filterCMakeSummary)
574-
return !is_cmake_configure_summary_line(line);
574+
return false;
575575

576576
if (!progressOnly)
577577
return true;

src/commands/BuildCommand.cpp

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <vix/cli/build/ObjectCache.hpp>
2121
#include <vix/cli/build/BuildGraphExecutor.hpp>
2222
#include <vix/cli/build/BuildStyle.hpp>
23+
#include <vix/cli/build/BuildContext.hpp>
2324

2425
#include <algorithm>
2526
#include <cctype>
@@ -95,17 +96,6 @@ namespace vix::commands::BuildCommand
9596
}
9697
};
9798

98-
static std::map<std::string, process::Preset> builtin_presets()
99-
{
100-
std::map<std::string, process::Preset> m;
101-
102-
m.emplace("dev", process::Preset{"dev", "Ninja", "Debug", "build-dev"});
103-
m.emplace("dev-ninja", process::Preset{"dev-ninja", "Ninja", "Debug", "build-ninja"});
104-
m.emplace("release", process::Preset{"release", "Ninja", "Release", "build-release"});
105-
106-
return m;
107-
}
108-
10999
static bool write_if_different(const fs::path &path, const std::string &content)
110100
{
111101
if (util::file_exists(path))
@@ -118,26 +108,6 @@ namespace vix::commands::BuildCommand
118108
return util::write_text_file_atomic(path, content);
119109
}
120110

121-
static std::string graph_build_target_name(
122-
const process::Options &opt,
123-
const process::Plan &plan)
124-
{
125-
if (!opt.buildTarget.empty())
126-
return opt.buildTarget;
127-
128-
return plan.projectDir.filename().string();
129-
}
130-
131-
static std::string cmake_build_target_name(
132-
const process::Options &opt,
133-
const process::Plan &plan)
134-
{
135-
if (!opt.buildTarget.empty())
136-
return opt.buildTarget;
137-
138-
return plan.projectDir.filename().string();
139-
}
140-
141111
static bool graph_executor_enabled()
142112
{
143113
const char *value = std::getenv("VIX_GRAPH_EXECUTOR");
@@ -191,15 +161,6 @@ namespace vix::commands::BuildCommand
191161
return true;
192162
}
193163

194-
static std::optional<process::Preset> resolve_preset(const std::string &name)
195-
{
196-
const auto presets = builtin_presets();
197-
const auto it = presets.find(name);
198-
if (it == presets.end())
199-
return std::nullopt;
200-
return it->second;
201-
}
202-
203164
static std::size_t count_built_targets_from_log(const std::string &log)
204165
{
205166
std::size_t count = 0;
@@ -927,7 +888,7 @@ namespace vix::commands::BuildCommand
927888
return std::nullopt;
928889
}
929890

930-
const auto presetOpt = resolve_preset(opt.preset);
891+
const auto presetOpt = build::resolve_builtin_preset(opt.preset);
931892
if (!presetOpt)
932893
return std::nullopt;
933894

@@ -1848,7 +1809,7 @@ namespace vix::commands::BuildCommand
18481809
{
18491810
build::BuildGraphExecutorOptions executorOptions;
18501811
executorOptions.buildDir = plan_.buildDir;
1851-
executorOptions.target = graph_build_target_name(opt_, plan_);
1812+
executorOptions.target = build::default_graph_target_name(opt_, plan_);
18521813
executorOptions.jobs = opt_.jobs;
18531814
executorOptions.quiet = opt_.quiet;
18541815
executorOptions.verbose = verboseMode;
@@ -2088,7 +2049,7 @@ namespace vix::commands::BuildCommand
20882049

20892050
build::print_build_header_full(
20902051
std::cout,
2091-
cmake_build_target_name(opt_, plan_),
2052+
build::default_build_target_name(opt_, plan_),
20922053
display_build_profile(plan_),
20932054
plan_.launcher,
20942055
plan_.fastLinkerFlag,
@@ -2098,7 +2059,7 @@ namespace vix::commands::BuildCommand
20982059
{
20992060
build::print_build_header_full(
21002061
std::cout,
2101-
cmake_build_target_name(opt_, plan_),
2062+
build::default_build_target_name(opt_, plan_),
21022063
display_build_profile(plan_),
21032064
std::nullopt,
21042065
std::nullopt,
@@ -2280,7 +2241,7 @@ namespace vix::commands::BuildCommand
22802241
if (parseExit != 0)
22812242
return parseExit;
22822243

2283-
if (!resolve_preset(opt.preset))
2244+
if (!build::resolve_builtin_preset(opt.preset))
22842245
{
22852246
error("Unknown preset: " + opt.preset);
22862247
hint("Available presets: dev, dev-ninja, release");

src/commands/DevCommand.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <algorithm>
2020
#include <string>
2121
#include <vector>
22+
#include <iostream>
2223

2324
#include <cstdlib>
2425
#ifdef _WIN32
@@ -46,12 +47,20 @@ namespace vix::commands::DevCommand
4647
int run(const std::vector<std::string> &args)
4748
{
4849
std::vector<std::string> forwarded;
49-
forwarded.reserve(args.size() + 1);
50+
forwarded.reserve(args.size() + 2);
51+
5052
forwarded.insert(forwarded.end(), args.begin(), args.end());
5153

5254
if (!has_watch_flag(forwarded))
5355
forwarded.emplace_back("--watch");
54-
vix::cli::util::info_line(std::cout, "Dev mode active");
56+
57+
forwarded.emplace_back("--dev-mode");
58+
59+
std::cerr << "[vix:dev] forwarding to run:";
60+
for (const auto &arg : forwarded)
61+
std::cerr << " " << arg;
62+
std::cerr << "\n";
63+
5564
return vix::commands::RunCommand::run(forwarded);
5665
}
5766

src/commands/RunCommand.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,23 @@ namespace vix::commands::RunCommand
15951595
? fs::current_path()
15961596
: target.path;
15971597

1598+
warn_if_env_file_missing(projectDir);
1599+
1600+
if (opt.watch)
1601+
{
1602+
#ifndef _WIN32
1603+
std::cerr << "[vix:dev] entering project watch from resolved target:"
1604+
<< " watch=" << (opt.watch ? "1" : "0")
1605+
<< " devMode=" << (opt.devMode ? "1" : "0")
1606+
<< " projectDir=" << projectDir.string()
1607+
<< "\n";
1608+
1609+
return run_project_watch(opt, projectDir);
1610+
#else
1611+
hint("Project watch mode is not yet implemented on Windows; running once without auto-reload.");
1612+
#endif
1613+
}
1614+
15981615
if (has_presets(projectDir))
15991616
return run_project_with_presets(projectDir, opt, ui_enabled());
16001617

@@ -1624,6 +1641,13 @@ namespace vix::commands::RunCommand
16241641

16251642
warn_if_env_file_missing(projectDir);
16261643

1644+
std::cerr << "[vix:dev] before project watch check:"
1645+
<< " watch=" << (opt.watch ? "1" : "0")
1646+
<< " devMode=" << (opt.devMode ? "1" : "0")
1647+
<< " singleCpp=" << (opt.singleCpp ? "1" : "0")
1648+
<< " projectDir=" << projectDir.string()
1649+
<< "\n";
1650+
16271651
if (!opt.singleCpp && opt.watch)
16281652
{
16291653
#ifndef _WIN32

src/commands/run/RunFlow.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ namespace vix::commands::RunCommand::detail
9898
{
9999
return v == "--verbose" || v == "--quiet" || v == "-q" ||
100100
v == "--watch" || v == "--reload" ||
101+
v == "--dev-mode" ||
101102
v == "--force-server" || v == "--force-script" ||
102103
v == "--san" || v == "--ubsan" || v == "--tsan" ||
103104
v == "--docs" || v == "--no-docs" || v.rfind("--docs=", 0) == 0 ||
@@ -444,6 +445,10 @@ namespace vix::commands::RunCommand::detail
444445
{
445446
opt.localCache = true;
446447
}
448+
else if (a == "--dev-mode")
449+
{
450+
opt.devMode = true;
451+
}
447452
else if (a == "--log-level" || a == "--loglevel")
448453
{
449454
opt.logLevel = take_value(args, i, a, opt);

0 commit comments

Comments
 (0)