Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add create file error handling #127

Merged
merged 4 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ecsact/cli/commands/build/recipe/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ cc_library(
"//ecsact/cli/detail:download",
"//ecsact/cli/detail:glob",
"//ecsact/cli/detail:archive",
"//ecsact/cli/detail:long_path_workaround",
"//ecsact/cli/commands/build:build_recipe",
"//ecsact/cli/commands/build:cc_compiler_config",
"//ecsact/cli/commands/build:cc_defines_gen",
Expand Down
12 changes: 12 additions & 0 deletions ecsact/cli/commands/build/recipe/cook.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "ecsact/cli/detail/download.hh"
#include "ecsact/cli/detail/glob.hh"
#include "ecsact/cli/detail/archive.hh"
#include "ecsact/cli/detail/long_path_workaround.hh"
#ifndef ECSACT_CLI_USE_SDK_VERSION
# include "tools/cpp/runfiles/runfiles.h"
#endif
Expand All @@ -34,6 +35,7 @@ using ecsact::cli::report_warning;
using ecsact::cli::detail::download_file;
using ecsact::cli::detail::expand_path_globs;
using ecsact::cli::detail::integrity;
using ecsact::cli::detail::long_path_workaround;
using ecsact::cli::detail::path_before_glob;
using ecsact::cli::detail::path_matches_glob;
using ecsact::cli::detail::path_strip_prefix;
Expand Down Expand Up @@ -286,6 +288,8 @@ static auto handle_source( //
src_path = (base_directory / src_path).lexically_normal();
}

src_path = long_path_workaround(src_path);

auto outdir = src.outdir //
? options.work_dir / *src.outdir
: options.work_dir;
Expand Down Expand Up @@ -490,6 +494,10 @@ auto clang_gcc_compile(compile_options options) -> int {
continue;
}

if(src.extension().string() == ".ipp") {
continue;
}

compile_proc_args.push_back(fs::relative(src, options.work_dir).string());
}

Expand Down Expand Up @@ -630,6 +638,10 @@ auto cl_compile(compile_options options) -> int {
continue;
}

if(src.extension().string() == ".ipp") {
continue;
}

cl_args.push_back(abs_from_wd(src).string());
}

Expand Down
1 change: 1 addition & 0 deletions ecsact/cli/commands/recipe-bundle/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ cc_library(
"//ecsact/cli/commands/codegen",
"//ecsact/cli/commands/build:build_recipe",
"//ecsact/cli/detail:download",
"//ecsact/cli/detail:long_path_workaround",
"//ecsact/cli:report",
],
)
56 changes: 47 additions & 9 deletions ecsact/cli/commands/recipe-bundle/build_recipe_bundle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <filesystem>
#include <fstream>
#include <vector>
#include <cerrno>
#include <span>
#include <ratio>
#include <cstddef>
Expand All @@ -18,11 +19,13 @@
#include <archive.h>
#include <archive_entry.h>
#include "xxhash.h"

#include "ecsact/cli/report.hh"
#include "ecsact/cli/detail/download.hh"
#include "ecsact/cli/detail/long_path_workaround.hh"
#include "ecsact/cli/commands/codegen/codegen_util.hh"

using ecsact::cli::detail::long_path_workaround;

using namespace std::string_literals;
using namespace std::string_view_literals;
namespace fs = std::filesystem;
Expand Down Expand Up @@ -87,7 +90,7 @@ static auto is_valid_bundle_entry_path(std::string_view path) -> bool {

static auto read_file(fs::path path) -> std::optional<std::vector<std::byte>> {
auto ec = std::error_code{};
auto file_size = fs::file_size(path, ec);
auto file_size = fs::file_size(long_path_workaround(path), ec);
if(ec) {
ecsact::cli::report_error(
"failed to read file size {}: {}",
Expand All @@ -96,7 +99,7 @@ static auto read_file(fs::path path) -> std::optional<std::vector<std::byte>> {
);
return {};
}
auto file = std::ifstream{path, std::ios_base::binary};
auto file = std::ifstream{long_path_workaround(path), std::ios_base::binary};
if(!file) {
ecsact::cli::report_error(
"failed to open file file for reading {}",
Expand All @@ -117,15 +120,46 @@ static auto read_file(fs::path path) -> std::optional<std::vector<std::byte>> {
return file_buffer;
}

static auto write_file(fs::path path, std::span<std::byte> data) -> void {
if(path.has_parent_path()) {
static auto write_file(fs::path path, std::span<std::byte> data) -> bool {
if(path.has_parent_path() && !fs::exists(path.parent_path())) {
auto ec = std::error_code{};
fs::create_directories(path.parent_path(), ec);
fs::create_directories(long_path_workaround(path.parent_path()), ec);
if(ec) {
ecsact::cli::report_error(
"failed to create directory {}: {}",
path.generic_string(),
ec.message()
);
return false;
}
}

auto file = std::ofstream{
long_path_workaround(path),
std::ios::binary | std::ios::trunc
};
if(!file) {
ecsact::cli::report_error(
"failed to open file {}: {}",
path.generic_string(),
std::strerror(errno)
);
return false;
}
auto file = std::ofstream(path, std::ios_base::binary | std::ios_base::trunc);
assert(file);

file.write(reinterpret_cast<const char*>(data.data()), data.size());

if(!file) {
ecsact::cli::report_error(
"failed to write file {}: {}",
path.generic_string(),
std::strerror(errno)
);
return false;
}

file.flush();
return true;
}

ecsact::build_recipe_bundle::build_recipe_bundle() = default;
Expand Down Expand Up @@ -399,7 +433,11 @@ auto ecsact::build_recipe_bundle::extract( //
return std::logic_error{std::format("Failed to read {}", path)};
}

write_file(dir / path, data);
if(!write_file(dir / path, data)) {
return std::logic_error{
std::format("Failed to extract {}", (dir / path).generic_string())
};
}
}

archive_entry_free(entry);
Expand Down
7 changes: 7 additions & 0 deletions ecsact/cli/detail/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,10 @@ cc_library(
"@boost.process",
],
)

cc_library(
name = "long_path_workaround",
copts = copts,
hdrs = ["long_path_workaround.hh"],
srcs = ["long_path_workaround.cc"],
)
17 changes: 17 additions & 0 deletions ecsact/cli/detail/long_path_workaround.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "ecsact/cli/detail/long_path_workaround.hh"

auto ecsact::cli::detail::long_path_workaround( //
std::filesystem::path p
) -> std::filesystem::path {
#if _WIN32
auto win_path_str = "\\\\?\\" + std::filesystem::absolute(p).string();
for(auto& c : win_path_str) {
if(c == '/') {
c = '\\';
}
}
return win_path_str;
#else
return p;
#endif
}
13 changes: 13 additions & 0 deletions ecsact/cli/detail/long_path_workaround.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <filesystem>

namespace ecsact::cli::detail {

/**
* The Ecsact CLI isn't built with long path awareness on Windows. This utility
* function returns an absolute //?/ prefixed path on Windows and on other
* platforms does nothing.
*/
auto long_path_workaround(std::filesystem::path p) -> std::filesystem::path;
} // namespace ecsact::cli::detail