Skip to content

Commit

Permalink
feat: recipe bundle command
Browse files Browse the repository at this point in the history
  • Loading branch information
zaucy committed Apr 30, 2024
1 parent b99cc9d commit 43bb338
Show file tree
Hide file tree
Showing 12 changed files with 488 additions and 84 deletions.
6 changes: 6 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ bazel_dep(name = "boost.process", version = "1.83.0.bzl.2")
bazel_dep(name = "boost.algorithm", version = "1.83.0.bzl.1")
bazel_dep(name = "boost.url", version = "1.83.0.bzl.2")
bazel_dep(name = "yaml-cpp", version = "0.8.0")
bazel_dep(name = "libarchive", version = "3.7.2.bcr.4")
git_override(
module_name = "libarchive",
remote = "https://github.com/zaucy/libarchive.git",
commit = "ff54c610fde57bb5b47b34b972c90300f758e054",
)

bazel_dep(name = "toolchains_llvm", version = "1.0.0", dev_dependency = True)
bazel_dep(name = "hedron_compile_commands", dev_dependency = True)
Expand Down
350 changes: 272 additions & 78 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions bazel/common.bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ startup --windows_enable_symlinks
common --enable_bzlmod
common --registry=https://raw.githubusercontent.com/ecsact-dev/bazel_registry/main
common --registry=https://raw.githubusercontent.com/bazelboost/registry/main
common --registry=https://raw.githubusercontent.com/zaucy/bazel-central-registry/bzip2-include-dir # temporary for this PR until https://github.com/bazelbuild/bazel-central-registry/pull/1865 is merged
common --registry=https://bcr.bazel.build
build --enable_platform_specific_config
build --incompatible_enable_cc_toolchain_resolution
Expand Down
3 changes: 2 additions & 1 deletion ecsact/cli/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
load("//bazel/tools:cc_stamp_header.bzl", "cc_stamp_header")
load("//bazel:copts.bzl", "copts")
load("//bazel/tools:cc_stamp_header.bzl", "cc_stamp_header")

package(default_visibility = ["//:__subpackages__"])

Expand Down Expand Up @@ -44,5 +44,6 @@ cc_binary(
"//ecsact/cli/commands:command",
"//ecsact/cli/commands:config",
"//ecsact/cli/commands:build",
"//ecsact/cli/commands:recipe-bundle",
],
)
20 changes: 20 additions & 0 deletions ecsact/cli/commands/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,23 @@ cc_library(
"@magic_enum",
],
)

cc_library(
name = "recipe-bundle",
srcs = ["recipe-bundle.cc"],
hdrs = ["recipe-bundle.hh"],
copts = copts,
deps = [
":command",
"//ecsact/cli:report",
"//ecsact/cli:report_message",
"//ecsact/cli/detail:json_report",
"//ecsact/cli/detail:text_report",
"//ecsact/cli/commands/build:build_recipe",
"//ecsact/cli/commands/recipe-bundle:build_recipe_bundle",
"//ecsact/cli/detail:argv0",
"@ecsact_interpret",
"@docopt.cpp//:docopt",
"@magic_enum",
],
)
121 changes: 121 additions & 0 deletions ecsact/cli/commands/recipe-bundle.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include "ecsact/cli/commands/recipe-bundle.hh"

#include <memory>
#include <iostream>
#include <format>
#include <filesystem>
#include <variant>
#include <string_view>
#include <format>
#include "docopt.h"
#include "magic_enum.hpp"
#include "ecsact/cli/report.hh"
#include "ecsact/cli/detail/argv0.hh"
#include "ecsact/cli/detail/json_report.hh"
#include "ecsact/cli/detail/text_report.hh"
#include "ecsact/cli/commands/build/build_recipe.hh"

namespace fs = std::filesystem;

using namespace std::string_view_literals;

constexpr auto USAGE = R"docopt(Ecsact Recipe Bundle Command
Usage:
ecsact recipe-bundle (-h | --help)
ecsact recipe-bundle <recipe>... --output=<path> [--format=<type>] [--report_filter=<filter>]
Options:
<recipe> Name or path to recipe
-o --output=<path> Recipe bundle output path
-f --format=<type> The format used to report progress of the build [default: text]
--report_filter=<filter> Filtering out report logs [default: none]
)docopt";

// TODO(zaucy): Add this documentation to docopt (msvc regex fails)
// Allowed Formats:
// none : No output
// json : Each line of stdout/stderr is a JSON object
// text : Human readable text format

auto ecsact::cli::detail::recipe_bundle_command( //
int argc,
const char* argv[]
) -> int {
auto args = docopt::docopt(USAGE, {argv + 1, argv + argc});
auto format = args["--format"].asString();
auto exec_path = canon_argv0(argv[0]);

if(format == "text") {
set_report_handler(text_report{});
} else if(format == "json") {
set_report_handler(json_report{});
} else if(format == "none") {
set_report_handler({});
} else {
std::cerr << "Invalid --format value: " << format << "\n";
std::cout << USAGE;
return 1;
}

auto report_filter = args["--report_filter"].asString();
if(report_filter == "none") {
set_report_filter(report_filter::none);
} else if(report_filter == "error_only") {
set_report_filter(report_filter::error_only);
} else if(report_filter == "errors_and_warnings") {
set_report_filter(report_filter::errors_and_warnings);
} else {
std::cerr << "Invalid --report_filter value: " << report_filter << "\n";
std::cout << USAGE;
return 1;
}

auto output_path = fs::path{args.at("--output").asString()};

auto recipe_composite = std::optional<build_recipe>{};
auto recipe_paths = args.at("<recipe>").asStringList();
for(auto recipe_path : args.at("<recipe>").asStringList()) {
auto recipe_result = build_recipe::from_yaml_file(recipe_path);

if(std::holds_alternative<build_recipe_parse_error>(recipe_result)) {
auto recipe_error = std::get<build_recipe_parse_error>(recipe_result);
ecsact::cli::report_error(
"Recipe Error {}",
magic_enum::enum_name(recipe_error)
);
return 1;
}

auto recipe = std::move(std::get<build_recipe>(recipe_result));
if(!recipe_composite) {
recipe_composite.emplace(std::move(recipe));
} else {
auto merge_result = build_recipe::merge(*recipe_composite, recipe);
if(std::holds_alternative<build_recipe_merge_error>(merge_result)) {
auto merge_error = std::get<build_recipe_merge_error>(merge_result);
ecsact::cli::report_error(
"Recipe Merge Error {}",
magic_enum::enum_name(merge_error)
);
return 1;
}

recipe_composite.emplace(std::get<build_recipe>(std::move(merge_result)));
}
}

if(!recipe_composite) {
ecsact::cli::report_error("No recipes");
return 1;
}

auto additional_plugin_dirs = std::vector<fs::path>{};
for(fs::path recipe_path : recipe_paths) {
if(recipe_path.has_parent_path()) {
additional_plugin_dirs.emplace_back(recipe_path.parent_path());
}
}

return 0;
}
23 changes: 23 additions & 0 deletions ecsact/cli/commands/recipe-bundle.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

#pragma once

#include <type_traits>
#include <vector>
#include <string>

#include "./command.hh"

namespace ecsact::cli::detail {

int recipe_bundle_command(int argc, const char* argv[]);
static_assert(std::is_same_v<command_fn_t, decltype(&recipe_bundle_command)>);

inline auto recipe_bundle_command(std::vector<std::string> args) -> int {
auto c_args = std::vector<const char*>();
c_args.reserve(args.size());
for(auto& arg : args) {
c_args.emplace_back(arg.c_str());
}
return recipe_bundle_command(c_args.size(), c_args.data());
}
} // namespace ecsact::cli::detail
15 changes: 15 additions & 0 deletions ecsact/cli/commands/recipe-bundle/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
load("//bazel:copts.bzl", "copts")

package(default_visibility = ["//:__subpackages__"])

cc_library(
name = "build_recipe_bundle",
copts = copts,
hdrs = ["build_recipe_bundle.hh"],
srcs = ["build_recipe_bundle.cc"],
deps = [
"@libarchive//tar",
"//ecsact/cli/commands/build:build_recipe",
],
)
9 changes: 9 additions & 0 deletions ecsact/cli/commands/recipe-bundle/build_recipe_bundle.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "ecsact/cli/commands/recipe-bundle/build_recipe_bundle.hh"

#include <archive.h>

auto ecsact::build_recipe_bundle::create( //
const build_recipe& recipe
) -> build_recipe_bundle {
return {};
}
12 changes: 12 additions & 0 deletions ecsact/cli/commands/recipe-bundle/build_recipe_bundle.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include "ecsact/cli/commands/build/build_recipe.hh"

namespace ecsact {

class build_recipe_bundle {
public:
static auto create(const build_recipe& recipe) -> build_recipe_bundle;
};

} // namespace ecsact
3 changes: 3 additions & 0 deletions ecsact/cli/ecsact_cli.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "ecsact/cli/bazel_stamp_header.hh"
#include "ecsact/cli/commands/build.hh"
#include "ecsact/cli/commands/codegen.hh"
#include "ecsact/cli/commands/recipe-bundle.hh"
#include "ecsact/cli/commands/command.hh"
#include "ecsact/cli/commands/config.hh"

Expand Down Expand Up @@ -35,6 +36,7 @@ constexpr auto USAGE = R"(Ecsact SDK Command Line
ecsact build ([<options>...] | --help)
ecsact codegen ([<options>...] | --help)
ecsact config ([<options>...] | --help)
ecsact recipe-bundle ([<options>...] | --help)
)";

std::string colorize_logo() {
Expand Down Expand Up @@ -77,6 +79,7 @@ int main(int argc, const char* argv[]) {
{"build", &ecsact::cli::detail::build_command},
{"codegen", &ecsact::cli::detail::codegen_command},
{"config", &ecsact::cli::detail::config_command},
{"recipe-bundle", &ecsact::cli::detail::recipe_bundle_command},
};

if(argc >= 2) {
Expand Down
9 changes: 4 additions & 5 deletions test/build_recipe/test.nu
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
let dir = $env.FILE_PWD;
let ecsact_file = $dir + '/test.ecsact';
let recipe_file = $dir + '/example-recipe.yml';
let output_file = $dir + '/tmp/test';
let recipe_file = $dir + '/test-recipe.yml';
let recipe_bundle_file = $dir + '/test-recipe.tar';
let temp_dir = $dir + '/tmp';

# bazel run @ecsact_cli -- build $ecsact_file -r $recipe_file -o $output_file --temp_dir $temp_dir -f text
ecsact build $ecsact_file -r $recipe_file -o $output_file --temp_dir $temp_dir -f text
bazel run @ecsact_cli -- recipe-bundle $recipe_file -o $recipe_bundle_file -f text
# ecsact build $ecsact_file -r $recipe_file -o $output_file --temp_dir $temp_dir -f text

0 comments on commit 43bb338

Please # to comment.