Skip to content

Commit 967aed2

Browse files
Kelwanzaucy
andauthored
fix: error handling for codegen and recipe plugins work (#92)
Co-authored-by: Ezekiel Warren <[email protected]> Co-authored-by: Ezekiel Warren <[email protected]>
1 parent 249211c commit 967aed2

File tree

12 files changed

+168
-87
lines changed

12 files changed

+168
-87
lines changed

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ bazel_dep(name = "rules_pkg", version = "0.10.1")
1111
bazel_dep(name = "bazel_skylib", version = "1.6.1")
1212
bazel_dep(name = "ecsact_parse", version = "0.4.0")
1313
bazel_dep(name = "ecsact_runtime", version = "0.6.1")
14-
bazel_dep(name = "ecsact_interpret", version = "0.6.0")
14+
bazel_dep(name = "ecsact_interpret", version = "0.6.1")
1515
bazel_dep(name = "ecsact_codegen", version = "0.2.0")
1616
bazel_dep(name = "boost.dll", version = "1.83.0.bzl.2")
1717
bazel_dep(name = "magic_enum", version = "0.9.3")

MODULE.bazel.lock

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ecsact/cli/commands/build.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "docopt.h"
1212
#include "magic_enum.hpp"
1313
#include "ecsact/interpret/eval.hh"
14+
#include "ecsact/runtime/dynamic.h"
1415
#include "ecsact/runtime/meta.hh"
1516
#include "ecsact/cli/report.hh"
1617
#include "ecsact/cli/detail/argv0.hh"
@@ -207,6 +208,13 @@ auto ecsact::cli::detail::build_command( //
207208

208209
auto ec = std::error_code{};
209210
fs::remove_all(work_dir, ec);
211+
if(ec) {
212+
ecsact::cli::report_error(
213+
"Failed to clear work directory: {}",
214+
ec.message()
215+
);
216+
return 1;
217+
}
210218
fs::create_directories(work_dir, ec);
211219

212220
for(auto file : files) {
@@ -218,6 +226,9 @@ auto ecsact::cli::detail::build_command( //
218226
file_paths.emplace_back(file);
219227
}
220228

229+
if(auto main_pkg_id = ecsact::meta::main_package(); main_pkg_id) {
230+
ecsact_destroy_package(*main_pkg_id);
231+
}
221232
auto eval_errors = ecsact::eval_files(file_paths);
222233

223234
if(!eval_errors.empty()) {

ecsact/cli/commands/build/recipe/cook.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ static auto handle_source( //
189189
auto default_plugins_dir = ecsact::cli::get_default_plugins_dir();
190190
auto plugin_paths = std::vector<fs::path>{};
191191

192+
auto out_dir = fs::path(options.work_dir);
193+
194+
if(src.outdir) {
195+
auto outdir_path = fs::path(*src.outdir);
196+
out_dir = options.work_dir / outdir_path;
197+
}
198+
192199
for(auto plugin : src.plugins) {
193200
auto plugin_path = ecsact::cli::resolve_plugin_path({
194201
.plugin_arg = plugin,
@@ -199,11 +206,13 @@ static auto handle_source( //
199206
if(!plugin_path) {
200207
return 1;
201208
}
209+
210+
plugin_paths.push_back(*plugin_path);
202211
}
203212

204213
auto exit_code = ecsact::cli::codegen({
205214
.plugin_paths = plugin_paths,
206-
.outdir = src.outdir ? *src.outdir : "",
215+
.outdir = out_dir,
207216
});
208217

209218
return exit_code;

ecsact/cli/commands/codegen.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
#include <boost/dll/library_info.hpp>
1111
#include "docopt.h"
1212
#include "ecsact/interpret/eval.hh"
13-
#include "ecsact/runtime/meta.h"
13+
#include "ecsact/runtime/dynamic.h"
14+
#include "ecsact/runtime/meta.hh"
1415
#include "ecsact/runtime/dylib.h"
1516
#include "ecsact/codegen/plugin.h"
1617
#include "ecsact/codegen/plugin_validate.hh"
@@ -118,6 +119,9 @@ int ecsact::cli::detail::codegen_command(int argc, const char* argv[]) {
118119
return 1;
119120
}
120121

122+
if(auto main_pkg_id = ecsact::meta::main_package(); main_pkg_id) {
123+
ecsact_destroy_package(*main_pkg_id);
124+
}
121125
auto eval_errors = ecsact::eval_files(files);
122126
if(!eval_errors.empty()) {
123127
for(auto& eval_err : eval_errors) {

ecsact/cli/commands/codegen/BUILD.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ cc_library(
88
copts = copts,
99
hdrs = ["codegen.hh"],
1010
srcs = ["codegen.cc"],
11+
defines = [
12+
"ECSACT_DYNAMIC_API=\"\"",
13+
"ECSACT_META_API=\"\"",
14+
],
1115
deps = [
1216
":codegen_util",
1317
"//ecsact/cli:report",

ecsact/cli/commands/codegen/codegen.cc

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,16 @@
1313
namespace fs = std::filesystem;
1414
using namespace std::string_literals;
1515

16+
static thread_local std::ofstream file_write_stream;
17+
18+
static void file_write_fn(const char* str, int32_t str_len) {
19+
file_write_stream << std::string_view(str, str_len);
20+
}
21+
1622
auto ecsact::cli::codegen(codegen_options options) -> int {
1723
auto plugins = std::vector<boost::dll::shared_library>{};
24+
// key = plugin name, value = plugin path
25+
auto plugin_names = std::unordered_map<std::string, std::string>{};
1826

1927
auto unload_plugins = [&plugins] {
2028
for(auto& plugin : plugins) {
@@ -37,6 +45,16 @@ auto ecsact::cli::codegen(codegen_options options) -> int {
3745
unload_plugins();
3846
return 1;
3947
}
48+
49+
auto plugin_name_fn = plugin.get<decltype(ecsact_codegen_plugin_name)>(
50+
"ecsact_codegen_plugin_name"
51+
);
52+
std::string plugin_name = plugin_name_fn();
53+
if(plugin_names.contains(plugin_name)) {
54+
ecsact::cli::report_error("Multiple plugins with name '{}'", plugin_name);
55+
unload_plugins();
56+
return 1;
57+
}
4058
}
4159

4260
std::vector<ecsact_package_id> package_ids;
@@ -47,7 +65,8 @@ auto ecsact::cli::codegen(codegen_options options) -> int {
4765
nullptr
4866
);
4967

50-
auto output_paths = std::unordered_set<std::string>{};
68+
// key is output path, value is plugin responsible for generating it
69+
auto output_paths = std::unordered_map<std::string, std::string>{};
5170
auto has_plugin_error = false;
5271

5372
for(auto& plugin : plugins) {
@@ -101,9 +120,47 @@ auto ecsact::cli::codegen(codegen_options options) -> int {
101120
}
102121

103122
for(auto package_id : package_ids) {
104-
plugin_fn(package_id, options.output_write_fn);
105-
}
123+
fs::path output_file_path = ecsact_meta_package_file_path(package_id);
124+
if(output_file_path.empty()) {
125+
has_plugin_error = true;
126+
ecsact::cli::report_error( //
127+
"Could not find package source file path from "
128+
"ecsact_meta_package_file_path"
129+
);
130+
continue;
131+
}
132+
133+
output_file_path.replace_extension(
134+
output_file_path.extension().string() + "." + plugin_name
135+
);
136+
137+
if(output_paths.contains(output_file_path.string())) {
138+
has_plugin_error = true;
139+
auto conflicting_plugin_name = output_paths[output_file_path.string()];
140+
141+
ecsact::cli::report_error(
142+
"Plugin '{}' ({}) has conflicts with plugin '{}' output file "
143+
"{}",
144+
plugin_name,
145+
plugin.location().filename().string(),
146+
conflicting_plugin_name,
147+
output_file_path.string()
148+
);
149+
150+
continue;
151+
}
152+
output_paths.emplace(output_file_path.string(), plugin_name);
153+
if(fs::exists(output_file_path)) {
154+
fs::permissions(output_file_path, fs::perms::all);
155+
}
156+
157+
output_file_path = options.outdir / output_file_path.filename();
106158

159+
file_write_stream.open(output_file_path);
160+
plugin_fn(package_id, &file_write_fn);
161+
file_write_stream.flush();
162+
file_write_stream.close();
163+
}
107164
plugin.unload();
108165
}
109166
if(has_plugin_error) {

ecsact/cli/commands/codegen/codegen.hh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ using codegen_output_write_fn_t = void (*)(const char* str, int32_t str_len);
1212
struct codegen_options {
1313
std::vector<std::filesystem::path> plugin_paths;
1414
std::filesystem::path outdir;
15-
codegen_output_write_fn_t output_write_fn;
1615
};
1716

1817
auto codegen(codegen_options options) -> int;

test/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ cc_test(
6666
"TEST_CODEGEN_PLUGIN_PATH": "$(rootpath :test_codegen_plugin)",
6767
},
6868
deps = [
69-
"@ecsact_interpret",
7069
"@bazel_tools//tools/cpp/runfiles",
7170
"@ecsact_cli//ecsact/cli/commands:codegen",
7271
"@googletest//:gtest",

test/MODULE.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ bazel_dep(name = "ecsact_codegen", version = "0.2.0")
44
bazel_dep(name = "boost.dll", version = "1.83.0.bzl.2")
55
bazel_dep(name = "boost.process", version = "1.83.0.bzl.2")
66
bazel_dep(name = "ecsact_runtime", version = "0.6.1")
7-
bazel_dep(name = "ecsact_interpret", version = "0.6.0")
87

98
# TODO: https://github.com/bazelbuild/bazel-central-registry/pull/1916
109
git_override(

0 commit comments

Comments
 (0)