Skip to content

Commit c327d24

Browse files
authored
feat: new codegen flag for printing output paths (#141)
1 parent d3c0cae commit c327d24

File tree

8 files changed

+125
-4
lines changed

8 files changed

+125
-4
lines changed

ecsact/cli/commands/codegen.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ constexpr auto USAGE = R"(Ecsact Codegen Command
2828
2929
Usage:
3030
ecsact codegen <files>... --plugin=<plugin> [--stdout]
31-
ecsact codegen <files>... --plugin=<plugin>... [--outdir=<directory>] [--format=<type>] [--report_filter=<filter>]
31+
ecsact codegen <files>... --plugin=<plugin>... [--outdir=<directory>] [--format=<type>] [--report_filter=<filter>] [--print-output-files]
3232
3333
Options:
3434
-p, --plugin=<plugin> Name of bundled plugin or path to plugin.
3535
--stdout Print to stdout instead of writing to a file. May only be used if a single ecsact file and single ecsact codegen plugin are used.
3636
-o, --outdir=<directory> Specify directory generated files should be written to. By default generated files are written next to source files.
3737
-f --format=<type> The format used to report progress of the build [default: text]
3838
--report_filter=<filter> Filtering out report logs [default: none]
39+
--print-output-files Simply print output file paths to stdout. No codegen will occur.
3940
)";
4041

4142
static auto stdout_write_fn(
@@ -54,6 +55,8 @@ int ecsact::cli::detail::codegen_command(int argc, const char* argv[]) {
5455
return exit_code;
5556
}
5657

58+
auto only_print_output_files = args.at("--print-output-files").asBool();
59+
5760
auto files_error = false;
5861
auto files_str = args.at("<files>").asStringList();
5962
auto files = std::vector<fs::path>{};
@@ -158,6 +161,7 @@ int ecsact::cli::detail::codegen_command(int argc, const char* argv[]) {
158161
auto codegen_options = ecsact::cli::codegen_options{
159162
.plugin_paths = plugin_paths,
160163
.outdir = outdir,
164+
.only_print_output_files = only_print_output_files,
161165
};
162166

163167
if(args.at("--stdout").asBool()) {

ecsact/cli/commands/codegen/codegen.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,16 @@ 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+
if(options.only_print_output_files) {
260+
for(auto& output_file_path : plugin_output_paths) {
261+
report(output_path_message{
262+
fs::weakly_canonical(output_file_path).generic_string()
263+
});
264+
}
265+
plugin.unload();
266+
continue;
267+
}
268+
259269
if(options.write_fn) {
260270
if(plugin_output_paths.size() > 1) {
261271
// TODO: this error can be misleading if a non-stdout custom
@@ -266,8 +276,6 @@ auto ecsact::cli::codegen(codegen_options options) -> int {
266276

267277
plugin_fn(package_id, *options.write_fn, &codegen_report_fn);
268278
} else {
269-
auto write_fn = options.write_fn.value_or(&file_write_fn);
270-
271279
for(auto filename_index = 0;
272280
plugin_output_paths.size() > filename_index;
273281
++filename_index) {

ecsact/cli/commands/codegen/codegen.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ struct codegen_options {
1111
std::vector<std::filesystem::path> plugin_paths;
1212
std::optional<std::filesystem::path> outdir;
1313
std::optional<ecsact_codegen_write_fn_t> write_fn;
14+
bool only_print_output_files;
1415
};
1516

1617
auto codegen(codegen_options options) -> int;

ecsact/cli/detail/json_report.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(subcommand_stdout_message, id, line)
1818
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(subcommand_stderr_message, id, line)
1919
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(subcommand_progress_message, id, description)
2020
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(subcommand_end_message, id, exit_code)
21+
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(output_path_message, output_path)
2122
// clang-format on
2223
} // namespace ecsact::cli
2324

ecsact/cli/detail/text_report.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ using ecsact::cli::ecsact_error_message;
88
using ecsact::cli::error_message;
99
using ecsact::cli::info_message;
1010
using ecsact::cli::module_methods_message;
11+
using ecsact::cli::output_path_message;
1112
using ecsact::cli::subcommand_end_message;
1213
using ecsact::cli::subcommand_progress_message;
1314
using ecsact::cli::subcommand_start_message;
@@ -151,6 +152,10 @@ auto print_text_report(auto&& output, const subcommand_end_message& msg)
151152
msg.exit_code
152153
);
153154
}
155+
156+
auto print_text_report(auto&& output, const output_path_message& msg) -> void {
157+
get_outputstream(output, std::cout) << msg.output_path << "\n";
158+
}
154159
} // namespace
155160

156161
auto ecsact::cli::detail::text_report::operator()( //

ecsact/cli/report_message.hh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ struct subcommand_end_message {
101101
int exit_code;
102102
};
103103

104+
struct output_path_message {
105+
static constexpr auto type = std::string_view{"output_path"};
106+
std::string output_path;
107+
};
108+
104109
using message_variant_t = std::variant<
105110
alert_message,
106111
info_message,
@@ -113,5 +118,6 @@ using message_variant_t = std::variant<
113118
subcommand_stdout_message,
114119
subcommand_stderr_message,
115120
subcommand_progress_message,
116-
subcommand_end_message>;
121+
subcommand_end_message,
122+
output_path_message>;
117123
} // namespace ecsact::cli

test/BUILD.bazel

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,29 @@ cc_test(
7878
],
7979
)
8080

81+
cc_test(
82+
name = "test_codegen_print_outputs",
83+
srcs = ["test_codegen_print_outputs.cc"],
84+
copts = copts,
85+
data = [
86+
"test.ecsact",
87+
":test_codegen_plugin",
88+
":test_codegen_plugin_multi_output",
89+
"@ecsact_cli",
90+
],
91+
env = {
92+
"TEST_ECSACT_CLI": "$(rootpath @ecsact_cli)",
93+
"TEST_ECSACT_FILE_PATH": "$(rootpath test.ecsact)",
94+
"TEST_CODEGEN_PLUGIN_PATH": "$(rootpath :test_codegen_plugin_multi_output)",
95+
},
96+
deps = [
97+
"@bazel_tools//tools/cpp/runfiles",
98+
"@boost.process",
99+
"@googletest//:gtest",
100+
"@googletest//:gtest_main",
101+
],
102+
)
103+
81104
cc_test(
82105
name = "test_codegen_stdout",
83106
srcs = ["test_codegen_stdout.cc"],

test/test_codegen_print_outputs.cc

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <gtest/gtest.h>
2+
#include <string>
3+
#include <vector>
4+
#include <format>
5+
#include <ranges>
6+
#include <filesystem>
7+
#include <fstream>
8+
#include <boost/process.hpp>
9+
#include "tools/cpp/runfiles/runfiles.h"
10+
11+
using bazel::tools::cpp::runfiles::Runfiles;
12+
using namespace std::string_literals;
13+
namespace fs = std::filesystem;
14+
namespace bp = boost::process;
15+
16+
TEST(Codegen, Stdout) {
17+
auto runfiles_err = std::string{};
18+
auto runfiles = Runfiles::CreateForTest(&runfiles_err);
19+
auto test_ecsact_cli = std::getenv("TEST_ECSACT_CLI");
20+
auto test_codegen_plugin_path = std::getenv("TEST_CODEGEN_PLUGIN_PATH");
21+
auto test_ecsact_file_path = std::getenv("TEST_ECSACT_FILE_PATH");
22+
23+
ASSERT_NE(test_ecsact_cli, nullptr);
24+
ASSERT_NE(test_codegen_plugin_path, nullptr);
25+
ASSERT_NE(test_ecsact_file_path, nullptr);
26+
ASSERT_NE(runfiles, nullptr) << runfiles_err;
27+
ASSERT_TRUE(fs::exists(test_codegen_plugin_path));
28+
ASSERT_TRUE(fs::exists(test_ecsact_file_path));
29+
30+
// this file should NOT be generated
31+
auto bad_generated_file_path = fs::path{"test.txt"s};
32+
if(fs::exists(bad_generated_file_path)) {
33+
fs::remove(bad_generated_file_path);
34+
}
35+
36+
auto proc_stdout = bp::ipstream{};
37+
auto proc = bp::child{
38+
bp::exe(test_ecsact_cli),
39+
bp::args({
40+
"codegen"s,
41+
std::string{test_ecsact_file_path},
42+
std::format("--plugin={}", test_codegen_plugin_path),
43+
"--print-output-files"s,
44+
}),
45+
bp::std_out > proc_stdout
46+
};
47+
48+
proc.wait();
49+
50+
auto exit_code = proc.exit_code();
51+
ASSERT_EQ(exit_code, 0);
52+
53+
auto output_files = std::vector<std::string>{};
54+
auto line = std::string{};
55+
while(std::getline(proc_stdout, line)) {
56+
if(line.ends_with("\r")) {
57+
line.pop_back();
58+
}
59+
output_files.emplace_back(line);
60+
}
61+
62+
EXPECT_EQ(output_files.size(), 2);
63+
64+
EXPECT_FALSE(
65+
std::ranges::find(output_files, "test.txt") == output_files.end()
66+
);
67+
EXPECT_FALSE(
68+
std::ranges::find(output_files, "test.zomsky") == output_files.end()
69+
);
70+
EXPECT_FALSE(fs::exists(bad_generated_file_path))
71+
<< bad_generated_file_path.string()
72+
<< " was generated even with --print-output-files option!";
73+
}

0 commit comments

Comments
 (0)