From ac3fa98e51fbde0996fa1cd4c2a2dbc7fc8a3ef0 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Mon, 25 May 2020 02:19:39 -0400 Subject: [PATCH] tasks will now delete their own git folders git will check for uncommitted changes before deleting added --ignore-uncommitted-changes --- mob.ini | 23 +++++++------ src/commands.cpp | 8 +++++ src/commands.h | 1 + src/conf.h | 5 +++ src/process.cpp | 1 - src/tasks/boost_di.cpp | 12 +++++++ src/tasks/gtest.cpp | 21 +++++++----- src/tasks/libffi.cpp | 12 +++++++ src/tasks/lz4.cpp | 6 ++++ src/tasks/modorganizer.cpp | 21 ++++++------ src/tasks/ncc.cpp | 12 ++++--- src/tasks/nmm.cpp | 12 ++++--- src/tasks/python.cpp | 6 ++++ src/tasks/spdlog.cpp | 12 +++++++ src/tasks/tasks.h | 3 ++ src/tasks/usvfs.cpp | 6 ++++ src/tools/git.cpp | 70 ++++++++++++++++++++++++++++---------- src/tools/tools.h | 7 ++-- 18 files changed, 177 insertions(+), 61 deletions(-) diff --git a/mob.ini b/mob.ini index 7b8bf1e..620d9b3 100644 --- a/mob.ini +++ b/mob.ini @@ -1,15 +1,16 @@ [global] -dry = false -redownload = false -reextract = false -reconfigure = false -rebuild = false -clean_task = true -fetch_task = true -build_task = true -output_log_level = 3 -file_log_level = 5 -log_file = mob.log +dry = false +redownload = false +reextract = false +reconfigure = false +rebuild = false +clean_task = true +fetch_task = true +build_task = true +output_log_level = 3 +file_log_level = 5 +log_file = mob.log +ignore_uncommitted = false [options] mo_org = ModOrganizer2 diff --git a/src/commands.cpp b/src/commands.cpp index b8a9907..bed7922 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -351,6 +351,11 @@ clipp::group build_command::do_group() ) % "whether to revert all the .ts files in a repo before pulling to " "avoid merge errors; global override", + (clipp::option("--ignore-uncommitted-changes") >> ignore_uncommitted_) + % "when --redownload or --reextract is given, directories " + "controlled by git will be deleted even if they contain " + "uncommitted changes", + (clipp::option("--keep-msbuild") >> keep_msbuild_) % "don't terminate msbuild.exe instances after building", @@ -376,6 +381,9 @@ void build_command::convert_cl_to_conf() if (rebuild_ || new_) common.options.push_back("global/rebuild=true"); + if (ignore_uncommitted_) + common.options.push_back("global/ignore_uncommitted=true"); + if (clean_) { if (*clean_) diff --git a/src/commands.h b/src/commands.h index 8f8e191..dc1573a 100644 --- a/src/commands.h +++ b/src/commands.h @@ -118,6 +118,7 @@ private: std::optional fetch_; std::optional build_; std::optional nopull_; + bool ignore_uncommitted_ = false; bool keep_msbuild_ = false; std::optional revert_ts_; diff --git a/src/conf.h b/src/conf.h index 2ac6679..f23d992 100644 --- a/src/conf.h +++ b/src/conf.h @@ -60,6 +60,11 @@ public: static bool fetch() { return bool_global_by_name("fetch_task"); } static bool build() { return bool_global_by_name("build_task"); } + static bool ignore_uncommitted() + { + return bool_global_by_name("ignore_uncommitted"); + } + static std::vector format_options(); private: diff --git a/src/process.cpp b/src/process.cpp index 2f86262..c24833d 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -68,7 +68,6 @@ std::string_view async_pipe::read(bool finish) if (finish && s.empty()) { - cx_.trace(context::cmd, "read: finish=true and read is empty, closing"); ::CancelIo(stdout_.get()); closed_ = true; } diff --git a/src/tasks/boost_di.cpp b/src/tasks/boost_di.cpp index 0fa5afe..8dc3b15 100644 --- a/src/tasks/boost_di.cpp +++ b/src/tasks/boost_di.cpp @@ -24,6 +24,18 @@ fs::path boost_di::source_path() return paths::build() / "di"; } +void boost_di::do_clean(clean c) +{ + instrument([&] + { + if (is_any_set(c, clean::redownload|clean::reextract)) + { + git::delete_directory(cx(), source_path()); + return; + } + }); +} + void boost_di::do_fetch() { instrument([&] diff --git a/src/tasks/gtest.cpp b/src/tasks/gtest.cpp index 0a37da1..9de770e 100644 --- a/src/tasks/gtest.cpp +++ b/src/tasks/gtest.cpp @@ -26,23 +26,26 @@ fs::path gtest::source_path() void gtest::do_clean(clean c) { - if (is_set(c, clean::reconfigure)) + instrument([&] { - instrument([&] + if (is_any_set(c, clean::redownload|clean::reextract)) + { + git::delete_directory(cx(), source_path()); + return; + } + + if (is_set(c, clean::reconfigure)) { run_tool(create_cmake_tool(arch::x86, cmake::clean)); run_tool(create_cmake_tool(arch::x64, cmake::clean)); - }); - } + } - if (is_set(c, clean::rebuild)) - { - instrument([&] + if (is_set(c, clean::rebuild)) { run_tool(create_msbuild_tool(arch::x86, msbuild::clean)); run_tool(create_msbuild_tool(arch::x64, msbuild::clean)); - }); - } + } + }); } void gtest::do_fetch() diff --git a/src/tasks/libffi.cpp b/src/tasks/libffi.cpp index 455335b..7c1a35f 100644 --- a/src/tasks/libffi.cpp +++ b/src/tasks/libffi.cpp @@ -24,6 +24,18 @@ fs::path libffi::source_path() return paths::build() / "libffi"; } +void libffi::do_clean(clean c) +{ + instrument([&] + { + if (is_any_set(c, clean::redownload|clean::reextract)) + { + git::delete_directory(cx(), source_path()); + return; + } + }); +} + void libffi::do_fetch() { instrument([&] diff --git a/src/tasks/lz4.cpp b/src/tasks/lz4.cpp index 269079e..0587b20 100644 --- a/src/tasks/lz4.cpp +++ b/src/tasks/lz4.cpp @@ -42,6 +42,12 @@ void lz4::do_clean(clean c) } else { + if (is_any_set(c, clean::redownload|clean::reextract)) + { + git::delete_directory(cx(), source_path()); + return; + } + if (is_set(c, clean::rebuild)) run_tool(create_msbuild_tool(msbuild::clean)); } diff --git a/src/tasks/modorganizer.cpp b/src/tasks/modorganizer.cpp index 159b7fa..b96b04f 100644 --- a/src/tasks/modorganizer.cpp +++ b/src/tasks/modorganizer.cpp @@ -62,21 +62,20 @@ fs::path modorganizer::super_path() void modorganizer::do_clean(clean c) { - if (is_set(c, clean::reconfigure)) + instrument([&] { - instrument([&] + if (is_any_set(c, clean::redownload|clean::reextract)) { - run_tool(create_this_cmake_tool(cmake::clean)); - }); - } + git::delete_directory(cx(), this_source_path()); + return; + } - if (is_set(c, clean::rebuild)) - { - instrument([&] - { + if (is_set(c, clean::reconfigure)) + run_tool(create_this_cmake_tool(cmake::clean)); + + if (is_set(c, clean::rebuild)) run_tool(create_this_msbuild_tool(msbuild::clean)); - }); - } + }); } void modorganizer::do_fetch() diff --git a/src/tasks/ncc.cpp b/src/tasks/ncc.cpp index c2f77c8..fd923b7 100644 --- a/src/tasks/ncc.cpp +++ b/src/tasks/ncc.cpp @@ -26,13 +26,17 @@ fs::path ncc::source_path() void ncc::do_clean(clean c) { - if (is_set(c, clean::rebuild)) + instrument([&] { - instrument([&] + if (is_any_set(c, clean::redownload|clean::reextract)) { + git::delete_directory(cx(), source_path()); + return; + } + + if (is_set(c, clean::rebuild)) run_tool(create_msbuild_tool(msbuild::clean)); - }); - } + }); } void ncc::do_fetch() diff --git a/src/tasks/nmm.cpp b/src/tasks/nmm.cpp index bfc6e9d..e80b23a 100644 --- a/src/tasks/nmm.cpp +++ b/src/tasks/nmm.cpp @@ -26,13 +26,17 @@ fs::path nmm::source_path() void nmm::do_clean(clean c) { - if (is_set(c, clean::rebuild)) + instrument([&] { - instrument([&] + if (is_any_set(c, clean::redownload|clean::reextract)) { + git::delete_directory(cx(), source_path()); + return; + } + + if (is_set(c, clean::rebuild)) run_tool(create_msbuild_tool(msbuild::clean)); - }); - } + }); } void nmm::do_fetch() diff --git a/src/tasks/python.cpp b/src/tasks/python.cpp index 3858ffc..96cc608 100644 --- a/src/tasks/python.cpp +++ b/src/tasks/python.cpp @@ -80,6 +80,12 @@ void python::do_clean(clean c) } else { + if (is_any_set(c, clean::redownload|clean::reextract)) + { + git::delete_directory(cx(), source_path()); + return; + } + if (is_set(c, clean::rebuild)) run_tool(create_msbuild_tool(msbuild::clean)); } diff --git a/src/tasks/spdlog.cpp b/src/tasks/spdlog.cpp index 6245b5a..c0dc578 100644 --- a/src/tasks/spdlog.cpp +++ b/src/tasks/spdlog.cpp @@ -24,6 +24,18 @@ fs::path spdlog::source_path() return paths::build() / ("spdlog-" + version()); } +void spdlog::do_clean(clean c) +{ + instrument([&] + { + if (is_any_set(c, clean::redownload|clean::reextract)) + { + git::delete_directory(cx(), source_path()); + return; + } + }); +} + void spdlog::do_fetch() { instrument([&] diff --git a/src/tasks/tasks.h b/src/tasks/tasks.h index c32efa3..76d2ebd 100644 --- a/src/tasks/tasks.h +++ b/src/tasks/tasks.h @@ -76,6 +76,7 @@ public: static fs::path source_path(); protected: + void do_clean(clean c) override; void do_fetch() override; }; @@ -214,6 +215,7 @@ public: static fs::path lib_path(); protected: + void do_clean(clean c) override; void do_fetch() override; }; @@ -531,6 +533,7 @@ public: static fs::path source_path(); protected: + void do_clean(clean c) override; void do_fetch() override; }; diff --git a/src/tasks/usvfs.cpp b/src/tasks/usvfs.cpp index 1ed9254..ddfb15e 100644 --- a/src/tasks/usvfs.cpp +++ b/src/tasks/usvfs.cpp @@ -48,6 +48,12 @@ void usvfs::do_clean(clean c) } else { + if (is_any_set(c, clean::redownload|clean::reextract)) + { + git::delete_directory(cx(), source_path()); + return; + } + if (is_set(c, clean::rebuild)) { op::delete_directory(cx(), source_path() / "bin", op::optional); diff --git a/src/tools/git.cpp b/src/tools/git.cpp index d9d5d71..6fd1013 100644 --- a/src/tools/git.cpp +++ b/src/tools/git.cpp @@ -12,6 +12,32 @@ git::git(ops o) { } +void git::delete_directory(const context& cx, const fs::path& p) +{ + git g(no_op); + g.root(p); + + if (!conf::ignore_uncommitted()) + { + if (g.has_uncommitted_changes()) + { + cx.bail_out(context::redownload, + "will not delete {}, has uncommitted changes; " + "see --ignore-uncommitted-changes", p); + } + + if (g.has_stashed_changes()) + { + cx.bail_out(context::redownload, + "will not delete {}, has stashed changes; " + "see --ignore-uncommitted-changes", p); + } + } + + cx.trace(context::redownload, "deleting directory controlled by git{}", p); + op::delete_directory(cx, p, op::optional); +} + void git::set_credentials( const fs::path& repo, const std::string& username, const std::string& email) @@ -215,30 +241,14 @@ void git::do_add_submodule() execute_and_join(); } -void git::delete_root_if_needed() -{ - if (conf::redownload() || conf::reextract()) - { - if (fs::exists(root_)) - { - cx().trace(context::rebuild, "deleting directory controlled by git"); - op::delete_directory(cx(), root_, op::optional); - } - } -} - void git::do_clone_or_pull() { - delete_root_if_needed(); - if (!do_clone()) do_pull(); } bool git::do_clone() { - delete_root_if_needed(); - const fs::path dot_git = root_ / ".git"; if (fs::exists(dot_git)) { @@ -278,8 +288,6 @@ bool git::do_clone() void git::do_pull() { - delete_root_if_needed(); - if (revert_ts_) do_revert_ts(); @@ -482,6 +490,32 @@ bool git::is_repo() return (execute_and_join() == 0); } +bool git::has_uncommitted_changes() +{ + process_ = make_process() + .flags(process::allow_failure) + .stdout_flags(process::keep_in_string) + .arg("status") + .arg("-s") + .arg("--porcelain") + .cwd(root_); + + execute_and_join(); + + return (process_.stdout_string() != ""); +} + +bool git::has_stashed_changes() +{ + process_ = make_process() + .flags(process::allow_failure) + .stderr_level(context::level::trace) + .arg("stash show") + .cwd(root_); + + return (execute_and_join() == 0); +} + void git::init() { process_ = make_process() diff --git a/src/tools/tools.h b/src/tools/tools.h index 5a25a77..57ac45e 100644 --- a/src/tools/tools.h +++ b/src/tools/tools.h @@ -159,6 +159,8 @@ public: git(ops o); + static void delete_directory(const context& cx, const fs::path& p); + static fs::path binary(); static void set_credentials( @@ -226,7 +228,6 @@ private: void do_ignore_ts(); void do_revert_ts(); - void delete_root_if_needed(); void set_config(const std::string& key, const std::string& value); bool has_remote(const std::string& name); void rename_remote(const std::string& from, const std::string& to); @@ -235,6 +236,8 @@ private: void set_assume_unchanged(const fs::path& relative_file, bool on); bool is_tracked(const fs::path& relative_file); bool is_repo(); + bool has_uncommitted_changes(); + bool has_stashed_changes(); void init(); std::string git_file(); @@ -397,8 +400,6 @@ private: void do_clean(); void do_generate(); - fs::path real_output_path(); - static const std::map& all_generators(); static const gen_info& get_generator(generators g); };