diff --git a/libmamba/CMakeLists.txt b/libmamba/CMakeLists.txt index 2aa5747eca..ae4c7ca564 100644 --- a/libmamba/CMakeLists.txt +++ b/libmamba/CMakeLists.txt @@ -120,6 +120,7 @@ set(LIBMAMBA_SOURCES ${LIBMAMBA_SOURCE_DIR}/version.cpp # C++ utility library ${LIBMAMBA_SOURCE_DIR}/util/string.cpp + ${LIBMAMBA_SOURCE_DIR}/util/path_manip.cpp ${LIBMAMBA_SOURCE_DIR}/util/url_manip.cpp ${LIBMAMBA_SOURCE_DIR}/util/url.cpp # C++ wrapping of libsolv @@ -208,6 +209,7 @@ set(LIBMAMBA_PUBLIC_HEADERS ${LIBMAMBA_INCLUDE_DIR}/mamba/version.hpp # Utility library ${LIBMAMBA_INCLUDE_DIR}/mamba/util/deprecation.hpp + ${LIBMAMBA_INCLUDE_DIR}/mamba/util/build.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/cast.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/compare.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/functional.hpp @@ -218,6 +220,7 @@ set(LIBMAMBA_PUBLIC_HEADERS ${LIBMAMBA_INCLUDE_DIR}/mamba/util/graph.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/iterator.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/string.hpp + ${LIBMAMBA_INCLUDE_DIR}/mamba/util/path_manip.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/url_manip.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/url.hpp # Implementation of version and matching specs diff --git a/libmamba/include/mamba/core/link.hpp b/libmamba/include/mamba/core/link.hpp index 824867b22b..53534ef807 100644 --- a/libmamba/include/mamba/core/link.hpp +++ b/libmamba/include/mamba/core/link.hpp @@ -12,7 +12,7 @@ #include #include -#include "nlohmann/json.hpp" +#include "mamba/util/build.hpp" #include "mamba_fs.hpp" #include "match_spec.hpp" @@ -35,7 +35,7 @@ namespace mamba "(.*))$"); // the rest of the line can contain option // flags and end whole_shebang group - constexpr size_t MAX_SHEBANG_LENGTH = on_linux ? 127 : 512; + constexpr std::size_t MAX_SHEBANG_LENGTH = util::on_linux ? 127 : 512; struct python_entry_point_parsed { diff --git a/libmamba/include/mamba/core/util.hpp b/libmamba/include/mamba/core/util.hpp index 0efd9aaf40..2e6ccec986 100644 --- a/libmamba/include/mamba/core/util.hpp +++ b/libmamba/include/mamba/core/util.hpp @@ -33,22 +33,6 @@ namespace mamba { -#if __APPLE__ || __MACH__ - static constexpr bool on_win = false; - static constexpr bool on_linux = false; - static constexpr bool on_mac = true; -#elif __linux__ - static constexpr bool on_win = false; - static constexpr bool on_linux = true; - static constexpr bool on_mac = false; -#elif _WIN32 - static constexpr bool on_win = true; - static constexpr bool on_linux = false; - static constexpr bool on_mac = false; -#else -#error "no supported OS detected" -#endif - // Used when we want a callback which does nothing. struct no_op { diff --git a/libmamba/include/mamba/util/build.hpp b/libmamba/include/mamba/util/build.hpp new file mode 100644 index 0000000000..5c0df390cc --- /dev/null +++ b/libmamba/include/mamba/util/build.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2023, QuantStack and Mamba Contributors +// +// Distributed under the terms of the BSD 3-Clause License. +// +// The full license is in the file LICENSE, distributed with this software. + +#ifndef MAMBA_UTIL_BUILD_HPP +#define MAMBA_UTIL_BUILD_HPP + +namespace mamba::util +{ +#if __APPLE__ || __MACH__ + inline static constexpr bool on_win = false; + inline static constexpr bool on_linux = false; + inline static constexpr bool on_mac = true; +#elif __linux__ + inline static constexpr bool on_win = false; + inline static constexpr bool on_linux = true; + inline static constexpr bool on_mac = false; +#elif _WIN32 + inline static constexpr bool on_win = true; + inline static constexpr bool on_linux = false; + inline static constexpr bool on_mac = false; +#else +#error "no supported OS detected" +#endif +} +#endif diff --git a/libmamba/include/mamba/util/path_manip.hpp b/libmamba/include/mamba/util/path_manip.hpp new file mode 100644 index 0000000000..c698a5ff3c --- /dev/null +++ b/libmamba/include/mamba/util/path_manip.hpp @@ -0,0 +1,43 @@ +// Copyright (c) 2023, QuantStack and Mamba Contributors +// +// Distributed under the terms of the BSD 3-Clause License. +// +// The full license is in the file LICENSE, distributed with this software. + +#ifndef MAMBA_UTIL_PATH_MANIP_HPP +#define MAMBA_UTIL_PATH_MANIP_HPP + +#include +#include + +namespace mamba::util +{ + inline static constexpr char preferred_path_separator_posix = '/'; + inline static constexpr char preferred_path_separator_win = '\\'; + + /** + * Return true is the input is explicitly a path. + * + * Explicit path are: + * - Absolute path + * - Path starting with '~' + * - Relative paths starting with "./" or "../" + */ + [[nodiscard]] auto is_explicit_path(std::string_view input) -> bool; + + /** + * Check if a Windows path (not URL) starts with a drive letter. + */ + [[nodiscard]] auto path_has_drive_letter(std::string_view path) -> bool; + + /** + * Convert the Windows path separators to Posix ones. + */ + [[nodiscard]] auto path_win_to_posix(std::string path) -> std::string; + + /** + * Convert the Windows path separators to Posix ones on Windows only. + */ + [[nodiscard]] auto path_to_posix(std::string path) -> std::string; +} +#endif diff --git a/libmamba/include/mamba/util/url_manip.hpp b/libmamba/include/mamba/util/url_manip.hpp index 911960e682..38f8de87d3 100644 --- a/libmamba/include/mamba/util/url_manip.hpp +++ b/libmamba/include/mamba/util/url_manip.hpp @@ -59,11 +59,6 @@ namespace mamba::util */ [[nodiscard]] auto url_has_scheme(std::string_view url) -> bool; - /** - * Check if a Windows path (not URL) starts with a drive letter. - */ - [[nodiscard]] auto path_has_drive_letter(std::string_view path) -> bool; - void split_anaconda_token(const std::string& url, std::string& cleaned_url, std::string& token); void split_scheme_auth_token( @@ -76,7 +71,6 @@ namespace mamba::util bool compare_cleaned_url(const std::string& url1, const std::string& url2); - bool is_path(const std::string& input); std::string path_to_url(const std::string& path); template diff --git a/libmamba/src/api/configuration.cpp b/libmamba/src/api/configuration.cpp index 77050f0379..999b809db9 100644 --- a/libmamba/src/api/configuration.cpp +++ b/libmamba/src/api/configuration.cpp @@ -19,6 +19,7 @@ #include "mamba/core/fsutil.hpp" #include "mamba/core/output.hpp" #include "mamba/core/package_download.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/string.hpp" namespace mamba @@ -1779,7 +1780,7 @@ namespace mamba auto& ctx = Context::instance(); std::vector system; - if constexpr (on_mac || on_linux) + if constexpr (util::on_mac || util::on_linux) { system = { "/etc/conda/.condarc", "/etc/conda/condarc", "/etc/conda/condarc.d/", "/etc/conda/.mambarc", diff --git a/libmamba/src/core/activation.cpp b/libmamba/src/core/activation.cpp index 2896f2c34a..6052d55458 100644 --- a/libmamba/src/core/activation.cpp +++ b/libmamba/src/core/activation.cpp @@ -10,6 +10,7 @@ #include "mamba/core/output.hpp" #include "mamba/core/shell_init.hpp" #include "mamba/core/util.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/string.hpp" namespace mamba @@ -207,7 +208,7 @@ namespace mamba std::vector get_path_dirs(const fs::u8path& prefix) { - if (on_win) + if (util::on_win) { return { prefix, prefix / "Library" / "mingw-w64" / "bin", @@ -725,7 +726,7 @@ namespace mamba std::stringstream out; if (!env_transform.export_path.empty()) { - if (on_win) + if (util::on_win) { out << "export PATH='" << native_path_to_unix(env_transform.export_path, /*is_a_env_path=*/true) @@ -754,7 +755,7 @@ namespace mamba for (const auto& [ekey, evar] : env_transform.export_vars) { - if (on_win && ekey == "PATH") + if (util::on_win && ekey == "PATH") { out << "export " << ekey << "='" << native_path_to_unix(evar, /*is_a_env_path=*/true) << "'\n"; @@ -844,7 +845,7 @@ namespace mamba std::stringstream out; if (!env_transform.export_path.empty()) { - if (on_win) + if (util::on_win) { out << "setenv PATH '" << native_path_to_unix(env_transform.export_path, /*is_a_env_path=*/true) @@ -873,7 +874,7 @@ namespace mamba for (const auto& [ekey, evar] : env_transform.export_vars) { - if (on_win && ekey == "PATH") + if (util::on_win && ekey == "PATH") { out << "setenv " << ekey << " '" << native_path_to_unix(evar, /*is_a_env_path=*/true) << "';\n"; diff --git a/libmamba/src/core/channel.cpp b/libmamba/src/core/channel.cpp index 35fae7cac7..10961fd485 100644 --- a/libmamba/src/core/channel.cpp +++ b/libmamba/src/core/channel.cpp @@ -19,6 +19,7 @@ #include "mamba/core/package_cache.hpp" #include "mamba/core/util_os.hpp" #include "mamba/core/validate.hpp" +#include "mamba/util/path_manip.hpp" #include "mamba/util/string.hpp" #include "mamba/util/url.hpp" #include "mamba/util/url_manip.hpp" @@ -578,10 +579,10 @@ namespace mamba std::string value = in_value; auto platforms = take_platforms(value); - auto chan = util::url_has_scheme(value) ? from_url(fix_win_path(value)) - : util::is_path(value) ? from_url(util::path_to_url(value)) - : is_package_file(value) ? from_url(fix_win_path(value)) - : from_name(value); + auto chan = util::url_has_scheme(value) ? from_url(fix_win_path(value)) + : util::is_explicit_path(value) ? from_url(util::path_to_url(value)) + : is_package_file(value) ? from_url(fix_win_path(value)) + : from_name(value); chan.m_platforms = std::move(platforms); diff --git a/libmamba/src/core/fetch.cpp b/libmamba/src/core/fetch.cpp index b42ff34941..f391f68738 100644 --- a/libmamba/src/core/fetch.cpp +++ b/libmamba/src/core/fetch.cpp @@ -12,6 +12,7 @@ #include "mamba/core/fetch.hpp" #include "mamba/core/output.hpp" #include "mamba/core/thread_utils.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/string.hpp" #include "mamba/util/url.hpp" #include "mamba/util/url_manip.hpp" @@ -144,7 +145,7 @@ namespace mamba ctx.remote_fetch_params.ssl_verify = std::getenv("REQUESTS_CA_BUNDLE"); LOG_INFO << "Using REQUESTS_CA_BUNDLE " << ctx.remote_fetch_params.ssl_verify; } - else if (ctx.remote_fetch_params.ssl_verify == "" && on_linux) + else if (ctx.remote_fetch_params.ssl_verify == "" && util::on_linux) { std::array cert_locations{ "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. diff --git a/libmamba/src/core/link.cpp b/libmamba/src/core/link.cpp index 1c82376a9e..047d26b2d4 100644 --- a/libmamba/src/core/link.cpp +++ b/libmamba/src/core/link.cpp @@ -21,6 +21,7 @@ #include "mamba/core/transaction_context.hpp" #include "mamba/core/util_os.hpp" #include "mamba/core/validate.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/string.hpp" #if _WIN32 @@ -315,7 +316,7 @@ namespace mamba ) { fs::u8path path; - if (on_win) + if (util::on_win) { path = prefix / get_bin_directory_short_path() / util::concat(".", pkg_info.name, "-", action, ".bat"); @@ -345,7 +346,7 @@ namespace mamba std::vector command_args; std::unique_ptr script_file; - if (on_win) + if (util::on_win) { ensure_comspec_set(); auto comspec = env::get("COMSPEC"); @@ -625,7 +626,7 @@ namespace mamba buffer = read_contents(src, std::ios::in | std::ios::binary); util::replace_all(buffer, path_data.prefix_placeholder, new_prefix); - if constexpr (!on_win) // only on non-windows platforms + if constexpr (!util::on_win) // only on non-windows platforms { // we need to check the first line for a shebang and replace it if it's too long if (buffer[0] == '#' && buffer[1] == '!') @@ -1052,7 +1053,7 @@ namespace mamba } // Create all start menu shortcuts if prefix name doesn't start with underscore - if (on_win && Context::instance().shortcuts + if (util::on_win && Context::instance().shortcuts && m_context->target_prefix.filename().string()[0] != '_') { for (auto& path : paths_data) diff --git a/libmamba/src/core/shell_init.cpp b/libmamba/src/core/shell_init.cpp index 777cbed886..6aa3c34e2f 100644 --- a/libmamba/src/core/shell_init.cpp +++ b/libmamba/src/core/shell_init.cpp @@ -25,6 +25,7 @@ #include "mamba/core/shell_init.hpp" #include "mamba/core/util.hpp" #include "mamba/core/util_os.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/string.hpp" namespace mamba @@ -332,7 +333,7 @@ namespace mamba std::stringstream content; std::string s_mamba_exe; - if (on_win) + if (util::on_win) { s_mamba_exe = native_path_to_unix(mamba_exe.string()); } @@ -364,7 +365,7 @@ namespace mamba std::stringstream content; std::string s_mamba_exe; - if (on_win) + if (util::on_win) { s_mamba_exe = native_path_to_unix(mamba_exe.string()); } @@ -388,7 +389,7 @@ namespace mamba std::stringstream content; std::string s_mamba_exe; - if (on_win) + if (util::on_win) { s_mamba_exe = native_path_to_unix(mamba_exe.string()); } @@ -1024,7 +1025,8 @@ namespace mamba // initializing conda in .bash_profile. // On Windows, there are multiple ways to open bash depending on how it was installed. // Git Bash, Cygwin, and MSYS2 all use .bash_profile by default. - fs::u8path bashrc_path = (on_mac || on_win) ? home / ".bash_profile" : home / ".bashrc"; + fs::u8path bashrc_path = (util::on_mac || util::on_win) ? home / ".bash_profile" + : home / ".bashrc"; modify_rc_file(bashrc_path, conda_prefix, shell, mamba_exe); } else if (shell == "zsh") @@ -1092,7 +1094,8 @@ namespace mamba fs::u8path home = env::home_directory(); if (shell == "bash") { - fs::u8path bashrc_path = (on_mac || on_win) ? home / ".bash_profile" : home / ".bashrc"; + fs::u8path bashrc_path = (util::on_mac || util::on_win) ? home / ".bash_profile" + : home / ".bashrc"; reset_rc_file(bashrc_path, shell, mamba_exe); } else if (shell == "zsh") @@ -1150,7 +1153,7 @@ namespace mamba fs::u8path config_path; if (shell == "bash") { - config_path = (on_mac || on_win) ? home / ".bash_profile" : home / ".bashrc"; + config_path = (util::on_mac || util::on_win) ? home / ".bash_profile" : home / ".bashrc"; } else if (shell == "zsh") { diff --git a/libmamba/src/core/singletons.cpp b/libmamba/src/core/singletons.cpp index b0bf5006ac..826c86e98f 100644 --- a/libmamba/src/core/singletons.cpp +++ b/libmamba/src/core/singletons.cpp @@ -15,6 +15,7 @@ extern "C" #include "mamba/core/execution.hpp" #include "mamba/core/output.hpp" #include "mamba/core/validate.hpp" +#include "mamba/util/build.hpp" #include "spdlog/spdlog.h" @@ -46,11 +47,11 @@ namespace mamba CURLsslset sslset_res; const curl_ssl_backend** available_backends; - if (on_linux) + if (util::on_linux) { sslset_res = curl_global_sslset(CURLSSLBACKEND_OPENSSL, nullptr, &available_backends); } - else if (on_mac) + else if (util::on_mac) { sslset_res = curl_global_sslset( CURLSSLBACKEND_SECURETRANSPORT, @@ -58,7 +59,7 @@ namespace mamba &available_backends ); } - else if (on_win) + else if (util::on_win) { sslset_res = curl_global_sslset(CURLSSLBACKEND_SCHANNEL, nullptr, &available_backends); } diff --git a/libmamba/src/core/util.cpp b/libmamba/src/core/util.cpp index 9723df44b5..1c630010ba 100644 --- a/libmamba/src/core/util.cpp +++ b/libmamba/src/core/util.cpp @@ -44,7 +44,6 @@ extern "C" #include "mamba/core/context.hpp" #include "mamba/core/environment.hpp" #include "mamba/core/execution.hpp" -#include "mamba/core/fsutil.hpp" #include "mamba/core/invoke.hpp" #include "mamba/core/output.hpp" #include "mamba/core/shell_init.hpp" @@ -52,6 +51,7 @@ extern "C" #include "mamba/core/util.hpp" #include "mamba/core/util_os.hpp" #include "mamba/core/util_random.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/compare.hpp" #include "mamba/util/string.hpp" #include "mamba/util/url.hpp" @@ -314,7 +314,7 @@ namespace mamba std::string quote_for_shell(const std::vector& arguments, const std::string& shell) { - if ((shell.empty() && on_win) || shell == "cmdexe") + if ((shell.empty() && util::on_win) || shell == "cmdexe") { // ported from CPython's list2cmdline to C++ // @@ -1455,7 +1455,7 @@ namespace mamba std::vector command_args; std::unique_ptr script_file; - if (on_win) + if (util::on_win) { ensure_comspec_set(); auto comspec = env::get("COMSPEC"); diff --git a/libmamba/src/core/util_os.cpp b/libmamba/src/core/util_os.cpp index ecf16482f0..bb30701d82 100644 --- a/libmamba/src/core/util_os.cpp +++ b/libmamba/src/core/util_os.cpp @@ -33,8 +33,8 @@ #include "mamba/core/environment.hpp" #include "mamba/core/output.hpp" -#include "mamba/core/util.hpp" #include "mamba/core/util_os.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/string.hpp" #ifdef _WIN32 @@ -229,7 +229,7 @@ namespace mamba return override_version.value(); } - if (!on_win) + if (!util::on_win) { return ""; } @@ -281,7 +281,7 @@ namespace mamba return override_version.value(); } - if (!on_mac) + if (!util::on_mac) { return ""; } @@ -319,7 +319,7 @@ namespace mamba { return override_version.value(); } - if (!on_linux) + if (!util::on_linux) { return ""; } diff --git a/libmamba/src/core/virtual_packages.cpp b/libmamba/src/core/virtual_packages.cpp index c6974d88f0..f0d9cda0e9 100644 --- a/libmamba/src/core/virtual_packages.cpp +++ b/libmamba/src/core/virtual_packages.cpp @@ -7,9 +7,9 @@ #include "mamba/core/context.hpp" #include "mamba/core/environment.hpp" #include "mamba/core/output.hpp" -#include "mamba/core/util.hpp" #include "mamba/core/util_os.hpp" #include "mamba/core/virtual_packages.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/string.hpp" #ifdef _WIN32 @@ -35,7 +35,7 @@ namespace mamba return override_version.value(); } - if (!on_linux) + if (!util::on_linux) { return ""; } @@ -79,7 +79,7 @@ namespace mamba out = ""; } - if (ec && on_win) + if (ec && util::on_win) { // Windows fallback bool may_exist = false; diff --git a/libmamba/src/util/path_manip.cpp b/libmamba/src/util/path_manip.cpp new file mode 100644 index 0000000000..17d15084e3 --- /dev/null +++ b/libmamba/src/util/path_manip.cpp @@ -0,0 +1,69 @@ +// Copyright (c) 2023, QuantStack and Mamba Contributors +// +// Distributed under the terms of the BSD 3-Clause License. +// +// The full license is in the file LICENSE, distributed with this software. + +#include +#include + +#include "mamba/util/build.hpp" +#include "mamba/util/path_manip.hpp" +#include "mamba/util/string.hpp" +#include "mamba/util/url_manip.hpp" + +namespace mamba::util +{ + auto is_explicit_path(std::string_view input) -> bool + { + // URI are not path + if (url_has_scheme(input)) + { + return false; + } + // Posix-like path + if (starts_with(input, '~') || starts_with(input, '/') || (input == ".") + || starts_with(input, "./") || (input == "..") || starts_with(input, "../") + + ) + { + return true; + } + // Windows like path + if ((input.size() >= 3) && is_alpha(input[0]) && (input[1] == ':') + && ((input[2] == '/') || (input[2] == '\\'))) + { + return true; + } + return false; + } + + auto path_has_drive_letter(std::string_view path) -> bool + { + static constexpr auto is_drive_char = [](char c) -> bool { return is_alphanum(c); }; + + auto [drive, rest] = lstrip_if_parts(path, is_drive_char); + return !drive.empty() && (rest.size() >= 2) && (rest[0] == ':') + && ((rest[1] == '/') || (rest[1] == '\\')); + } + + auto path_win_to_posix(std::string path) -> std::string + { + std::replace( + path.begin(), + path.end(), + preferred_path_separator_win, + preferred_path_separator_posix + ); + return path; + } + + auto path_to_posix(std::string path) -> std::string + { + if (on_win) + { + return path_win_to_posix(std::move(path)); + } + return path; + } +} diff --git a/libmamba/src/util/url.cpp b/libmamba/src/util/url.cpp index a5582cb624..ade67aff87 100644 --- a/libmamba/src/util/url.cpp +++ b/libmamba/src/util/url.cpp @@ -13,6 +13,7 @@ #include #include +#include "mamba/util/path_manip.hpp" #include "mamba/util/string.hpp" #include "mamba/util/url.hpp" #include "mamba/util/url_manip.hpp" diff --git a/libmamba/src/util/url_manip.cpp b/libmamba/src/util/url_manip.cpp index 2f4d57bb3e..6ac6ca1f41 100644 --- a/libmamba/src/util/url_manip.cpp +++ b/libmamba/src/util/url_manip.cpp @@ -16,7 +16,7 @@ #include #include "mamba/core/context.hpp" -#include "mamba/core/util.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/string.hpp" #include "mamba/util/url.hpp" @@ -216,15 +216,6 @@ namespace mamba::util return !url_get_scheme(url).empty(); } - auto path_has_drive_letter(std::string_view path) -> bool - { - static constexpr auto is_drive_char = [](char c) -> bool { return util::is_alphanum(c); }; - - auto [drive, rest] = util::lstrip_if_parts(path, is_drive_char); - return !drive.empty() && (rest.size() >= 2) && (rest[0] == ':') - && ((rest[1] == '/') || (rest[1] == '\\')); - } - void split_anaconda_token(const std::string& url, std::string& cleaned_url, std::string& token) { auto token_begin = std::sregex_iterator(url.begin(), url.end(), Context::instance().token_regex); @@ -273,14 +264,6 @@ namespace mamba::util return u1_remaining == u2_remaining; } - bool is_path(const std::string& input) - { - static const std::regex re(R"(\./|\.\.|~|/|[a-zA-Z]:[/\\]|\\\\|//)"); - std::smatch sm; - std::regex_search(input, sm, re); - return !sm.empty() && sm.position(0) == 0 && input.find("://") == std::string::npos; - } - std::string path_to_url(const std::string& path) { static constexpr std::string_view file_scheme = "file://"; diff --git a/libmamba/tests/CMakeLists.txt b/libmamba/tests/CMakeLists.txt index d63c1234f4..3dc5d1d5a7 100644 --- a/libmamba/tests/CMakeLists.txt +++ b/libmamba/tests/CMakeLists.txt @@ -30,6 +30,7 @@ set(LIBMAMBA_TEST_SRCS src/util/test_flat_bool_expr_tree.cpp src/util/test_graph.cpp src/util/test_iterator.cpp + src/util/test_path_manip.cpp src/util/test_url_manip.cpp src/util/test_url.cpp # Implementation of version and matching specs diff --git a/libmamba/tests/src/core/test_cpp.cpp b/libmamba/tests/src/core/test_cpp.cpp index bec1e9b89d..29bd399a17 100644 --- a/libmamba/tests/src/core/test_cpp.cpp +++ b/libmamba/tests/src/core/test_cpp.cpp @@ -18,6 +18,7 @@ #include "mamba/core/match_spec.hpp" #include "mamba/core/output.hpp" #include "mamba/core/subdirdata.hpp" +#include "mamba/util/build.hpp" #include "test_data.hpp" @@ -339,7 +340,7 @@ namespace mamba { TEST_CASE("env_name") { - if constexpr (on_mac || on_linux) + if constexpr (util::on_mac || util::on_linux) { auto& ctx = Context::instance(); ctx.prefix_params.root_prefix = "/home/user/micromamba/"; @@ -363,7 +364,7 @@ namespace mamba { TEST_CASE("starts_with_home") { - if (on_linux) + if (util::on_linux) { auto home = env::expand_user("~"); CHECK_EQ(path::starts_with_home(home / "test" / "file.txt"), true); @@ -381,7 +382,7 @@ namespace mamba TEST_CASE("touch") { - if (on_linux) + if (util::on_linux) { path::touch("/tmp/dir/file.txt", true); CHECK(fs::exists("/tmp/dir/file.txt")); @@ -393,12 +394,12 @@ namespace mamba { TEST_CASE("replace_long_shebang") { - if (!on_win) + if (!util::on_win) { std::string res = replace_long_shebang( "#!/this/is/loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong/python -o test -x" ); - if (on_linux) + if (util::on_linux) { CHECK_EQ(res, "#!/usr/bin/env python -o test -x"); } @@ -410,7 +411,7 @@ namespace mamba ); } - if (on_linux) + if (util::on_linux) { res = replace_long_shebang( "#!/this/is/loooooooooooooooooooooooooooooooooooooooooooooooooooo\\ oooooo\\ oooooo\\ oooooooooooooooooooooooooooooooooooong/python -o test -x" @@ -491,7 +492,7 @@ namespace mamba { TEST_CASE("quote_for_shell") { - if (!on_win) + if (!util::on_win) { std::vector args1 = { "python", "-c", "print('is\ngreat')" }; CHECK_EQ(quote_for_shell(args1), "python -c 'print('\"'\"'is\ngreat'\"'\"')'"); diff --git a/libmamba/tests/src/core/test_env_file_reading.cpp b/libmamba/tests/src/core/test_env_file_reading.cpp index 4334f2c792..68967ce688 100644 --- a/libmamba/tests/src/core/test_env_file_reading.cpp +++ b/libmamba/tests/src/core/test_env_file_reading.cpp @@ -7,7 +7,7 @@ #include #include "mamba/api/install.hpp" -#include "mamba/core/util.hpp" +#include "mamba/util/build.hpp" #include "test_data.hpp" @@ -18,10 +18,10 @@ namespace mamba TEST_CASE("selector") { using namespace detail; - if constexpr (on_linux || on_mac) + if constexpr (util::on_linux || util::on_mac) { CHECK(eval_selector("sel(unix)")); - if (on_mac) + if (util::on_mac) { CHECK(eval_selector("sel(osx)")); CHECK_FALSE(eval_selector("sel(linux)")); @@ -34,7 +34,7 @@ namespace mamba CHECK_FALSE(eval_selector("sel(win)")); } } - else if (on_win) + else if (util::on_win) { CHECK(eval_selector("sel(win)")); CHECK_FALSE(eval_selector("sel(osx)")); diff --git a/libmamba/tests/src/core/test_shell_init.cpp b/libmamba/tests/src/core/test_shell_init.cpp index bde97df409..0b62697591 100644 --- a/libmamba/tests/src/core/test_shell_init.cpp +++ b/libmamba/tests/src/core/test_shell_init.cpp @@ -4,12 +4,10 @@ // // The full license is in the file LICENSE, distributed with this software. -#include - #include #include "mamba/core/environment.hpp" -#include "mamba/core/util.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/string.hpp" namespace mamba @@ -30,7 +28,7 @@ namespace mamba TEST_CASE("expand_user") { auto expanded = env::expand_user("~/this/is/a/test"); - if (on_linux) + if (util::on_linux) { CHECK(util::starts_with(expanded.string(), "/home/")); } diff --git a/libmamba/tests/src/core/test_virtual_packages.cpp b/libmamba/tests/src/core/test_virtual_packages.cpp index 8cfc08387d..049c9c3085 100644 --- a/libmamba/tests/src/core/test_virtual_packages.cpp +++ b/libmamba/tests/src/core/test_virtual_packages.cpp @@ -10,8 +10,8 @@ #include "mamba/core/context.hpp" #include "mamba/core/environment.hpp" -#include "mamba/core/util.hpp" #include "mamba/core/virtual_packages.hpp" +#include "mamba/util/build.hpp" namespace mamba { @@ -50,19 +50,19 @@ namespace mamba auto pkgs = detail::dist_packages(); auto& ctx = Context::instance(); - if (on_win) + if (util::on_win) { REQUIRE_EQ(pkgs.size(), 2); CHECK_EQ(pkgs[0].name, "__win"); } - if (on_linux) + if (util::on_linux) { REQUIRE_EQ(pkgs.size(), 4); CHECK_EQ(pkgs[0].name, "__unix"); CHECK_EQ(pkgs[1].name, "__linux"); CHECK_EQ(pkgs[2].name, "__glibc"); } - if (on_mac) + if (util::on_mac) { REQUIRE_EQ(pkgs.size(), 3); CHECK_EQ(pkgs[0].name, "__unix"); @@ -125,15 +125,15 @@ namespace mamba auto pkgs = get_virtual_packages(); int pkgs_count; - if (on_win) + if (util::on_win) { pkgs_count = 2; } - if (on_linux) + if (util::on_linux) { pkgs_count = 4; } - if (on_mac) + if (util::on_mac) { pkgs_count = 3; } diff --git a/libmamba/tests/src/util/test_path_manip.cpp b/libmamba/tests/src/util/test_path_manip.cpp new file mode 100644 index 0000000000..f7fbc4b318 --- /dev/null +++ b/libmamba/tests/src/util/test_path_manip.cpp @@ -0,0 +1,70 @@ +// Copyright (c) 2023, QuantStack and Mamba Contributors +// +// Distributed under the terms of the BSD 3-Clause License. +// +// The full license is in the file LICENSE, distributed with this software. + + +#include + +#include "mamba/util/build.hpp" +#include "mamba/util/path_manip.hpp" + +using namespace mamba::util; + +TEST_SUITE("util::path_manip") +{ + TEST_CASE("is_explicit_path") + { + CHECK(is_explicit_path(".")); + CHECK(is_explicit_path("./")); + CHECK(is_explicit_path("./folder/file.txt")); + CHECK(is_explicit_path("..")); + CHECK(is_explicit_path("../file.txt")); + CHECK(is_explicit_path("~")); + CHECK(is_explicit_path("~/there")); + CHECK(is_explicit_path("/")); + CHECK(is_explicit_path("/asset")); + + CHECK_FALSE(is_explicit_path("")); + CHECK_FALSE(is_explicit_path("name")); + CHECK_FALSE(is_explicit_path("folder/file.txt")); + CHECK_FALSE(is_explicit_path("file://makefile")); + } + + TEST_CASE("path_has_drive_letter") + { + CHECK(path_has_drive_letter("C:/folder/file")); + CHECK(path_has_drive_letter(R"(C:\folder\file)")); + CHECK_FALSE(path_has_drive_letter("/folder/file")); + CHECK_FALSE(path_has_drive_letter("folder/file")); + CHECK_FALSE(path_has_drive_letter(R"(\folder\file)")); + CHECK_FALSE(path_has_drive_letter(R"(folder\file)")); + } + + TEST_CASE("path_win_to_posix") + { + CHECK_EQ(path_win_to_posix(""), ""); + CHECK_EQ(path_win_to_posix("file"), "file"); + CHECK_EQ(path_win_to_posix(R"(C:\folder\file)"), "C:/folder/file"); + CHECK_EQ(path_win_to_posix("C:/folder/file"), "C:/folder/file"); + } + + TEST_CASE("path_to_posix") + { + CHECK_EQ(path_to_posix(""), ""); + CHECK_EQ(path_to_posix("file"), "file"); + CHECK_EQ(path_to_posix("folder/file"), "folder/file"); + CHECK_EQ(path_to_posix("/folder/file"), "/folder/file"); + + if (on_win) + { + CHECK_EQ(path_to_posix(R"(C:\folder\file)"), "C:/folder/file"); + CHECK_EQ(path_to_posix("C:/folder/file"), "C:/folder/file"); + } + else + { + CHECK_EQ(path_to_posix(R"(folder/weird\file)"), R"(folder/weird\file)"); + } + } +} diff --git a/libmamba/tests/src/util/test_url_manip.cpp b/libmamba/tests/src/util/test_url_manip.cpp index 434c755d0d..e96521c8bd 100644 --- a/libmamba/tests/src/util/test_url_manip.cpp +++ b/libmamba/tests/src/util/test_url_manip.cpp @@ -9,13 +9,11 @@ #include +#include "mamba/core/mamba_fs.hpp" #include "mamba/specs/platform.hpp" +#include "mamba/util/build.hpp" #include "mamba/util/url_manip.hpp" -#ifdef _WIN32 -#include "mamba/core/mamba_fs.hpp" -#endif - using namespace mamba::util; TEST_SUITE("util::url_manip") @@ -134,14 +132,17 @@ TEST_SUITE("util::url_manip") TEST_CASE("path_to_url") { auto url = path_to_url("/users/test/miniconda3"); -#ifndef _WIN32 - CHECK_EQ(url, "file:///users/test/miniconda3"); -#else - std::string driveletter = fs::absolute(fs::u8path("/")).string().substr(0, 1); - CHECK_EQ(url, std::string("file://") + driveletter + ":/users/test/miniconda3"); - auto url2 = path_to_url("D:\\users\\test\\miniconda3"); - CHECK_EQ(url2, "file://D:/users/test/miniconda3"); -#endif + if (on_win) + { + std::string driveletter = fs::absolute(fs::u8path("/")).string().substr(0, 1); + CHECK_EQ(url, std::string("file://") + driveletter + ":/users/test/miniconda3"); + auto url2 = path_to_url("D:\\users\\test\\miniconda3"); + CHECK_EQ(url2, "file://D:/users/test/miniconda3"); + } + else + { + CHECK_EQ(url, "file:///users/test/miniconda3"); + } } TEST_CASE("file_uri_unc2_to_unc4") @@ -185,16 +186,6 @@ TEST_SUITE("util::url_manip") CHECK_FALSE(url_has_scheme("")); } - TEST_CASE("path_has_drive_letter") - { - CHECK(path_has_drive_letter("C:/folder/file")); - CHECK(path_has_drive_letter(R"(C:\folder\file)")); - CHECK_FALSE(path_has_drive_letter("/folder/file")); - CHECK_FALSE(path_has_drive_letter("folder/file")); - CHECK_FALSE(path_has_drive_letter(R"(\folder\file)")); - CHECK_FALSE(path_has_drive_letter(R"(folder\file)")); - } - TEST_CASE("split_ananconda_token") { std::string input, cleaned_url, token; @@ -258,28 +249,22 @@ TEST_SUITE("util::url_manip") CHECK_EQ(auth, "u:p"); CHECK_EQ(token, "a_-12345-absdj12345-xyxyxyx"); -#ifdef _WIN32 - split_scheme_auth_token("file://C:/Users/wolfv/test.json", remaining_url, scheme, auth, token); - CHECK_EQ(remaining_url, "C:/Users/wolfv/test.json"); - CHECK_EQ(scheme, "file"); - CHECK_EQ(auth, ""); - CHECK_EQ(token, ""); -#else - split_scheme_auth_token("file:///home/wolfv/test.json", remaining_url, scheme, auth, token); - CHECK_EQ(remaining_url, "/home/wolfv/test.json"); - CHECK_EQ(scheme, "file"); - CHECK_EQ(auth, ""); - CHECK_EQ(token, ""); -#endif - } - - TEST_CASE("is_path") - { - CHECK(is_path("./")); - CHECK(is_path("..")); - CHECK(is_path("~")); - CHECK(is_path("/")); - CHECK_FALSE(is_path("file://makefile")); + if (on_win) + { + split_scheme_auth_token("file://C:/Users/wolfv/test.json", remaining_url, scheme, auth, token); + CHECK_EQ(remaining_url, "C:/Users/wolfv/test.json"); + CHECK_EQ(scheme, "file"); + CHECK_EQ(auth, ""); + CHECK_EQ(token, ""); + } + else + { + split_scheme_auth_token("file:///home/wolfv/test.json", remaining_url, scheme, auth, token); + CHECK_EQ(remaining_url, "/home/wolfv/test.json"); + CHECK_EQ(scheme, "file"); + CHECK_EQ(auth, ""); + CHECK_EQ(token, ""); + } } TEST_CASE("cache_name_from_url") diff --git a/micromamba/src/config.cpp b/micromamba/src/config.cpp index 0fbd69ff90..54a0db8f5e 100644 --- a/micromamba/src/config.cpp +++ b/micromamba/src/config.cpp @@ -12,6 +12,7 @@ #include "mamba/api/configuration.hpp" #include "mamba/core/fsutil.hpp" #include "mamba/core/util.hpp" +#include "mamba/util/build.hpp" #include "common_options.hpp" @@ -47,8 +48,8 @@ is_valid_rc_sequence(const mamba::Configuration& config, const std::string& key, fs::u8path get_system_path() { - return (on_mac || on_linux) ? fs::u8path("/etc/conda/.condarc") - : fs::u8path("C:\\ProgramData\\conda\\.condarc"); + return (util::on_mac || util::on_linux) ? fs::u8path("/etc/conda/.condarc") + : fs::u8path("C:\\ProgramData\\conda\\.condarc"); } fs::u8path diff --git a/micromamba/src/shell.cpp b/micromamba/src/shell.cpp index 5f00523a56..ac26a76f2a 100644 --- a/micromamba/src/shell.cpp +++ b/micromamba/src/shell.cpp @@ -8,6 +8,7 @@ #include "mamba/api/shell.hpp" #include "mamba/core/run.hpp" #include "mamba/core/shell_init.hpp" +#include "mamba/util/build.hpp" #include "common_options.hpp" #include "umamba.hpp" @@ -327,11 +328,11 @@ namespace auto const get_shell = []() -> std::string { - if constexpr (on_win) + if constexpr (util::on_win) { return env::get("SHELL").value_or("cmd.exe"); } - else if constexpr (on_mac) + else if constexpr (util::on_mac) { return env::get("SHELL").value_or("zsh"); } diff --git a/micromamba/src/update.cpp b/micromamba/src/update.cpp index 6cdacad0a8..6a24cc0221 100644 --- a/micromamba/src/update.cpp +++ b/micromamba/src/update.cpp @@ -10,12 +10,12 @@ #include "mamba/api/channel_loader.hpp" #include "mamba/api/configuration.hpp" -#include "mamba/api/shell.hpp" #include "mamba/api/update.hpp" #include "mamba/core/channel.hpp" #include "mamba/core/context.hpp" #include "mamba/core/transaction.hpp" #include "mamba/core/util_os.hpp" +#include "mamba/util/build.hpp" #include "common_options.hpp" #include "version.hpp" @@ -107,7 +107,7 @@ update_self(Configuration& config, const std::optional& version) try { - if (on_win) + if (util::on_win) { fs::copy_file( cache_path / "Library" / "bin" / "micromamba.exe",