diff --git a/lib/utils/mu-test-utils.cc b/lib/utils/mu-test-utils.cc index 694ddd0e..c6f728bc 100644 --- a/lib/utils/mu-test-utils.cc +++ b/lib/utils/mu-test-utils.cc @@ -1,5 +1,5 @@ /* -** Copyright (C) 2008-2022 Dirk-Jan C. Binnema +** Copyright (C) 2008-2023 Dirk-Jan C. Binnema ** ** This program is free software; you can redistribute it and/or modify it ** under the terms of the GNU General Public License as published by the @@ -29,7 +29,9 @@ #include #include +#include "utils/mu-utils.hh" #include "utils/mu-test-utils.hh" +#include "utils/mu-utils-file.hh" #include "utils/mu-error.hh" @@ -115,15 +117,29 @@ Mu::allow_warnings() -Mu::TempDir::TempDir(bool autodelete): autodelete_{autodelete} +Result +Mu::run_mu_command(const std::string& args) { - GError *err{}; - gchar *tmpdir = g_dir_make_tmp("mu-tmp-XXXXXX", &err); - if (!tmpdir) - throw Mu::Error(Error::Code::File, &err, - "failed to create temporary directory"); + auto cmdline{mu_format("/bin/sh -c '{} {}'", MU_PROGRAM, args)}; + if (g_test_verbose()) + mu_println("command-line: {}", cmdline); + + GError *err{}; + int wait_status{}; + if (!g_spawn_command_line_sync(cmdline.c_str(), {}, {}, &wait_status, &err)) + return Err(Error::Code::File, &err, "failed to execute command '{}", cmdline); + else + return Ok(WEXITSTATUS(wait_status)); +} + + +Mu::TempDir::TempDir(bool autodelete): autodelete_{autodelete} { + + if (auto res{make_temp_dir()}; !res) + throw res.error(); + else + path_ = std::move(*res); - path_ = to_string_gchar(std::move(tmpdir)); mu_debug("created '{}'", path_); } @@ -139,8 +155,9 @@ Mu::TempDir::~TempDir() /* ugly */ GError *err{}; - const auto cmd{fmt::format("/bin/rm -rf '{}'", path_)}; - if (!g_spawn_command_line_sync(cmd.c_str(), NULL, NULL, NULL, &err)) { + const auto cmd{mu_format("/bin/rm -rf '{}'", path_)}; + if (!g_spawn_command_line_sync(cmd.c_str(), NULL, + NULL, NULL, &err)) { mu_warning("error: {}", err ? err->message : "?"); g_clear_error(&err); } else diff --git a/lib/utils/mu-test-utils.hh b/lib/utils/mu-test-utils.hh index 84743bd4..c1368da3 100644 --- a/lib/utils/mu-test-utils.hh +++ b/lib/utils/mu-test-utils.hh @@ -22,6 +22,7 @@ #include #include +#include namespace Mu { @@ -97,6 +98,18 @@ bool set_en_us_utf8_locale(); void allow_warnings(); + +/** + * Execute the in-tree mu executable with the arguments + * Asserts if fails. + * + * @param args arguments;; + * + * @return either the exit code or an error. + */ +Result run_mu_command(const std::string& args); + + /** * For unit-tests, a RAII tempdir. * diff --git a/lib/utils/mu-utils-file.cc b/lib/utils/mu-utils-file.cc index 4922a789..82399ebb 100644 --- a/lib/utils/mu-utils-file.cc +++ b/lib/utils/mu-utils-file.cc @@ -147,6 +147,33 @@ Mu::canonicalize_filename(const std::string& path, const std::string& relative_t return str; } +Result +Mu::make_temp_dir() +{ + GError *err{}; + if (auto tmpdir{g_dir_make_tmp("mu-tmp-XXXXXX", &err)}; !tmpdir) + return Err(Error::Code::File, &err, + "failed to create temporary directory"); + else + return Ok(to_string_gchar(std::move(tmpdir))); +} + + +Result +Mu::remove_directory(const std::string& path) +{ + /* ugly */ + GError *err{}; + const auto cmd{mu_format("/bin/rm -rf '{}'", path)}; + if (!g_spawn_command_line_sync(cmd.c_str(), NULL, + NULL, NULL, &err)) + return Err(Error::Code::File, &err, "failed to remove {}", path); + else + return Ok(); +} + + + std::string Mu::runtime_path(Mu::RuntimePath path, const std::string& muhome) diff --git a/lib/utils/mu-utils-file.hh b/lib/utils/mu-utils-file.hh index df70d892..c922a68c 100644 --- a/lib/utils/mu-utils-file.hh +++ b/lib/utils/mu-utils-file.hh @@ -26,6 +26,7 @@ #include #include +#include #include namespace Mu { @@ -136,8 +137,9 @@ enum struct RuntimePath { * @return the path name */ std::string runtime_path(RuntimePath path, const std::string& muhome=""); + /** - * Join path components into a path (with '/') + * Join path components into a path (with '/') * * @param s a string-convertible value * @param args 0 or more string-convertible values @@ -176,6 +178,23 @@ GCancellable* g_cancellable_new_with_timeout(guint timeout); */ Result read_from_stdin(); +/** + * Create a randomly-named temporary directory + * + * @return name of the temporary directory or an error. + */ +Result make_temp_dir(); + + +/** + * Remove a directory, recursively. Does not have to be empty. + * + * @param path path to directory + * + * @return Ok() or an error. + */ +Result remove_directory(const std::string& path); + } // namespace Mu