Skip to content

Commit

Permalink
Windows path manipulation and other cleanups (#2801)
Browse files Browse the repository at this point in the history
* Add path_win_to_posix

* Move path_has_drive_letter and is_path

* Refactor on_[plat]

* Add util::path_to_posix

* Fix static builds
  • Loading branch information
AntoinePrv authored Aug 31, 2023
1 parent cf3e20e commit 3fcff39
Show file tree
Hide file tree
Showing 29 changed files with 319 additions and 148 deletions.
3 changes: 3 additions & 0 deletions libmamba/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions libmamba/include/mamba/core/link.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <tuple>
#include <vector>

#include "nlohmann/json.hpp"
#include "mamba/util/build.hpp"

#include "mamba_fs.hpp"
#include "match_spec.hpp"
Expand All @@ -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
{
Expand Down
16 changes: 0 additions & 16 deletions libmamba/include/mamba/core/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
28 changes: 28 additions & 0 deletions libmamba/include/mamba/util/build.hpp
Original file line number Diff line number Diff line change
@@ -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
43 changes: 43 additions & 0 deletions libmamba/include/mamba/util/path_manip.hpp
Original file line number Diff line number Diff line change
@@ -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 <string>
#include <string_view>

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
6 changes: 0 additions & 6 deletions libmamba/include/mamba/util/url_manip.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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 <class S, class... Args>
Expand Down
3 changes: 2 additions & 1 deletion libmamba/src/api/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1779,7 +1780,7 @@ namespace mamba
auto& ctx = Context::instance();

std::vector<fs::u8path> 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",
Expand Down
11 changes: 6 additions & 5 deletions libmamba/src/core/activation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -207,7 +208,7 @@ namespace mamba

std::vector<fs::u8path> get_path_dirs(const fs::u8path& prefix)
{
if (on_win)
if (util::on_win)
{
return { prefix,
prefix / "Library" / "mingw-w64" / "bin",
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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";
Expand Down
9 changes: 5 additions & 4 deletions libmamba/src/core/channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);

Expand Down
3 changes: 2 additions & 1 deletion libmamba/src/core/fetch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 == "<system>" && on_linux)
else if (ctx.remote_fetch_params.ssl_verify == "<system>" && util::on_linux)
{
std::array<std::string, 6> cert_locations{
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
Expand Down
9 changes: 5 additions & 4 deletions libmamba/src/core/link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -345,7 +346,7 @@ namespace mamba
std::vector<std::string> command_args;
std::unique_ptr<TemporaryFile> script_file;

if (on_win)
if (util::on_win)
{
ensure_comspec_set();
auto comspec = env::get("COMSPEC");
Expand Down Expand Up @@ -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] == '!')
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 9 additions & 6 deletions libmamba/src/core/shell_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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());
}
Expand Down Expand Up @@ -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());
}
Expand All @@ -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());
}
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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")
{
Expand Down
Loading

0 comments on commit 3fcff39

Please sign in to comment.