Skip to content

Commit bdf39e1

Browse files
committed
fix: --stdout works as intended again
* --stdout was being ignored and was writing files instead after the multi file update
1 parent 1198e1c commit bdf39e1

File tree

8 files changed

+207
-52
lines changed

8 files changed

+207
-52
lines changed

ecsact/cli/commands/codegen/codegen.cc

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -256,20 +256,34 @@ auto ecsact::cli::codegen(codegen_options options) -> int {
256256
// We're filling this in the for loop. We shouldn't have any in here.
257257
assert(file_write_streams.empty());
258258

259-
for(auto filename_index = 0;
260-
plugin_output_paths.size() > filename_index;
261-
++filename_index) {
262-
auto output_file_path = plugin_output_paths.at(filename_index);
263-
output_paths.emplace(output_file_path.string(), plugin_name);
264-
if(fs::exists(output_file_path)) {
265-
fs::permissions(output_file_path, fs::perms::all);
259+
if(options.write_fn) {
260+
if(plugin_output_paths.size() > 1) {
261+
// TODO: this error can be misleading if a non-stdout custom
262+
// write_fn is used
263+
report_error("cannot use --stdout with multiple output files");
264+
return 1;
266265
}
267266

268-
auto& file_write_stream = file_write_streams.emplace_back();
269-
file_write_stream.open(output_file_path);
267+
plugin_fn(package_id, *options.write_fn, &codegen_report_fn);
268+
} else {
269+
auto write_fn = options.write_fn.value_or(&file_write_fn);
270+
271+
for(auto filename_index = 0;
272+
plugin_output_paths.size() > filename_index;
273+
++filename_index) {
274+
auto output_file_path = plugin_output_paths.at(filename_index);
275+
output_paths.emplace(output_file_path.string(), plugin_name);
276+
if(fs::exists(output_file_path)) {
277+
fs::permissions(output_file_path, fs::perms::all);
278+
}
279+
280+
auto& file_write_stream = file_write_streams.emplace_back();
281+
file_write_stream.open(output_file_path);
282+
}
283+
284+
plugin_fn(package_id, &file_write_fn, &codegen_report_fn);
270285
}
271286

272-
plugin_fn(package_id, &file_write_fn, &codegen_report_fn);
273287
if(received_fatal_codegen_report) {
274288
received_fatal_codegen_report = false;
275289
has_plugin_error = true;

ecsact/cli/commands/common.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,20 @@ auto ecsact::cli::detail::process_common_args( //
1010
const docopt::Options& args
1111
) -> int {
1212
auto format = args.at("--format").asString();
13+
auto uses_stdout = args.contains("--stdout") && args.at("--stdout").asBool();
1314

1415
if(format == "text") {
15-
set_report_handler(text_report{});
16+
if(uses_stdout) {
17+
set_report_handler(text_report_stderr_only{});
18+
} else {
19+
set_report_handler(text_report{});
20+
}
1621
} else if(format == "json") {
17-
set_report_handler(json_report{});
22+
if(uses_stdout) {
23+
set_report_handler(json_report_stderr_only{});
24+
} else {
25+
set_report_handler(json_report{});
26+
}
1827
} else if(format == "none") {
1928
set_report_handler({});
2029
} else {

ecsact/cli/detail/json_report.cc

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,27 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(subcommand_end_message, id, exit_code)
2222
} // namespace ecsact::cli
2323

2424
template<typename MessageT>
25-
void print_json_report(const MessageT& message) {
25+
void print_json_report(auto&& outstream, const MessageT& message) {
2626
auto message_json = "{}"_json;
2727
to_json(message_json, message);
2828
message_json["type"] = MessageT::type;
29-
std::cout << message_json.dump() + "\n";
29+
outstream << message_json.dump() + "\n";
3030
}
3131

3232
auto ecsact::cli::detail::json_report::operator()( //
3333
const message_variant_t& message
3434
) const -> void {
35-
std::visit([](const auto& message) { print_json_report(message); }, message);
35+
std::visit(
36+
[](const auto& message) { print_json_report(std::cout, message); },
37+
message
38+
);
39+
}
40+
41+
auto ecsact::cli::detail::json_report_stderr_only::operator()( //
42+
const message_variant_t& message
43+
) const -> void {
44+
std::visit(
45+
[](const auto& message) { print_json_report(std::cerr, message); },
46+
message
47+
);
3648
}

ecsact/cli/detail/json_report.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ namespace ecsact::cli::detail {
66
struct json_report {
77
auto operator()(const message_variant_t&) const -> void;
88
};
9+
10+
struct json_report_stderr_only {
11+
auto operator()(const message_variant_t&) const -> void;
12+
};
913
} // namespace ecsact::cli::detail

ecsact/cli/detail/text_report.cc

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,29 +36,40 @@ using ecsact::cli::warning_message;
3636
#endif
3737

3838
namespace {
39-
auto print_text_report(const alert_message& msg) -> void {
40-
std::cout << std::format( //
39+
constexpr auto get_outputstream(auto&& stream, auto&& preferred)
40+
-> decltype(auto) {
41+
if constexpr(std::is_same_v<
42+
std::nullptr_t,
43+
std::remove_cvref_t<decltype(stream)>>) {
44+
return preferred;
45+
} else {
46+
return stream;
47+
}
48+
}
49+
50+
auto print_text_report(auto&& output, const alert_message& msg) -> void {
51+
get_outputstream(output, std::cout) << std::format( //
4152
COLOR_RED "ALERT:" COLOR_RESET " {}\n",
4253
msg.content
4354
);
4455
}
4556

46-
auto print_text_report(const info_message& msg) -> void {
47-
std::cout << std::format( //
57+
auto print_text_report(auto&& output, const info_message& msg) -> void {
58+
get_outputstream(output, std::cout) << std::format( //
4859
COLOR_GRN "INFO:" COLOR_RESET " {}\n",
4960
msg.content
5061
);
5162
}
5263

53-
auto print_text_report(const error_message& msg) -> void {
54-
std::cout << std::format( //
64+
auto print_text_report(auto&& output, const error_message& msg) -> void {
65+
get_outputstream(output, std::cerr) << std::format( //
5566
COLOR_RED "ERROR:" COLOR_RESET " {}\n",
5667
msg.content
5768
);
5869
}
5970

60-
auto print_text_report(const ecsact_error_message& msg) -> void {
61-
std::cerr << std::format( //
71+
auto print_text_report(auto&& output, const ecsact_error_message& msg) -> void {
72+
get_outputstream(output, std::cerr) << std::format( //
6273
COLOR_RED "ERROR:" COLOR_RESET " {}:{}:{}\n {}\n",
6374
msg.ecsact_source_path,
6475
msg.line,
@@ -67,31 +78,34 @@ auto print_text_report(const ecsact_error_message& msg) -> void {
6778
);
6879
}
6980

70-
auto print_text_report(const warning_message& msg) -> void {
71-
std::cout << std::format( //
81+
auto print_text_report(auto&& output, const warning_message& msg) -> void {
82+
get_outputstream(output, std::cout) << std::format( //
7283
COLOR_YEL "WARNING:" COLOR_RESET " {}\n",
7384
msg.content
7485
);
7586
}
7687

77-
auto print_text_report(const success_message& msg) -> void {
78-
std::cout << std::format( //
88+
auto print_text_report(auto&& output, const success_message& msg) -> void {
89+
get_outputstream(output, std::cout) << std::format( //
7990
COLOR_GRN "SUCCESS:" COLOR_RESET " {}\n",
8091
msg.content
8192
);
8293
}
8394

84-
auto print_text_report(const module_methods_message& msg) -> void {
85-
std::cout << "MODULE METHODS FOR " << msg.module_name << ":\n";
95+
auto print_text_report(auto&& output, const module_methods_message& msg)
96+
-> void {
97+
get_outputstream(output, std::cout)
98+
<< "MODULE METHODS FOR " << msg.module_name << ":\n";
8699
for(auto& method : msg.methods) {
87100
std::cout //
88101
<< " " << (method.available ? COLOR_GRN "YES " : COLOR_RED " NO ")
89102
<< COLOR_RESET << method.method_name << "\n";
90103
}
91104
}
92105

93-
auto print_text_report(const subcommand_start_message& msg) -> void {
94-
std::cout << std::format( //
106+
auto print_text_report(auto&& output, const subcommand_start_message& msg)
107+
-> void {
108+
get_outputstream(output, std::cout) << std::format( //
95109
COLOR_BLU "SUBCOMMAND({}) START >>" COLOR_RESET " {} ",
96110
msg.id,
97111
msg.executable
@@ -102,32 +116,36 @@ auto print_text_report(const subcommand_start_message& msg) -> void {
102116
std::cout << "\n";
103117
}
104118

105-
auto print_text_report(const subcommand_stdout_message& msg) -> void {
106-
std::cout << std::format( //
119+
auto print_text_report(auto&& output, const subcommand_stdout_message& msg)
120+
-> void {
121+
get_outputstream(output, std::cout) << std::format( //
107122
COLOR_BLU "SUBCOMMAND({}) STDOUT:" COLOR_RESET " {}\n",
108123
msg.id,
109124
msg.line
110125
);
111126
}
112127

113-
auto print_text_report(const subcommand_stderr_message& msg) -> void {
114-
std::cout << std::format( //
128+
auto print_text_report(auto&& output, const subcommand_stderr_message& msg)
129+
-> void {
130+
get_outputstream(output, std::cout) << std::format( //
115131
COLOR_RED "SUBCOMMAND({}) STDERR:" COLOR_RESET " {}\n",
116132
msg.id,
117133
msg.line
118134
);
119135
}
120136

121-
auto print_text_report(const subcommand_progress_message& msg) -> void {
122-
std::cout << std::format( //
137+
auto print_text_report(auto&& output, const subcommand_progress_message& msg)
138+
-> void {
139+
get_outputstream(output, std::cout) << std::format( //
123140
COLOR_BLU "SUBCOMMAND({}) PROG:" COLOR_RESET " {}\n",
124141
msg.id,
125142
msg.description
126143
);
127144
}
128145

129-
auto print_text_report(const subcommand_end_message& msg) -> void {
130-
std::cout << std::format( //
146+
auto print_text_report(auto&& output, const subcommand_end_message& msg)
147+
-> void {
148+
get_outputstream(output, std::cout) << std::format( //
131149
COLOR_BLU "SUBCOMMAND({}) END << " COLOR_RESET " exit code {}\n",
132150
msg.id,
133151
msg.exit_code
@@ -138,5 +156,17 @@ auto print_text_report(const subcommand_end_message& msg) -> void {
138156
auto ecsact::cli::detail::text_report::operator()( //
139157
const message_variant_t& message
140158
) const -> void {
141-
std::visit([](const auto& message) { print_text_report(message); }, message);
159+
std::visit(
160+
[](const auto& message) { print_text_report(nullptr, message); },
161+
message
162+
);
163+
}
164+
165+
auto ecsact::cli::detail::text_report_stderr_only::operator()( //
166+
const message_variant_t& message
167+
) const -> void {
168+
std::visit(
169+
[](const auto& message) { print_text_report(std::cerr, message); },
170+
message
171+
);
142172
}

ecsact/cli/detail/text_report.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ namespace ecsact::cli::detail {
66
struct text_report {
77
auto operator()(const message_variant_t&) const -> void;
88
};
9+
10+
struct text_report_stderr_only {
11+
auto operator()(const message_variant_t&) const -> void;
12+
};
913
} // namespace ecsact::cli::detail

test/BUILD.bazel

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,38 @@ _TEST_PLUGINS = [
1414

1515
[cc_binary(
1616
name = "{}.so".format(plugin),
17-
linkshared = True,
18-
copts = copts,
19-
tags = ["manual"],
2017
srcs = [
2118
"{}.cc".format(plugin),
2219
"@ecsact_runtime//dylib:dylib.cc",
2320
],
21+
copts = copts,
22+
defines = ["ECSACT_META_API_LOAD_AT_RUNTIME"],
23+
linkshared = True,
24+
tags = ["manual"],
2425
deps = [
2526
"@ecsact_codegen//:plugin",
2627
"@ecsact_runtime//:dylib",
2728
"@ecsact_runtime//dylib:meta",
2829
"@ecsact_runtime//dylib:util",
2930
],
30-
defines = ["ECSACT_META_API_LOAD_AT_RUNTIME"],
3131
) for plugin in _TEST_PLUGINS]
3232

3333
[cc_binary(
3434
name = "{}.dll".format(plugin),
35-
linkshared = True,
36-
copts = copts,
37-
tags = ["manual"],
3835
srcs = [
3936
"{}.cc".format(plugin),
4037
"@ecsact_runtime//dylib:dylib.cc",
4138
],
39+
copts = copts,
40+
defines = ["ECSACT_META_API_LOAD_AT_RUNTIME"],
41+
linkshared = True,
42+
tags = ["manual"],
4243
deps = [
4344
"@ecsact_codegen//:plugin",
4445
"@ecsact_runtime//:dylib",
4546
"@ecsact_runtime//dylib:meta",
4647
"@ecsact_runtime//dylib:util",
4748
],
48-
defines = ["ECSACT_META_API_LOAD_AT_RUNTIME"],
4949
) for plugin in _TEST_PLUGINS]
5050

5151
[alias(
@@ -58,12 +58,12 @@ _TEST_PLUGINS = [
5858

5959
cc_test(
6060
name = "test_codegen",
61-
copts = copts,
6261
srcs = ["test_codegen.cc"],
62+
copts = copts,
6363
data = [
64-
"@ecsact_cli",
6564
"test.ecsact",
6665
":test_codegen_plugin",
66+
"@ecsact_cli",
6767
],
6868
env = {
6969
"TEST_ECSACT_CLI": "$(rootpath @ecsact_cli)",
@@ -79,13 +79,35 @@ cc_test(
7979
)
8080

8181
cc_test(
82-
name = "test_codegen_multi_output",
82+
name = "test_codegen_stdout",
83+
srcs = ["test_codegen_stdout.cc"],
8384
copts = copts,
84-
srcs = ["test_codegen_multi_output.cc"],
8585
data = [
86+
"test.ecsact",
87+
":test_codegen_plugin",
8688
"@ecsact_cli",
89+
],
90+
env = {
91+
"TEST_ECSACT_CLI": "$(rootpath @ecsact_cli)",
92+
"TEST_ECSACT_FILE_PATH": "$(rootpath test.ecsact)",
93+
"TEST_CODEGEN_PLUGIN_PATH": "$(rootpath :test_codegen_plugin)",
94+
},
95+
deps = [
96+
"@bazel_tools//tools/cpp/runfiles",
97+
"@boost.process",
98+
"@googletest//:gtest",
99+
"@googletest//:gtest_main",
100+
],
101+
)
102+
103+
cc_test(
104+
name = "test_codegen_multi_output",
105+
srcs = ["test_codegen_multi_output.cc"],
106+
copts = copts,
107+
data = [
87108
"test.ecsact",
88109
":test_codegen_plugin_multi_output",
110+
"@ecsact_cli",
89111
],
90112
env = {
91113
"TEST_ECSACT_CLI": "$(rootpath @ecsact_cli)",

0 commit comments

Comments
 (0)