Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit 7a192b8

Browse files
authored
fix: avoid running multiple subcommands (#1417)
* fix: avoid running multiple subcommands * fix: log
1 parent 9032501 commit 7a192b8

File tree

4 files changed

+79
-21
lines changed

4 files changed

+79
-21
lines changed

engine/controllers/command_line_parser.cc

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ void CommandLineParser::SetupCommonCommands() {
111111
" pull [options] [model_id]");
112112
model_pull_cmd->add_option("model_id", cml_data_.model_id, "");
113113
model_pull_cmd->callback([this, model_pull_cmd]() {
114+
if (std::exchange(executed_, true))
115+
return;
114116
if (cml_data_.model_id.empty()) {
115117
CLI_LOG("[model_id] is required\n");
116118
CLI_LOG(model_pull_cmd->help());
@@ -130,6 +132,8 @@ void CommandLineParser::SetupCommonCommands() {
130132
run_cmd->add_option("model_id", cml_data_.model_id, "");
131133
run_cmd->add_flag("--chat", cml_data_.chat_flag, "Flag for interactive mode");
132134
run_cmd->callback([this, run_cmd] {
135+
if (std::exchange(executed_, true))
136+
return;
133137
if (cml_data_.model_id.empty()) {
134138
CLI_LOG("[model_id] is required\n");
135139
CLI_LOG(run_cmd->help());
@@ -151,6 +155,8 @@ void CommandLineParser::SetupCommonCommands() {
151155
chat_cmd->add_option("-m,--message", cml_data_.msg,
152156
"Message to chat with model");
153157
chat_cmd->callback([this, chat_cmd] {
158+
if (std::exchange(executed_, true))
159+
return;
154160
if (cml_data_.model_id.empty()) {
155161
CLI_LOG("[model_id] is required\n");
156162
CLI_LOG(chat_cmd->help());
@@ -184,7 +190,9 @@ void CommandLineParser::SetupModelCommands() {
184190
" models [options] [subcommand]");
185191
models_cmd->group(kModelsGroup);
186192

187-
models_cmd->callback([models_cmd] {
193+
models_cmd->callback([this, models_cmd] {
194+
if (std::exchange(executed_, true))
195+
return;
188196
if (models_cmd->get_subcommands().empty()) {
189197
CLI_LOG(models_cmd->help());
190198
}
@@ -197,6 +205,8 @@ void CommandLineParser::SetupModelCommands() {
197205
model_start_cmd->add_option("model_id", cml_data_.model_id, "");
198206
model_start_cmd->group(kSubcommands);
199207
model_start_cmd->callback([this, model_start_cmd]() {
208+
if (std::exchange(executed_, true))
209+
return;
200210
if (cml_data_.model_id.empty()) {
201211
CLI_LOG("[model_id] is required\n");
202212
CLI_LOG(model_start_cmd->help());
@@ -214,6 +224,8 @@ void CommandLineParser::SetupModelCommands() {
214224
stop_model_cmd->group(kSubcommands);
215225
stop_model_cmd->add_option("model_id", cml_data_.model_id, "");
216226
stop_model_cmd->callback([this, stop_model_cmd]() {
227+
if (std::exchange(executed_, true))
228+
return;
217229
if (cml_data_.model_id.empty()) {
218230
CLI_LOG("[model_id] is required\n");
219231
CLI_LOG(stop_model_cmd->help());
@@ -227,7 +239,11 @@ void CommandLineParser::SetupModelCommands() {
227239
auto list_models_cmd =
228240
models_cmd->add_subcommand("list", "List all models locally");
229241
list_models_cmd->group(kSubcommands);
230-
list_models_cmd->callback([]() { commands::ModelListCmd().Exec(); });
242+
list_models_cmd->callback([this]() {
243+
if (std::exchange(executed_, true))
244+
return;
245+
commands::ModelListCmd().Exec();
246+
});
231247

232248
auto get_models_cmd =
233249
models_cmd->add_subcommand("get", "Get info of {model_id} locally");
@@ -236,6 +252,8 @@ void CommandLineParser::SetupModelCommands() {
236252
get_models_cmd->group(kSubcommands);
237253
get_models_cmd->add_option("model_id", cml_data_.model_id, "");
238254
get_models_cmd->callback([this, get_models_cmd]() {
255+
if (std::exchange(executed_, true))
256+
return;
239257
if (cml_data_.model_id.empty()) {
240258
CLI_LOG("[model_id] is required\n");
241259
CLI_LOG(get_models_cmd->help());
@@ -251,6 +269,8 @@ void CommandLineParser::SetupModelCommands() {
251269
model_del_cmd->group(kSubcommands);
252270
model_del_cmd->add_option("model_id", cml_data_.model_id, "");
253271
model_del_cmd->callback([&]() {
272+
if (std::exchange(executed_, true))
273+
return;
254274
if (cml_data_.model_id.empty()) {
255275
CLI_LOG("[model_id] is required\n");
256276
CLI_LOG(model_del_cmd->help());
@@ -271,6 +291,8 @@ void CommandLineParser::SetupModelCommands() {
271291
model_alias_cmd->add_option("--alias", cml_data_.model_alias,
272292
"new alias to be set");
273293
model_alias_cmd->callback([this, model_alias_cmd]() {
294+
if (std::exchange(executed_, true))
295+
return;
274296
if (cml_data_.model_id.empty() || cml_data_.model_alias.empty()) {
275297
CLI_LOG("[model_id] and [alias] are required\n");
276298
CLI_LOG(model_alias_cmd->help());
@@ -294,6 +316,8 @@ void CommandLineParser::SetupModelCommands() {
294316
"Absolute path to .gguf model, the path should "
295317
"include the gguf file name");
296318
model_import_cmd->callback([this, model_import_cmd]() {
319+
if (std::exchange(executed_, true))
320+
return;
297321
if (cml_data_.model_id.empty() || cml_data_.model_path.empty()) {
298322
CLI_LOG("[model_id] and [model_path] are required\n");
299323
CLI_LOG(model_import_cmd->help());
@@ -310,7 +334,9 @@ void CommandLineParser::SetupEngineCommands() {
310334
engines_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
311335
" engines [options] [subcommand]");
312336
engines_cmd->group(kEngineGroup);
313-
engines_cmd->callback([engines_cmd] {
337+
engines_cmd->callback([this, engines_cmd] {
338+
if (std::exchange(executed_, true))
339+
return;
314340
if (engines_cmd->get_subcommands().empty()) {
315341
CLI_LOG("A subcommand is required\n");
316342
CLI_LOG(engines_cmd->help());
@@ -320,7 +346,9 @@ void CommandLineParser::SetupEngineCommands() {
320346
auto list_engines_cmd =
321347
engines_cmd->add_subcommand("list", "List all cortex engines");
322348
list_engines_cmd->group(kSubcommands);
323-
list_engines_cmd->callback([]() {
349+
list_engines_cmd->callback([this]() {
350+
if (std::exchange(executed_, true))
351+
return;
324352
commands::EngineListCmd command;
325353
command.Exec();
326354
});
@@ -329,7 +357,9 @@ void CommandLineParser::SetupEngineCommands() {
329357
install_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
330358
" engines install [engine_name] [options]");
331359
install_cmd->group(kSubcommands);
332-
install_cmd->callback([install_cmd] {
360+
install_cmd->callback([this, install_cmd] {
361+
if (std::exchange(executed_, true))
362+
return;
333363
if (install_cmd->get_subcommands().empty()) {
334364
CLI_LOG("[engine_name] is required\n");
335365
CLI_LOG(install_cmd->help());
@@ -345,7 +375,9 @@ void CommandLineParser::SetupEngineCommands() {
345375
engines_cmd->add_subcommand("uninstall", "Uninstall engine");
346376
uninstall_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
347377
" engines uninstall [engine_name] [options]");
348-
uninstall_cmd->callback([uninstall_cmd] {
378+
uninstall_cmd->callback([this, uninstall_cmd] {
379+
if (std::exchange(executed_, true))
380+
return;
349381
if (uninstall_cmd->get_subcommands().empty()) {
350382
CLI_LOG("[engine_name] is required\n");
351383
CLI_LOG(uninstall_cmd->help());
@@ -366,6 +398,8 @@ void CommandLineParser::SetupSystemCommands() {
366398
cml_data_.port = std::stoi(cml_data_.config.apiServerPort);
367399
start_cmd->add_option("-p, --port", cml_data_.port, "Server port to listen");
368400
start_cmd->callback([this] {
401+
if (std::exchange(executed_, true))
402+
return;
369403
if (cml_data_.port != stoi(cml_data_.config.apiServerPort)) {
370404
CTL_INF("apiServerPort changed from " << cml_data_.config.apiServerPort
371405
<< " to " << cml_data_.port);
@@ -381,6 +415,8 @@ void CommandLineParser::SetupSystemCommands() {
381415
auto stop_cmd = app_.add_subcommand("stop", "Stop the API server");
382416
stop_cmd->group(kSystemGroup);
383417
stop_cmd->callback([this] {
418+
if (std::exchange(executed_, true))
419+
return;
384420
commands::ServerStopCmd ssc(cml_data_.config.apiServerHost,
385421
std::stoi(cml_data_.config.apiServerPort));
386422
ssc.Exec();
@@ -391,6 +427,8 @@ void CommandLineParser::SetupSystemCommands() {
391427
ps_cmd->group(kSystemGroup);
392428
ps_cmd->usage("Usage:\n" + commands::GetCortexBinary() + "ps");
393429
ps_cmd->callback([&]() {
430+
if (std::exchange(executed_, true))
431+
return;
394432
commands::PsCmd().Exec(cml_data_.config.apiServerHost,
395433
std::stoi(cml_data_.config.apiServerPort));
396434
});
@@ -399,6 +437,8 @@ void CommandLineParser::SetupSystemCommands() {
399437
update_cmd->group(kSystemGroup);
400438
update_cmd->add_option("-v", cml_data_.cortex_version, "");
401439
update_cmd->callback([this] {
440+
if (std::exchange(executed_, true))
441+
return;
402442
#if !defined(_WIN32)
403443
if (getuid()) {
404444
CLI_LOG("Error: Not root user. Please run with sudo.");
@@ -425,7 +465,9 @@ void CommandLineParser::EngineInstall(CLI::App* parent,
425465
install_engine_cmd->add_option("-s, --source", src,
426466
"Install engine by local path");
427467

428-
install_engine_cmd->callback([engine_name, &version, &src] {
468+
install_engine_cmd->callback([this, engine_name, &version, &src] {
469+
if (std::exchange(executed_, true))
470+
return;
429471
try {
430472
commands::EngineInstallCmd().Exec(engine_name, version, src);
431473
} catch (const std::exception& e) {
@@ -441,7 +483,9 @@ void CommandLineParser::EngineUninstall(CLI::App* parent,
441483
" engines install " + engine_name + " [options]");
442484
uninstall_engine_cmd->group(kEngineGroup);
443485

444-
uninstall_engine_cmd->callback([engine_name] {
486+
uninstall_engine_cmd->callback([this, engine_name] {
487+
if (std::exchange(executed_, true))
488+
return;
445489
try {
446490
commands::EngineUninstallCmd().Exec(engine_name);
447491
} catch (const std::exception& e) {
@@ -455,7 +499,9 @@ void CommandLineParser::EngineGet(CLI::App* parent) {
455499
get_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
456500
" engines get [engine_name] [options]");
457501
get_cmd->group(kSubcommands);
458-
get_cmd->callback([get_cmd] {
502+
get_cmd->callback([this, get_cmd] {
503+
if (std::exchange(executed_, true))
504+
return;
459505
if (get_cmd->get_subcommands().empty()) {
460506
CLI_LOG("[engine_name] is required\n");
461507
CLI_LOG(get_cmd->help());
@@ -470,8 +516,11 @@ void CommandLineParser::EngineGet(CLI::App* parent) {
470516
engine_get_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
471517
" engines get " + engine_name + " [options]");
472518
engine_get_cmd->group(kEngineGroup);
473-
engine_get_cmd->callback(
474-
[engine_name] { commands::EngineGetCmd().Exec(engine_name); });
519+
engine_get_cmd->callback([this, engine_name] {
520+
if (std::exchange(executed_, true))
521+
return;
522+
commands::EngineGetCmd().Exec(engine_name);
523+
});
475524
}
476525
}
477526

@@ -536,6 +585,8 @@ void CommandLineParser::ModelUpdate(CLI::App* parent) {
536585
}
537586

538587
model_update_cmd->callback([this]() {
588+
if (std::exchange(executed_, true))
589+
return;
539590
commands::ModelUpdCmd command(cml_data_.model_id);
540591
command.Exec(cml_data_.model_update_options);
541592
});

engine/controllers/command_line_parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ class CommandLineParser {
4444
std::unordered_map<std::string, std::string> model_update_options;
4545
};
4646
CmlData cml_data_;
47+
bool executed_ = false;
4748
};

engine/utils/file_manager_utils.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ inline std::filesystem::path GetExecutableFolderContainerPath() {
3030
uint32_t size = sizeof(buffer);
3131

3232
if (_NSGetExecutablePath(buffer, &size) == 0) {
33-
CTL_INF("Executable path: " << buffer);
33+
// CTL_DBG("Executable path: " << buffer);
3434
return std::filesystem::path{buffer}.parent_path();
3535
} else {
3636
CTL_ERR("Failed to get executable path");
@@ -41,7 +41,7 @@ inline std::filesystem::path GetExecutableFolderContainerPath() {
4141
ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1);
4242
if (len != -1) {
4343
buffer[len] = '\0';
44-
CTL_INF("Executable path: " << buffer);
44+
// CTL_DBG("Executable path: " << buffer);
4545
return std::filesystem::path{buffer}.parent_path();
4646
} else {
4747
CTL_ERR("Failed to get executable path");
@@ -50,7 +50,7 @@ inline std::filesystem::path GetExecutableFolderContainerPath() {
5050
#elif defined(_WIN32)
5151
char buffer[MAX_PATH];
5252
GetModuleFileNameA(NULL, buffer, MAX_PATH);
53-
CTL_INF("Executable path: " << buffer);
53+
// CTL_DBG("Executable path: " << buffer);
5454
return std::filesystem::path{buffer}.parent_path();
5555
#else
5656
LOG_ERROR << "Unsupported platform!";
@@ -105,7 +105,7 @@ inline std::filesystem::path GetConfigurationPath() {
105105

106106
std::string config_file_name{kCortexConfigurationFileName};
107107
config_file_name.append(env_postfix);
108-
CTL_INF("Config file name: " + config_file_name);
108+
// CTL_INF("Config file name: " + config_file_name);
109109

110110
auto home_path = GetHomeDirectoryPath();
111111
auto configuration_path = home_path / config_file_name;

engine/utils/logging_utils.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,27 @@
66
inline bool log_verbose = false;
77

88
// Only use trantor log
9-
#define CTL_INF(msg) \
10-
if (log_verbose) { \
11-
LOG_INFO << msg; \
9+
#define CTL_DBG(msg) \
10+
if (!log_verbose) { \
11+
LOG_DEBUG << msg; \
1212
}
1313

14-
#define CTL_WRN(msg) \
15-
if (log_verbose) { \
16-
LOG_WARN << msg; \
14+
#define CTL_INF(msg) \
15+
if (!log_verbose) { \
16+
LOG_INFO << msg; \
17+
}
18+
19+
#define CTL_WRN(msg) \
20+
if (!log_verbose) { \
21+
LOG_WARN << msg; \
1722
}
1823

1924
// Use std::cout if not verbose, use trantor log if verbose
2025
#define CTL_ERR(msg) \
2126
if (log_verbose) { \
2227
LOG_ERROR << msg; \
2328
} else { \
29+
LOG_ERROR << msg; \
2430
std::cout << msg << std::endl; \
2531
}
2632

0 commit comments

Comments
 (0)