diff --git a/ecsact/cli/commands/codegen.cc b/ecsact/cli/commands/codegen.cc index 45cf3ee..38f56a8 100644 --- a/ecsact/cli/commands/codegen.cc +++ b/ecsact/cli/commands/codegen.cc @@ -28,7 +28,7 @@ constexpr auto USAGE = R"(Ecsact Codegen Command Usage: ecsact codegen ... --plugin= [--stdout] - ecsact codegen ... --plugin=... [--outdir=] [--format=] [--report_filter=] + ecsact codegen ... --plugin=... [--outdir=] [--format=] [--report_filter=] [--print-output-files] Options: -p, --plugin= Name of bundled plugin or path to plugin. @@ -36,6 +36,7 @@ constexpr auto USAGE = R"(Ecsact Codegen Command -o, --outdir= Specify directory generated files should be written to. By default generated files are written next to source files. -f --format= The format used to report progress of the build [default: text] --report_filter= Filtering out report logs [default: none] + --print-output-files Simply print output file paths to stdout. No codegen will occur. )"; static auto stdout_write_fn( @@ -54,6 +55,8 @@ int ecsact::cli::detail::codegen_command(int argc, const char* argv[]) { return exit_code; } + auto only_print_output_files = args.at("--print-output-files").asBool(); + auto files_error = false; auto files_str = args.at("").asStringList(); auto files = std::vector{}; @@ -158,6 +161,7 @@ int ecsact::cli::detail::codegen_command(int argc, const char* argv[]) { auto codegen_options = ecsact::cli::codegen_options{ .plugin_paths = plugin_paths, .outdir = outdir, + .only_print_output_files = only_print_output_files, }; if(args.at("--stdout").asBool()) { diff --git a/ecsact/cli/commands/codegen/codegen.cc b/ecsact/cli/commands/codegen/codegen.cc index 90c406b..2657709 100644 --- a/ecsact/cli/commands/codegen/codegen.cc +++ b/ecsact/cli/commands/codegen/codegen.cc @@ -256,6 +256,16 @@ auto ecsact::cli::codegen(codegen_options options) -> int { // We're filling this in the for loop. We shouldn't have any in here. assert(file_write_streams.empty()); + if(options.only_print_output_files) { + for(auto& output_file_path : plugin_output_paths) { + report(output_path_message{ + fs::weakly_canonical(output_file_path).generic_string() + }); + } + plugin.unload(); + continue; + } + if(options.write_fn) { if(plugin_output_paths.size() > 1) { // TODO: this error can be misleading if a non-stdout custom @@ -266,8 +276,6 @@ auto ecsact::cli::codegen(codegen_options options) -> int { plugin_fn(package_id, *options.write_fn, &codegen_report_fn); } else { - auto write_fn = options.write_fn.value_or(&file_write_fn); - for(auto filename_index = 0; plugin_output_paths.size() > filename_index; ++filename_index) { diff --git a/ecsact/cli/commands/codegen/codegen.hh b/ecsact/cli/commands/codegen/codegen.hh index 66510a3..90019a7 100644 --- a/ecsact/cli/commands/codegen/codegen.hh +++ b/ecsact/cli/commands/codegen/codegen.hh @@ -11,6 +11,7 @@ struct codegen_options { std::vector plugin_paths; std::optional outdir; std::optional write_fn; + bool only_print_output_files; }; auto codegen(codegen_options options) -> int; diff --git a/ecsact/cli/detail/json_report.cc b/ecsact/cli/detail/json_report.cc index 5402231..c9bfb31 100644 --- a/ecsact/cli/detail/json_report.cc +++ b/ecsact/cli/detail/json_report.cc @@ -18,6 +18,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(subcommand_stdout_message, id, line) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(subcommand_stderr_message, id, line) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(subcommand_progress_message, id, description) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(subcommand_end_message, id, exit_code) +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(output_path_message, output_path) // clang-format on } // namespace ecsact::cli diff --git a/ecsact/cli/detail/text_report.cc b/ecsact/cli/detail/text_report.cc index d8aa878..9ac7c78 100644 --- a/ecsact/cli/detail/text_report.cc +++ b/ecsact/cli/detail/text_report.cc @@ -8,6 +8,7 @@ using ecsact::cli::ecsact_error_message; using ecsact::cli::error_message; using ecsact::cli::info_message; using ecsact::cli::module_methods_message; +using ecsact::cli::output_path_message; using ecsact::cli::subcommand_end_message; using ecsact::cli::subcommand_progress_message; using ecsact::cli::subcommand_start_message; @@ -151,6 +152,10 @@ auto print_text_report(auto&& output, const subcommand_end_message& msg) msg.exit_code ); } + +auto print_text_report(auto&& output, const output_path_message& msg) -> void { + get_outputstream(output, std::cout) << msg.output_path << "\n"; +} } // namespace auto ecsact::cli::detail::text_report::operator()( // diff --git a/ecsact/cli/report_message.hh b/ecsact/cli/report_message.hh index 8e5a288..b0a7c5b 100644 --- a/ecsact/cli/report_message.hh +++ b/ecsact/cli/report_message.hh @@ -101,6 +101,11 @@ struct subcommand_end_message { int exit_code; }; +struct output_path_message { + static constexpr auto type = std::string_view{"output_path"}; + std::string output_path; +}; + using message_variant_t = std::variant< alert_message, info_message, @@ -113,5 +118,6 @@ using message_variant_t = std::variant< subcommand_stdout_message, subcommand_stderr_message, subcommand_progress_message, - subcommand_end_message>; + subcommand_end_message, + output_path_message>; } // namespace ecsact::cli diff --git a/test/BUILD.bazel b/test/BUILD.bazel index 05b410d..8308249 100644 --- a/test/BUILD.bazel +++ b/test/BUILD.bazel @@ -78,6 +78,29 @@ cc_test( ], ) +cc_test( + name = "test_codegen_print_outputs", + srcs = ["test_codegen_print_outputs.cc"], + copts = copts, + data = [ + "test.ecsact", + ":test_codegen_plugin", + ":test_codegen_plugin_multi_output", + "@ecsact_cli", + ], + env = { + "TEST_ECSACT_CLI": "$(rootpath @ecsact_cli)", + "TEST_ECSACT_FILE_PATH": "$(rootpath test.ecsact)", + "TEST_CODEGEN_PLUGIN_PATH": "$(rootpath :test_codegen_plugin_multi_output)", + }, + deps = [ + "@bazel_tools//tools/cpp/runfiles", + "@boost.process", + "@googletest//:gtest", + "@googletest//:gtest_main", + ], +) + cc_test( name = "test_codegen_stdout", srcs = ["test_codegen_stdout.cc"], diff --git a/test/test_codegen_print_outputs.cc b/test/test_codegen_print_outputs.cc new file mode 100644 index 0000000..9cb69c1 --- /dev/null +++ b/test/test_codegen_print_outputs.cc @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "tools/cpp/runfiles/runfiles.h" + +using bazel::tools::cpp::runfiles::Runfiles; +using namespace std::string_literals; +namespace fs = std::filesystem; +namespace bp = boost::process; + +TEST(Codegen, Stdout) { + auto runfiles_err = std::string{}; + auto runfiles = Runfiles::CreateForTest(&runfiles_err); + auto test_ecsact_cli = std::getenv("TEST_ECSACT_CLI"); + auto test_codegen_plugin_path = std::getenv("TEST_CODEGEN_PLUGIN_PATH"); + auto test_ecsact_file_path = std::getenv("TEST_ECSACT_FILE_PATH"); + + ASSERT_NE(test_ecsact_cli, nullptr); + ASSERT_NE(test_codegen_plugin_path, nullptr); + ASSERT_NE(test_ecsact_file_path, nullptr); + ASSERT_NE(runfiles, nullptr) << runfiles_err; + ASSERT_TRUE(fs::exists(test_codegen_plugin_path)); + ASSERT_TRUE(fs::exists(test_ecsact_file_path)); + + // this file should NOT be generated + auto bad_generated_file_path = fs::path{"test.txt"s}; + if(fs::exists(bad_generated_file_path)) { + fs::remove(bad_generated_file_path); + } + + auto proc_stdout = bp::ipstream{}; + auto proc = bp::child{ + bp::exe(test_ecsact_cli), + bp::args({ + "codegen"s, + std::string{test_ecsact_file_path}, + std::format("--plugin={}", test_codegen_plugin_path), + "--print-output-files"s, + }), + bp::std_out > proc_stdout + }; + + proc.wait(); + + auto exit_code = proc.exit_code(); + ASSERT_EQ(exit_code, 0); + + auto output_files = std::vector{}; + auto line = std::string{}; + while(std::getline(proc_stdout, line)) { + if(line.ends_with("\r")) { + line.pop_back(); + } + output_files.emplace_back(line); + } + + EXPECT_EQ(output_files.size(), 2); + + EXPECT_FALSE( + std::ranges::find(output_files, "test.txt") == output_files.end() + ); + EXPECT_FALSE( + std::ranges::find(output_files, "test.zomsky") == output_files.end() + ); + EXPECT_FALSE(fs::exists(bad_generated_file_path)) + << bad_generated_file_path.string() + << " was generated even with --print-output-files option!"; +}