mirror of https://github.com/mamba-org/mamba.git
Transaction context (#3950)
This commit is contained in:
parent
6115ac5cf2
commit
7e6435c605
|
@ -64,9 +64,6 @@ namespace mamba
|
|||
class Logger;
|
||||
class Context;
|
||||
|
||||
std::string env_name(const Context& context, const fs::u8path& prefix);
|
||||
std::string env_name(const Context& context);
|
||||
|
||||
struct ContextOptions
|
||||
{
|
||||
bool enable_logging = false;
|
||||
|
@ -104,12 +101,6 @@ namespace mamba
|
|||
bool no_env{ false };
|
||||
};
|
||||
|
||||
struct ThreadsParams
|
||||
{
|
||||
std::size_t download_threads{ 5 };
|
||||
int extract_threads{ 0 };
|
||||
};
|
||||
|
||||
// Configurable
|
||||
bool experimental = false;
|
||||
bool experimental_repodata_parsing = true;
|
||||
|
@ -131,15 +122,10 @@ namespace mamba
|
|||
|
||||
bool extract_sparse = false;
|
||||
|
||||
bool dev = false; // TODO this is always used as default=false and isn't set anywhere => to
|
||||
// be removed if this is the case...
|
||||
bool dry_run = false;
|
||||
bool download_only = false;
|
||||
bool always_yes = false;
|
||||
|
||||
bool allow_softlinks = false;
|
||||
bool always_copy = false;
|
||||
bool always_softlink = false;
|
||||
bool register_envs = true;
|
||||
|
||||
bool show_anaconda_channel_warnings = true;
|
||||
|
@ -167,6 +153,7 @@ namespace mamba
|
|||
ThreadsParams threads_params;
|
||||
PrefixParams prefix_params;
|
||||
ValidationParams validation_params;
|
||||
LinkParams link_params;
|
||||
|
||||
download::RemoteFetchParams remote_fetch_params = {
|
||||
/* .ssl_verify */ { "" },
|
||||
|
@ -222,11 +209,22 @@ namespace mamba
|
|||
};
|
||||
}
|
||||
|
||||
TransactionParams transaction_params() const
|
||||
{
|
||||
return { /* .is_mamba_exe */ command_params.is_mamba_exe,
|
||||
/* .json_output */ output_params.json,
|
||||
/* .verbosity */ output_params.verbosity,
|
||||
/* .shortcut */ shortcuts,
|
||||
/* .envs_dirs */ envs_dirs,
|
||||
/* .platform */ platform,
|
||||
/* .prefix_params */ prefix_params,
|
||||
/* .link_params */ link_params,
|
||||
/* .threads_params */ threads_params };
|
||||
}
|
||||
|
||||
std::size_t lock_timeout = 0;
|
||||
bool use_lockfiles = true;
|
||||
|
||||
bool compile_pyc = true;
|
||||
|
||||
// Conda compat
|
||||
bool add_pip_as_python_dependency = true;
|
||||
|
||||
|
|
|
@ -10,10 +10,8 @@
|
|||
|
||||
#include "mamba/fs/filesystem.hpp"
|
||||
|
||||
// TODO: having a file for this single structure is a bit of
|
||||
// overkill; this should be refactored when we have more structures
|
||||
// like this (i.e. parameters structures with no dependency on other
|
||||
// parts of mamba)
|
||||
// TODO move these structures back to Context.hpp or rename this file
|
||||
// with a better name when the Context is fully refactored.
|
||||
namespace mamba
|
||||
{
|
||||
struct CommandParams
|
||||
|
@ -32,4 +30,32 @@ namespace mamba
|
|||
fs::u8path conda_prefix;
|
||||
fs::u8path relocate_prefix;
|
||||
};
|
||||
|
||||
struct LinkParams
|
||||
{
|
||||
bool allow_softlinks = false;
|
||||
bool always_copy = false;
|
||||
bool always_softlink = false;
|
||||
bool compile_pyc = true;
|
||||
};
|
||||
|
||||
struct ThreadsParams
|
||||
{
|
||||
std::size_t download_threads{ 5 };
|
||||
int extract_threads{ 0 };
|
||||
};
|
||||
|
||||
struct TransactionParams
|
||||
{
|
||||
bool is_mamba_exe;
|
||||
bool json_output;
|
||||
int verbosity;
|
||||
bool shortcuts;
|
||||
std::vector<fs::u8path> envs_dirs;
|
||||
std::string platform;
|
||||
|
||||
PrefixParams prefix_params;
|
||||
LinkParams link_params;
|
||||
ThreadsParams threads_params;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fsutil.hpp"
|
||||
|
||||
|
@ -20,6 +21,12 @@ namespace mamba
|
|||
|
||||
bool is_conda_environment(const fs::u8path& prefix);
|
||||
|
||||
std::string env_name(
|
||||
const std::vector<fs::u8path>& envs_dirs,
|
||||
const fs::u8path& root_prefix,
|
||||
const fs::u8path& prefix
|
||||
);
|
||||
|
||||
class EnvironmentsManager
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
namespace mamba
|
||||
{
|
||||
class Context;
|
||||
class TransactionContext;
|
||||
|
||||
namespace fs
|
||||
|
@ -14,14 +13,8 @@ namespace mamba
|
|||
class u8path;
|
||||
}
|
||||
|
||||
void remove_menu_from_json(
|
||||
const Context& context,
|
||||
const fs::u8path& json_file,
|
||||
TransactionContext* transaction_context
|
||||
);
|
||||
void create_menu_from_json(
|
||||
const Context& context,
|
||||
const fs::u8path& json_file,
|
||||
TransactionContext* transaction_context
|
||||
);
|
||||
void
|
||||
remove_menu_from_json(const fs::u8path& json_file, const TransactionContext& transaction_context);
|
||||
void
|
||||
create_menu_from_json(const fs::u8path& json_file, const TransactionContext& transaction_context);
|
||||
}
|
||||
|
|
|
@ -108,9 +108,6 @@ namespace mamba
|
|||
std::vector<detail::other_pkg_mgr_spec>& other_specs
|
||||
);
|
||||
|
||||
// NOTE: This can be moved to somewhere else if more appropriate
|
||||
// See: https://github.com/mamba-org/mamba/issues/2288
|
||||
void print_activation_message(const Context& ctx);
|
||||
} // namespace mamba
|
||||
|
||||
#endif // MAMBA_TRANSACTION_HPP
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <reproc++/reproc.hpp>
|
||||
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/context_params.hpp"
|
||||
#include "mamba/core/util.hpp"
|
||||
#include "mamba/fs/filesystem.hpp"
|
||||
#include "mamba/specs/match_spec.hpp"
|
||||
|
@ -32,62 +32,52 @@ namespace mamba
|
|||
{
|
||||
public:
|
||||
|
||||
TransactionContext();
|
||||
struct PythonParams
|
||||
{
|
||||
bool has_python = false;
|
||||
std::string python_version;
|
||||
std::string old_python_version;
|
||||
std::string short_python_version;
|
||||
fs::u8path python_path;
|
||||
fs::u8path site_packages_path;
|
||||
};
|
||||
|
||||
// TODO: remove this constructor when refactoring
|
||||
// the MTransaction class.
|
||||
TransactionContext() = default;
|
||||
|
||||
TransactionContext(
|
||||
TransactionParams transaction_params,
|
||||
std::pair<std::string, std::string> py_versions,
|
||||
std::vector<specs::MatchSpec> requested_specs
|
||||
);
|
||||
|
||||
~TransactionContext();
|
||||
|
||||
TransactionContext(TransactionContext&&) = default;
|
||||
|
||||
explicit TransactionContext(const Context& context);
|
||||
|
||||
TransactionContext& operator=(TransactionContext&&) = default;
|
||||
|
||||
TransactionContext(
|
||||
const Context& context,
|
||||
const fs::u8path& target_prefix,
|
||||
const std::pair<std::string, std::string>& py_versions,
|
||||
std::vector<specs::MatchSpec> requested_specs
|
||||
);
|
||||
|
||||
TransactionContext(
|
||||
const Context& context,
|
||||
const fs::u8path& target_prefix,
|
||||
const fs::u8path& relocate_prefix,
|
||||
const std::pair<std::string, std::string>& py_versions,
|
||||
std::vector<specs::MatchSpec> requested_specs
|
||||
);
|
||||
~TransactionContext();
|
||||
bool try_pyc_compilation(const std::vector<fs::u8path>& py_files);
|
||||
void wait_for_pyc_compilation();
|
||||
|
||||
bool has_python = false;
|
||||
fs::u8path target_prefix;
|
||||
fs::u8path relocate_prefix;
|
||||
fs::u8path site_packages_path;
|
||||
fs::u8path python_path;
|
||||
std::string python_version;
|
||||
std::string old_python_version;
|
||||
std::string short_python_version;
|
||||
bool allow_softlinks = false;
|
||||
bool always_copy = false;
|
||||
bool always_softlink = false;
|
||||
bool compile_pyc = true;
|
||||
// this needs to be done when python version changes
|
||||
std::vector<specs::MatchSpec> requested_specs;
|
||||
const TransactionParams& transaction_params() const;
|
||||
const PrefixParams& prefix_params() const;
|
||||
const LinkParams& link_params() const;
|
||||
const PythonParams& python_params() const;
|
||||
|
||||
const Context& context() const
|
||||
{
|
||||
return *m_context;
|
||||
}
|
||||
const std::vector<specs::MatchSpec>& requested_specs() const;
|
||||
|
||||
private:
|
||||
|
||||
bool start_pyc_compilation_process();
|
||||
|
||||
TransactionParams m_transaction_params;
|
||||
PythonParams m_python_params;
|
||||
std::vector<specs::MatchSpec> m_requested_specs;
|
||||
|
||||
std::unique_ptr<reproc::process> m_pyc_process = nullptr;
|
||||
std::unique_ptr<TemporaryFile> m_pyc_script_file = nullptr;
|
||||
std::unique_ptr<TemporaryFile> m_pyc_compileall = nullptr;
|
||||
|
||||
const Context* m_context = nullptr; // TODO: replace by a struct with the necessary params.
|
||||
|
||||
void throw_if_not_ready() const;
|
||||
};
|
||||
} // namespace mamba
|
||||
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
|
||||
namespace mamba
|
||||
{
|
||||
class Context;
|
||||
|
||||
const std::regex& token_regex();
|
||||
const std::regex& http_basicauth_regex();
|
||||
|
||||
|
@ -337,7 +335,7 @@ namespace mamba
|
|||
quote_for_shell(const std::vector<std::string>& arguments, const std::string& shell = "");
|
||||
|
||||
std::size_t clean_trash_files(const fs::u8path& prefix, bool deep_clean);
|
||||
std::size_t remove_or_rename(const Context& context, const fs::u8path& path);
|
||||
std::size_t remove_or_rename(const fs::u8path& target_prefix, const fs::u8path& path);
|
||||
|
||||
// Unindent a string literal
|
||||
std::string unindent(const char* p);
|
||||
|
@ -364,20 +362,11 @@ namespace mamba
|
|||
|
||||
bool ensure_comspec_set();
|
||||
|
||||
struct WrappedCallOptions
|
||||
{
|
||||
bool is_mamba_exe = false;
|
||||
bool dev_mode = false;
|
||||
bool debug_wrapper_scripts = false;
|
||||
|
||||
static WrappedCallOptions from_context(const Context&);
|
||||
};
|
||||
|
||||
std::unique_ptr<TemporaryFile> wrap_call(
|
||||
const fs::u8path& root_prefix,
|
||||
const fs::u8path& prefix,
|
||||
const std::vector<std::string>& arguments, // TODO: c++20 replace by std::span
|
||||
WrappedCallOptions options = {}
|
||||
bool is_mamba_exe = false
|
||||
);
|
||||
|
||||
struct PreparedWrappedCall
|
||||
|
@ -389,7 +378,7 @@ namespace mamba
|
|||
PreparedWrappedCall prepare_wrapped_call(
|
||||
const PrefixParams& prefix_params,
|
||||
const std::vector<std::string>& cmd,
|
||||
WrappedCallOptions options
|
||||
bool is_mamba_exe
|
||||
);
|
||||
|
||||
/// Returns `true` if the filename matches names of files which should be interpreted as YAML.
|
||||
|
|
|
@ -1745,7 +1745,7 @@ namespace mamba
|
|||
host max concurrency minus the value, zero (default) is the host max
|
||||
concurrency value.)")));
|
||||
|
||||
insert(Configurable("allow_softlinks", &m_context.allow_softlinks)
|
||||
insert(Configurable("allow_softlinks", &m_context.link_params.allow_softlinks)
|
||||
.group("Extract, Link & Install")
|
||||
.set_rc_configurable()
|
||||
.set_env_var_names()
|
||||
|
@ -1755,7 +1755,7 @@ namespace mamba
|
|||
such as when installing on a different filesystem than the one that
|
||||
the package cache is on.)")));
|
||||
|
||||
insert(Configurable("always_copy", &m_context.always_copy)
|
||||
insert(Configurable("always_copy", &m_context.link_params.always_copy)
|
||||
.group("Extract, Link & Install")
|
||||
.set_rc_configurable()
|
||||
.set_env_var_names()
|
||||
|
@ -1764,13 +1764,13 @@ namespace mamba
|
|||
Register a preference that files be copied into a prefix during
|
||||
install rather than hard-linked.)")));
|
||||
|
||||
insert(Configurable("always_softlink", &m_context.always_softlink)
|
||||
insert(Configurable("always_softlink", &m_context.link_params.always_softlink)
|
||||
.group("Extract, Link & Install")
|
||||
.set_rc_configurable()
|
||||
.set_env_var_names()
|
||||
.needs({ "always_copy" })
|
||||
.set_post_merge_hook<decltype(m_context.always_softlink)>(
|
||||
[&](decltype(m_context.always_softlink)& value)
|
||||
.set_post_merge_hook<decltype(m_context.link_params.always_softlink)>(
|
||||
[&](decltype(m_context.link_params.always_softlink)& value)
|
||||
{ return detail::always_softlink_hook(*this, value); }
|
||||
)
|
||||
.description("Use soft-link instead of hard-link")
|
||||
|
@ -1854,7 +1854,7 @@ namespace mamba
|
|||
However, some filesystems do not support file locking and locks do not always
|
||||
make sense - like when on an HPC. Default is true (use a lockfile)")));
|
||||
|
||||
insert(Configurable("compile_pyc", &m_context.compile_pyc)
|
||||
insert(Configurable("compile_pyc", &m_context.link_params.compile_pyc)
|
||||
.group("Extract, Link & Install")
|
||||
.set_rc_configurable()
|
||||
.set_env_var_names()
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mamba/api/info.hpp"
|
||||
#include "mamba/core/channel_context.hpp"
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/environments_manager.hpp"
|
||||
#include "mamba/core/util_os.hpp"
|
||||
#include "mamba/core/virtual_packages.hpp"
|
||||
#include "mamba/util/environment.hpp"
|
||||
|
@ -164,7 +165,11 @@ namespace mamba
|
|||
std::string name, location;
|
||||
if (!ctx.prefix_params.target_prefix.empty())
|
||||
{
|
||||
name = env_name(ctx);
|
||||
name = env_name(
|
||||
ctx.envs_dirs,
|
||||
ctx.prefix_params.root_prefix,
|
||||
ctx.prefix_params.target_prefix
|
||||
);
|
||||
location = ctx.prefix_params.target_prefix.string();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "mamba/core/package_database_loader.hpp"
|
||||
#include "mamba/core/pinning.hpp"
|
||||
#include "mamba/core/transaction.hpp"
|
||||
#include "mamba/core/util_os.hpp"
|
||||
#include "mamba/core/virtual_packages.hpp"
|
||||
#include "mamba/download/downloader.hpp"
|
||||
#include "mamba/fs/filesystem.hpp"
|
||||
|
@ -451,6 +452,36 @@ namespace mamba
|
|||
|
||||
namespace
|
||||
{
|
||||
void print_activation_message(const Context& ctx)
|
||||
{
|
||||
// Check that the target prefix is not active before printing the activation message
|
||||
if (util::get_env("CONDA_PREFIX") != ctx.prefix_params.target_prefix)
|
||||
{
|
||||
// Get the name of the executable used directly from the command.
|
||||
const auto executable = get_self_exe_path().stem().string();
|
||||
|
||||
// Get the name of the environment
|
||||
const auto environment = env_name(
|
||||
ctx.envs_dirs,
|
||||
ctx.prefix_params.root_prefix,
|
||||
ctx.prefix_params.target_prefix
|
||||
);
|
||||
|
||||
Console::stream() << "\nTo activate this environment, use:\n\n"
|
||||
" "
|
||||
<< executable << " activate " << environment
|
||||
<< "\n\n"
|
||||
"Or to execute a single command in this environment, use:\n\n"
|
||||
" "
|
||||
<< executable
|
||||
<< " run "
|
||||
// Use -n or -p depending on if the env_name is a full prefix or
|
||||
// just a name.
|
||||
<< (environment == ctx.prefix_params.target_prefix ? "-p " : "-n ")
|
||||
<< environment << " mycommand\n";
|
||||
}
|
||||
}
|
||||
|
||||
void install_specs_impl(
|
||||
Context& ctx,
|
||||
ChannelContext& channel_context,
|
||||
|
|
|
@ -175,7 +175,7 @@ namespace mamba
|
|||
auto [wrapped_command, tmpfile] = prepare_wrapped_call(
|
||||
ctx.prefix_params,
|
||||
command,
|
||||
WrappedCallOptions::from_context(ctx)
|
||||
ctx.command_params.is_mamba_exe
|
||||
);
|
||||
|
||||
reproc::options options;
|
||||
|
|
|
@ -379,32 +379,6 @@ namespace mamba
|
|||
m_authentication_infos_loaded = true;
|
||||
}
|
||||
|
||||
std::string env_name(const Context& context, const fs::u8path& prefix)
|
||||
{
|
||||
if (prefix.empty())
|
||||
{
|
||||
throw std::runtime_error("Empty path");
|
||||
}
|
||||
if (paths_equal(prefix, context.prefix_params.root_prefix))
|
||||
{
|
||||
return ROOT_ENV_NAME;
|
||||
}
|
||||
fs::u8path maybe_env_dir = prefix.parent_path();
|
||||
for (const auto& d : context.envs_dirs)
|
||||
{
|
||||
if (paths_equal(d, maybe_env_dir))
|
||||
{
|
||||
return prefix.filename().string();
|
||||
}
|
||||
}
|
||||
return prefix.string();
|
||||
}
|
||||
|
||||
std::string env_name(const Context& context)
|
||||
{
|
||||
return env_name(context, context.prefix_params.target_prefix);
|
||||
}
|
||||
|
||||
void Context::debug_print() const
|
||||
{
|
||||
#define PRINT_CTX(xout, xname) fmt::print(xout, "{}: {}\n", #xname, xname)
|
||||
|
@ -417,7 +391,7 @@ namespace mamba
|
|||
PRINT_CTX(out, prefix_params.root_prefix);
|
||||
PRINT_CTX(out, dry_run);
|
||||
PRINT_CTX(out, always_yes);
|
||||
PRINT_CTX(out, allow_softlinks);
|
||||
PRINT_CTX(out, link_params.allow_softlinks);
|
||||
PRINT_CTX(out, offline);
|
||||
PRINT_CTX(out, output_params.quiet);
|
||||
PRINT_CTX(out, src_params.no_rc);
|
||||
|
|
|
@ -21,6 +21,31 @@ namespace mamba
|
|||
return fs::exists(prefix / PREFIX_MAGIC_FILE);
|
||||
}
|
||||
|
||||
std::string env_name(
|
||||
const std::vector<fs::u8path>& envs_dirs,
|
||||
const fs::u8path& root_prefix,
|
||||
const fs::u8path& prefix
|
||||
)
|
||||
{
|
||||
if (prefix.empty())
|
||||
{
|
||||
throw std::runtime_error("Empty path");
|
||||
}
|
||||
if (paths_equal(prefix, root_prefix))
|
||||
{
|
||||
return ROOT_ENV_NAME;
|
||||
}
|
||||
fs::u8path maybe_env_dir = prefix.parent_path();
|
||||
for (const auto& d : envs_dirs)
|
||||
{
|
||||
if (paths_equal(d, maybe_env_dir))
|
||||
{
|
||||
return prefix.filename().string();
|
||||
}
|
||||
}
|
||||
return prefix.string();
|
||||
}
|
||||
|
||||
EnvironmentsManager::EnvironmentsManager(const Context& context)
|
||||
: m_context(context)
|
||||
{
|
||||
|
|
|
@ -143,18 +143,19 @@ namespace mamba
|
|||
const python_entry_point_parsed& entry_point
|
||||
)
|
||||
{
|
||||
const fs::u8path& target_prefix = m_context->prefix_params().target_prefix;
|
||||
#ifdef _WIN32
|
||||
// We add -script.py to WIN32, and link the conda.exe launcher which will
|
||||
// automatically find the correct script to launch
|
||||
std::string win_script = path.string() + "-script.py";
|
||||
std::string win_script_gen_str = path.generic_string() + "-script.py";
|
||||
fs::u8path script_path = m_context->target_prefix / win_script;
|
||||
fs::u8path script_path = target_prefix / win_script;
|
||||
#else
|
||||
fs::u8path script_path = m_context->target_prefix / path;
|
||||
fs::u8path script_path = target_prefix / path;
|
||||
#endif
|
||||
if (fs::exists(script_path))
|
||||
{
|
||||
m_clobber_warnings.push_back(fs::relative(script_path, m_context->target_prefix).string());
|
||||
m_clobber_warnings.push_back(fs::relative(script_path, target_prefix).string());
|
||||
fs::remove(script_path);
|
||||
}
|
||||
if (!fs::is_directory(script_path.parent_path()))
|
||||
|
@ -164,9 +165,10 @@ namespace mamba
|
|||
std::ofstream out_file = open_ofstream(script_path);
|
||||
|
||||
fs::u8path python_path;
|
||||
if (m_context->has_python)
|
||||
if (m_context->python_params().has_python)
|
||||
{
|
||||
python_path = m_context->relocate_prefix / m_context->python_path;
|
||||
python_path = m_context->prefix_params().relocate_prefix
|
||||
/ m_context->python_params().python_path;
|
||||
}
|
||||
if (!python_path.empty())
|
||||
{
|
||||
|
@ -180,19 +182,16 @@ namespace mamba
|
|||
fs::u8path script_exe = path;
|
||||
script_exe.replace_extension("exe");
|
||||
|
||||
if (fs::exists(m_context->target_prefix / script_exe))
|
||||
if (fs::exists(target_prefix / script_exe))
|
||||
{
|
||||
m_clobber_warnings.push_back(fs::relative(script_exe.string()).string());
|
||||
fs::remove(m_context->target_prefix / script_exe);
|
||||
fs::remove(target_prefix / script_exe);
|
||||
}
|
||||
|
||||
std::ofstream conda_exe_f = open_ofstream(
|
||||
m_context->target_prefix / script_exe,
|
||||
std::ios::binary
|
||||
);
|
||||
std::ofstream conda_exe_f = open_ofstream(target_prefix / script_exe, std::ios::binary);
|
||||
conda_exe_f.write(reinterpret_cast<char*>(conda_exe), conda_exe_len);
|
||||
conda_exe_f.close();
|
||||
make_executable(m_context->target_prefix / script_exe);
|
||||
make_executable(target_prefix / script_exe);
|
||||
return std::array<std::string, 2>{ win_script_gen_str, script_exe.generic_string() };
|
||||
#else
|
||||
if (!python_path.empty())
|
||||
|
@ -316,8 +315,8 @@ namespace mamba
|
|||
failure
|
||||
*/
|
||||
bool run_script(
|
||||
const Context& context,
|
||||
const fs::u8path& prefix,
|
||||
const TransactionParams& transaction_params,
|
||||
const PrefixParams& prefix_params,
|
||||
const specs::PackageInfo& pkg_info,
|
||||
const std::string& action = "post-link",
|
||||
const std::string& env_prefix = "",
|
||||
|
@ -327,12 +326,12 @@ namespace mamba
|
|||
fs::u8path path;
|
||||
if (util::on_win)
|
||||
{
|
||||
path = prefix / get_bin_directory_short_path()
|
||||
path = prefix_params.target_prefix / get_bin_directory_short_path()
|
||||
/ util::concat(".", pkg_info.name, "-", action, ".bat");
|
||||
}
|
||||
else
|
||||
{
|
||||
path = prefix / get_bin_directory_short_path()
|
||||
path = prefix_params.target_prefix / get_bin_directory_short_path()
|
||||
/ util::concat(".", pkg_info.name, "-", action, ".sh");
|
||||
}
|
||||
|
||||
|
@ -369,10 +368,10 @@ namespace mamba
|
|||
if (activate)
|
||||
{
|
||||
script_file = wrap_call(
|
||||
context.prefix_params.root_prefix,
|
||||
prefix,
|
||||
prefix_params.root_prefix,
|
||||
prefix_params.target_prefix,
|
||||
{ "@CALL", path.string() },
|
||||
WrappedCallOptions::from_context(context)
|
||||
transaction_params.is_mamba_exe
|
||||
);
|
||||
|
||||
command_args = { comspec.value(), "/d", "/c", script_file->path().string() };
|
||||
|
@ -396,10 +395,10 @@ namespace mamba
|
|||
{
|
||||
// std::string caller
|
||||
script_file = wrap_call(
|
||||
context.prefix_params.root_prefix.string(),
|
||||
prefix,
|
||||
prefix_params.root_prefix.string(),
|
||||
prefix_params.target_prefix,
|
||||
{ ".", path.string() },
|
||||
WrappedCallOptions::from_context(context)
|
||||
transaction_params.is_mamba_exe
|
||||
);
|
||||
command_args.push_back(shell_path.string());
|
||||
command_args.push_back(script_file->path().string());
|
||||
|
@ -412,8 +411,8 @@ namespace mamba
|
|||
}
|
||||
}
|
||||
|
||||
envmap["ROOT_PREFIX"] = context.prefix_params.root_prefix.string();
|
||||
envmap["PREFIX"] = env_prefix.size() ? env_prefix : prefix.string();
|
||||
envmap["ROOT_PREFIX"] = prefix_params.root_prefix.string();
|
||||
envmap["PREFIX"] = env_prefix.size() ? env_prefix : prefix_params.target_prefix.string();
|
||||
envmap["PKG_NAME"] = pkg_info.name;
|
||||
envmap["PKG_VERSION"] = pkg_info.version;
|
||||
envmap["PKG_BUILDNUM"] = std::to_string(pkg_info.build_number);
|
||||
|
@ -444,7 +443,7 @@ namespace mamba
|
|||
auto [status, ec] = reproc::run(command_args, options);
|
||||
|
||||
auto msg = get_prefix_messages(envmap["PREFIX"]);
|
||||
if (context.output_params.json)
|
||||
if (transaction_params.json_output)
|
||||
{
|
||||
// TODO implement cerr also on Console?
|
||||
std::cerr << msg;
|
||||
|
@ -481,14 +480,14 @@ namespace mamba
|
|||
|
||||
bool UnlinkPackage::unlink_path(const nlohmann::json& path_data)
|
||||
{
|
||||
const auto& context = m_context->context();
|
||||
std::string subtarget = path_data["_path"].get<std::string>();
|
||||
fs::u8path dst = m_context->target_prefix / subtarget;
|
||||
const fs::u8path& target_prefix = m_context->prefix_params().target_prefix;
|
||||
fs::u8path dst = target_prefix / subtarget;
|
||||
|
||||
LOG_TRACE << "Unlinking '" << dst.string() << "'";
|
||||
std::error_code err;
|
||||
|
||||
if (remove_or_rename(context, dst) == 0)
|
||||
if (remove_or_rename(target_prefix, dst) == 0)
|
||||
{
|
||||
LOG_DEBUG << "Error when removing file '" << dst.string() << "' will be ignored";
|
||||
}
|
||||
|
@ -512,7 +511,7 @@ namespace mamba
|
|||
}
|
||||
if (is_empty)
|
||||
{
|
||||
remove_or_rename(context, parent_path);
|
||||
remove_or_rename(target_prefix, parent_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -520,7 +519,7 @@ namespace mamba
|
|||
}
|
||||
}
|
||||
parent_path = parent_path.parent_path();
|
||||
if (parent_path == m_context->target_prefix)
|
||||
if (parent_path == target_prefix)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -530,9 +529,9 @@ namespace mamba
|
|||
|
||||
bool UnlinkPackage::execute()
|
||||
{
|
||||
const auto& context = m_context->context();
|
||||
// find the recorded JSON file
|
||||
fs::u8path json = m_context->target_prefix / "conda-meta" / (m_specifier + ".json");
|
||||
fs::u8path json = m_context->prefix_params().target_prefix / "conda-meta"
|
||||
/ (m_specifier + ".json");
|
||||
LOG_INFO << "Unlinking package '" << m_specifier << "'";
|
||||
LOG_DEBUG << "Use metadata found at '" << json.string() << "'";
|
||||
|
||||
|
@ -545,7 +544,7 @@ namespace mamba
|
|||
std::string fpath = path["_path"];
|
||||
if (std::regex_match(fpath, MENU_PATH_REGEX))
|
||||
{
|
||||
remove_menu_from_json(context, m_context->target_prefix / fpath, m_context);
|
||||
remove_menu_from_json(m_context->prefix_params().target_prefix / fpath, *m_context);
|
||||
}
|
||||
|
||||
unlink_path(path);
|
||||
|
@ -585,13 +584,16 @@ namespace mamba
|
|||
fs::u8path dst, rel_dst;
|
||||
if (noarch_python)
|
||||
{
|
||||
rel_dst = get_python_noarch_target_path(subtarget, m_context->site_packages_path);
|
||||
dst = m_context->target_prefix / rel_dst;
|
||||
rel_dst = get_python_noarch_target_path(
|
||||
subtarget,
|
||||
m_context->python_params().site_packages_path
|
||||
);
|
||||
dst = m_context->prefix_params().target_prefix / rel_dst;
|
||||
}
|
||||
else
|
||||
{
|
||||
rel_dst = subtarget;
|
||||
dst = m_context->target_prefix / rel_dst;
|
||||
dst = m_context->prefix_params().target_prefix / rel_dst;
|
||||
}
|
||||
|
||||
fs::u8path src = m_source / subtarget;
|
||||
|
@ -623,7 +625,7 @@ namespace mamba
|
|||
{
|
||||
// we have to replace the PREFIX stuff in the data
|
||||
// and copy the file
|
||||
std::string new_prefix = m_context->relocate_prefix.string();
|
||||
std::string new_prefix = m_context->prefix_params().relocate_prefix.string();
|
||||
#ifdef _WIN32
|
||||
util::replace_all(new_prefix, "\\", "/");
|
||||
#endif
|
||||
|
@ -747,7 +749,7 @@ namespace mamba
|
|||
#if defined(__APPLE__)
|
||||
if (binary_changed && m_pkg_info.platform == "osx-arm64")
|
||||
{
|
||||
codesign(dst, m_context->context().output_params.verbosity > 1);
|
||||
codesign(dst, m_context->transaction_params().verbosity > 1);
|
||||
}
|
||||
#endif
|
||||
return std::make_tuple(std::string(validation::sha256sum(dst)), rel_dst.generic_string());
|
||||
|
@ -755,8 +757,8 @@ namespace mamba
|
|||
|
||||
if ((path_data.path_type == PathType::HARDLINK) || path_data.no_link)
|
||||
{
|
||||
bool copy = path_data.no_link || m_context->always_copy;
|
||||
bool softlink = m_context->always_softlink;
|
||||
bool copy = path_data.no_link || m_context->link_params().always_copy;
|
||||
bool softlink = m_context->link_params().always_softlink;
|
||||
|
||||
if (!copy && !softlink)
|
||||
{
|
||||
|
@ -765,7 +767,7 @@ namespace mamba
|
|||
|
||||
if (lec)
|
||||
{
|
||||
softlink = m_context->allow_softlinks;
|
||||
softlink = m_context->link_params().allow_softlinks;
|
||||
copy = !softlink;
|
||||
}
|
||||
else
|
||||
|
@ -827,9 +829,9 @@ namespace mamba
|
|||
std::vector<fs::u8path> pyc_files;
|
||||
for (auto& f : py_files)
|
||||
{
|
||||
pyc_files.push_back(pyc_path(f, m_context->short_python_version));
|
||||
pyc_files.push_back(pyc_path(f, m_context->python_params().short_python_version));
|
||||
}
|
||||
if (m_context->compile_pyc)
|
||||
if (m_context->link_params().compile_pyc)
|
||||
{
|
||||
m_context->try_pyc_compilation(py_files);
|
||||
}
|
||||
|
@ -846,8 +848,6 @@ namespace mamba
|
|||
|
||||
bool LinkPackage::execute()
|
||||
{
|
||||
const auto& context = m_context->context();
|
||||
|
||||
nlohmann::json index_json, out_json;
|
||||
LOG_TRACE << "Preparing linking from '" << m_source.string() << "'";
|
||||
|
||||
|
@ -941,13 +941,17 @@ namespace mamba
|
|||
{
|
||||
// here we try to avoid recomputing the costly sha256 sum
|
||||
std::error_code ec;
|
||||
auto points_to = fs::canonical(m_context->target_prefix / files_record[i], ec);
|
||||
auto points_to = fs::canonical(
|
||||
m_context->prefix_params().target_prefix / files_record[i],
|
||||
ec
|
||||
);
|
||||
bool found = false;
|
||||
if (!ec)
|
||||
{
|
||||
for (std::size_t pix = 0; pix < files_record.size(); ++pix)
|
||||
{
|
||||
if ((m_context->target_prefix / files_record[pix]) == points_to)
|
||||
if ((m_context->prefix_params().target_prefix / files_record[pix])
|
||||
== points_to)
|
||||
{
|
||||
if (paths_json["paths"][pix].contains("sha256_in_prefix"))
|
||||
{
|
||||
|
@ -964,7 +968,10 @@ namespace mamba
|
|||
}
|
||||
if (!found)
|
||||
{
|
||||
bool exists = fs::exists(m_context->target_prefix / files_record[i], ec);
|
||||
bool exists = fs::exists(
|
||||
m_context->prefix_params().target_prefix / files_record[i],
|
||||
ec
|
||||
);
|
||||
if (ec)
|
||||
{
|
||||
LOG_WARNING << "Could not check existence for " << files_record[i] << ": "
|
||||
|
@ -975,7 +982,7 @@ namespace mamba
|
|||
if (exists)
|
||||
{
|
||||
paths_json["paths"][i]["sha256_in_prefix"] = validation::sha256sum(
|
||||
m_context->target_prefix / files_record[i]
|
||||
m_context->prefix_params().target_prefix / files_record[i]
|
||||
);
|
||||
}
|
||||
else
|
||||
|
@ -994,8 +1001,8 @@ namespace mamba
|
|||
out_json["paths_data"] = paths_json;
|
||||
out_json["files"] = files_record;
|
||||
|
||||
specs::MatchSpec* requested_spec = nullptr;
|
||||
for (auto& ms : m_context->requested_specs)
|
||||
const specs::MatchSpec* requested_spec = nullptr;
|
||||
for (auto& ms : m_context->requested_specs())
|
||||
{
|
||||
if (ms.name().contains(m_pkg_info.name))
|
||||
{
|
||||
|
@ -1025,9 +1032,10 @@ namespace mamba
|
|||
{
|
||||
if (std::regex_match(sub_path_json.path, py_file_re))
|
||||
{
|
||||
for_compilation.push_back(
|
||||
get_python_noarch_target_path(sub_path_json.path, m_context->site_packages_path)
|
||||
);
|
||||
for_compilation.push_back(get_python_noarch_target_path(
|
||||
sub_path_json.path,
|
||||
m_context->python_params().site_packages_path
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1072,21 +1080,31 @@ namespace mamba
|
|||
}
|
||||
|
||||
// Create all start menu shortcuts if prefix name doesn't start with underscore
|
||||
if (util::on_win && context.shortcuts
|
||||
&& m_context->target_prefix.filename().string()[0] != '_')
|
||||
if (util::on_win && m_context->transaction_params().shortcuts
|
||||
&& m_context->prefix_params().target_prefix.filename().string()[0] != '_')
|
||||
{
|
||||
for (auto& path : paths_data)
|
||||
{
|
||||
if (std::regex_match(path.path, MENU_PATH_REGEX))
|
||||
{
|
||||
create_menu_from_json(context, m_context->target_prefix / path.path, m_context);
|
||||
create_menu_from_json(
|
||||
m_context->prefix_params().target_prefix / path.path,
|
||||
*m_context
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run_script(context, m_context->target_prefix, m_pkg_info, "post-link", "", true);
|
||||
run_script(
|
||||
m_context->transaction_params(),
|
||||
m_context->prefix_params(),
|
||||
m_pkg_info,
|
||||
"post-link",
|
||||
"",
|
||||
true
|
||||
);
|
||||
|
||||
fs::u8path prefix_meta = m_context->target_prefix / "conda-meta";
|
||||
fs::u8path prefix_meta = m_context->prefix_params().target_prefix / "conda-meta";
|
||||
if (!fs::exists(prefix_meta))
|
||||
{
|
||||
fs::create_directory(prefix_meta);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#endif
|
||||
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/environments_manager.hpp"
|
||||
#include "mamba/core/output.hpp"
|
||||
#include "mamba/core/transaction_context.hpp"
|
||||
#include "mamba/util/string.hpp"
|
||||
|
@ -24,9 +25,13 @@ namespace mamba
|
|||
{
|
||||
namespace detail
|
||||
{
|
||||
std::string get_formatted_env_name(const Context& context, const fs::u8path& target_prefix)
|
||||
std::string get_formatted_env_name(
|
||||
const std::vector<fs::u8path>& envs_dirs,
|
||||
const fs::u8path& root_prefix,
|
||||
const fs::u8path& target_prefix
|
||||
)
|
||||
{
|
||||
std::string name = env_name(context, target_prefix);
|
||||
std::string name = env_name(envs_dirs, root_prefix, target_prefix);
|
||||
if (name.find_first_of("\\/") != std::string::npos)
|
||||
{
|
||||
return "";
|
||||
|
@ -193,18 +198,11 @@ namespace mamba
|
|||
#endif
|
||||
|
||||
|
||||
void
|
||||
replace_variables(const Context& ctx, std::string& text, TransactionContext* transaction_context)
|
||||
void replace_variables(std::string& text, const TransactionContext& context)
|
||||
{
|
||||
fs::u8path root_prefix = ctx.prefix_params.root_prefix;
|
||||
|
||||
fs::u8path target_prefix;
|
||||
std::string py_ver;
|
||||
if (transaction_context)
|
||||
{
|
||||
target_prefix = transaction_context->target_prefix;
|
||||
py_ver = transaction_context->python_version;
|
||||
}
|
||||
fs::u8path root_prefix = context.prefix_params().root_prefix;
|
||||
fs::u8path target_prefix = context.prefix_params().target_prefix;
|
||||
std::string py_ver = context.python_params().python_version;
|
||||
|
||||
std::string distribution_name = root_prefix.filename().string();
|
||||
if (distribution_name.size() > 1)
|
||||
|
@ -214,7 +212,7 @@ namespace mamba
|
|||
|
||||
auto to_forward_slash = [](const fs::u8path& p) { return util::path_to_posix(p.string()); };
|
||||
|
||||
auto platform_split = util::split(ctx.platform, "-");
|
||||
auto platform_split = util::split(context.transaction_params().platform, "-");
|
||||
std::string platform_bitness;
|
||||
if (platform_split.size() >= 2)
|
||||
{
|
||||
|
@ -232,7 +230,12 @@ namespace mamba
|
|||
{ "${PY_VER}", py_ver },
|
||||
{ "${MENU_DIR}", to_forward_slash(target_prefix / "Menu") },
|
||||
{ "${DISTRIBUTION_NAME}", distribution_name },
|
||||
{ "${ENV_NAME}", detail::get_formatted_env_name(ctx, target_prefix) },
|
||||
{ "${ENV_NAME}",
|
||||
detail::get_formatted_env_name(
|
||||
context.transaction_params().envs_dirs,
|
||||
root_prefix,
|
||||
target_prefix
|
||||
) },
|
||||
{ "${PLATFORM}", platform_bitness },
|
||||
};
|
||||
|
||||
|
@ -260,20 +263,24 @@ namespace mamba
|
|||
};
|
||||
|
||||
void create_remove_shortcut_impl(
|
||||
const Context& ctx,
|
||||
const fs::u8path& json_file,
|
||||
TransactionContext* transaction_context,
|
||||
const TransactionContext& context,
|
||||
[[maybe_unused]] bool remove
|
||||
)
|
||||
{
|
||||
std::string json_content = mamba::read_contents(json_file);
|
||||
replace_variables(ctx, json_content, transaction_context);
|
||||
replace_variables(json_content, context);
|
||||
auto j = nlohmann::json::parse(json_content);
|
||||
|
||||
std::string menu_name = j.value("menu_name", "Mamba Shortcuts");
|
||||
|
||||
std::string name_suffix;
|
||||
std::string e_name = detail::get_formatted_env_name(ctx, transaction_context->target_prefix);
|
||||
const PrefixParams& pp = context.prefix_params();
|
||||
std::string e_name = detail::get_formatted_env_name(
|
||||
context.transaction_params().envs_dirs,
|
||||
pp.root_prefix,
|
||||
pp.target_prefix
|
||||
);
|
||||
|
||||
if (e_name.size())
|
||||
{
|
||||
|
@ -295,8 +302,8 @@ namespace mamba
|
|||
// ]
|
||||
// }
|
||||
|
||||
const fs::u8path root_prefix = ctx.prefix_params.root_prefix;
|
||||
const fs::u8path target_prefix = ctx.prefix_params.target_prefix;
|
||||
const fs::u8path root_prefix = pp.root_prefix;
|
||||
const fs::u8path target_prefix = pp.target_prefix;
|
||||
|
||||
// using legacy stuff here
|
||||
const fs::u8path root_py = root_prefix / "python.exe";
|
||||
|
@ -474,15 +481,12 @@ namespace mamba
|
|||
}
|
||||
}
|
||||
|
||||
void remove_menu_from_json(
|
||||
const Context& context,
|
||||
const fs::u8path& json_file,
|
||||
TransactionContext* transaction_context
|
||||
)
|
||||
void
|
||||
remove_menu_from_json(const fs::u8path& json_file, const TransactionContext& transaction_context)
|
||||
{
|
||||
try
|
||||
{
|
||||
create_remove_shortcut_impl(context, json_file, transaction_context, true);
|
||||
create_remove_shortcut_impl(json_file, transaction_context, true);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
@ -490,15 +494,12 @@ namespace mamba
|
|||
}
|
||||
}
|
||||
|
||||
void create_menu_from_json(
|
||||
const Context& context,
|
||||
const fs::u8path& json_file,
|
||||
TransactionContext* transaction_context
|
||||
)
|
||||
void
|
||||
create_menu_from_json(const fs::u8path& json_file, const TransactionContext& transaction_context)
|
||||
{
|
||||
try
|
||||
{
|
||||
create_remove_shortcut_impl(context, json_file, transaction_context, false);
|
||||
create_remove_shortcut_impl(json_file, transaction_context, false);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
|
|
@ -335,7 +335,7 @@ namespace mamba
|
|||
auto [wrapped_command, script_file] = prepare_wrapped_call(
|
||||
context.prefix_params,
|
||||
command,
|
||||
WrappedCallOptions::from_context(context)
|
||||
context.command_params.is_mamba_exe
|
||||
);
|
||||
|
||||
fmt::print(LOG_DEBUG, "Running wrapped script: {}", fmt::join(command, " "));
|
||||
|
|
|
@ -41,32 +41,6 @@ namespace mamba
|
|||
{
|
||||
namespace nl = nlohmann;
|
||||
|
||||
void print_activation_message(const Context& ctx)
|
||||
{
|
||||
// Check that the target prefix is not active before printing the activation message
|
||||
if (util::get_env("CONDA_PREFIX") != ctx.prefix_params.target_prefix)
|
||||
{
|
||||
// Get the name of the executable used directly from the command.
|
||||
const auto executable = get_self_exe_path().stem().string();
|
||||
|
||||
// Get the name of the environment
|
||||
const auto environment = env_name(ctx);
|
||||
|
||||
Console::stream() << "\nTo activate this environment, use:\n\n"
|
||||
" "
|
||||
<< executable << " activate " << environment
|
||||
<< "\n\n"
|
||||
"Or to execute a single command in this environment, use:\n\n"
|
||||
" "
|
||||
<< executable
|
||||
<< " run "
|
||||
// Use -n or -p depending on if the env_name is a full prefix or just
|
||||
// a name.
|
||||
<< (environment == ctx.prefix_params.target_prefix ? "-p " : "-n ")
|
||||
<< environment << " mycommand\n";
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool need_pkg_download(const specs::PackageInfo& pkg_info, MultiPackageCache& caches)
|
||||
|
@ -239,9 +213,7 @@ namespace mamba
|
|||
}
|
||||
|
||||
m_transaction_context = TransactionContext(
|
||||
ctx,
|
||||
ctx.prefix_params.target_prefix,
|
||||
ctx.prefix_params.relocate_prefix,
|
||||
ctx.transaction_params(),
|
||||
find_python_version(m_solution, database),
|
||||
specs_to_install
|
||||
);
|
||||
|
@ -293,9 +265,7 @@ namespace mamba
|
|||
[&](const auto& item) { requested_specs.push_back(item.spec); }
|
||||
);
|
||||
m_transaction_context = TransactionContext(
|
||||
ctx,
|
||||
ctx.prefix_params.target_prefix,
|
||||
ctx.prefix_params.relocate_prefix,
|
||||
ctx.transaction_params(),
|
||||
find_python_version(m_solution, database),
|
||||
std::move(requested_specs)
|
||||
);
|
||||
|
@ -345,9 +315,7 @@ namespace mamba
|
|||
);
|
||||
|
||||
m_transaction_context = TransactionContext(
|
||||
ctx,
|
||||
ctx.prefix_params.target_prefix,
|
||||
ctx.prefix_params.relocate_prefix,
|
||||
ctx.transaction_params(),
|
||||
find_python_version(m_solution, database),
|
||||
std::move(specs_to_install)
|
||||
);
|
||||
|
|
|
@ -90,67 +90,39 @@ namespace mamba
|
|||
}
|
||||
}
|
||||
|
||||
TransactionContext::TransactionContext() = default;
|
||||
|
||||
TransactionContext::TransactionContext(const Context& context)
|
||||
: m_context(&context)
|
||||
TransactionContext::PythonParams
|
||||
build_python_params(std::pair<std::string, std::string> py_versions)
|
||||
{
|
||||
compile_pyc = this->context().compile_pyc;
|
||||
TransactionContext::PythonParams res;
|
||||
if (py_versions.first.size() != 0)
|
||||
{
|
||||
res.has_python = true;
|
||||
res.python_version = std::move(py_versions.first);
|
||||
res.old_python_version = std::move(py_versions.second);
|
||||
res.short_python_version = compute_short_python_version(res.python_version);
|
||||
res.python_path = get_python_short_path(res.short_python_version);
|
||||
res.site_packages_path = get_python_site_packages_short_path(res.short_python_version);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
TransactionContext::TransactionContext(
|
||||
const Context& context,
|
||||
const fs::u8path& ltarget_prefix,
|
||||
const std::pair<std::string, std::string>& py_versions,
|
||||
TransactionParams transaction_params,
|
||||
std::pair<std::string, std::string> py_versions,
|
||||
std::vector<specs::MatchSpec> lrequested_specs
|
||||
)
|
||||
: has_python(py_versions.first.size() != 0)
|
||||
, target_prefix(ltarget_prefix)
|
||||
, relocate_prefix(ltarget_prefix)
|
||||
, python_version(py_versions.first)
|
||||
, old_python_version(py_versions.second)
|
||||
, requested_specs(std::move(lrequested_specs))
|
||||
, m_context(&context)
|
||||
: m_transaction_params(std::move(transaction_params))
|
||||
, m_python_params(build_python_params(std::move(py_versions)))
|
||||
, m_requested_specs(std::move(lrequested_specs))
|
||||
{
|
||||
const auto& ctx = this->context();
|
||||
compile_pyc = ctx.compile_pyc;
|
||||
allow_softlinks = ctx.allow_softlinks;
|
||||
always_copy = ctx.always_copy;
|
||||
always_softlink = ctx.always_softlink;
|
||||
|
||||
std::string old_short_python_version;
|
||||
if (python_version.size() == 0)
|
||||
if (m_python_params.python_version.size() == 0)
|
||||
{
|
||||
LOG_INFO << "No python version given to TransactionContext, leaving it empty";
|
||||
}
|
||||
else
|
||||
PrefixParams& pp = m_transaction_params.prefix_params;
|
||||
if (pp.relocate_prefix.empty())
|
||||
{
|
||||
short_python_version = compute_short_python_version(python_version);
|
||||
python_path = get_python_short_path(short_python_version);
|
||||
site_packages_path = get_python_site_packages_short_path(short_python_version);
|
||||
}
|
||||
if (!old_python_version.empty())
|
||||
{
|
||||
old_short_python_version = compute_short_python_version(old_python_version);
|
||||
}
|
||||
}
|
||||
|
||||
TransactionContext::TransactionContext(
|
||||
const Context& context,
|
||||
const fs::u8path& ltarget_prefix,
|
||||
const fs::u8path& lrelocate_prefix,
|
||||
const std::pair<std::string, std::string>& py_versions,
|
||||
std::vector<specs::MatchSpec> lrequested_specs
|
||||
)
|
||||
: TransactionContext(context, ltarget_prefix, py_versions, std::move(lrequested_specs))
|
||||
{
|
||||
if (lrelocate_prefix.empty())
|
||||
{
|
||||
relocate_prefix = ltarget_prefix;
|
||||
}
|
||||
else
|
||||
{
|
||||
relocate_prefix = lrelocate_prefix;
|
||||
pp.relocate_prefix = pp.target_prefix;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,114 +131,14 @@ namespace mamba
|
|||
wait_for_pyc_compilation();
|
||||
}
|
||||
|
||||
void TransactionContext::throw_if_not_ready() const
|
||||
{
|
||||
if (m_context == nullptr)
|
||||
{
|
||||
throw mamba_error(
|
||||
"attempted to use TransactionContext while no Context was specified",
|
||||
mamba_error_code::internal_failure
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool TransactionContext::start_pyc_compilation_process()
|
||||
{
|
||||
throw_if_not_ready();
|
||||
|
||||
if (m_pyc_process)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
std::signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
const auto complete_python_path = target_prefix / python_path;
|
||||
std::vector<std::string> command = {
|
||||
complete_python_path.string(), "-Wi", "-m", "compileall", "-q", "-l", "-i", "-"
|
||||
};
|
||||
|
||||
auto py_ver_split = util::split(python_version, ".");
|
||||
|
||||
try
|
||||
{
|
||||
if (std::stoull(py_ver_split[0]) >= 3 && std::stoull(py_ver_split[1]) > 5)
|
||||
{
|
||||
m_pyc_compileall = std::make_unique<TemporaryFile>();
|
||||
std::ofstream compileall_f = open_ofstream(m_pyc_compileall->path());
|
||||
compile_python_sources(compileall_f);
|
||||
compileall_f.close();
|
||||
|
||||
command = { complete_python_path.string(),
|
||||
"-Wi",
|
||||
"-u",
|
||||
m_pyc_compileall->path().string() };
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR << "Bad conversion of Python version '" << python_version << "': " << e.what();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pyc_process = std::make_unique<reproc::process>();
|
||||
|
||||
reproc::options options;
|
||||
#ifndef _WIN32
|
||||
options.env.behavior = reproc::env::empty;
|
||||
#endif
|
||||
std::map<std::string, std::string> envmap;
|
||||
auto& ctx = context();
|
||||
envmap["MAMBA_EXTRACT_THREADS"] = std::to_string(ctx.threads_params.extract_threads);
|
||||
auto qemu_ld_prefix = util::get_env("QEMU_LD_PREFIX");
|
||||
if (qemu_ld_prefix)
|
||||
{
|
||||
envmap["QEMU_LD_PREFIX"] = qemu_ld_prefix.value();
|
||||
}
|
||||
options.env.extra = envmap;
|
||||
|
||||
options.stop = {
|
||||
{ reproc::stop::wait, reproc::milliseconds(10000) },
|
||||
{ reproc::stop::terminate, reproc::milliseconds(5000) },
|
||||
{ reproc::stop::kill, reproc::milliseconds(2000) },
|
||||
};
|
||||
|
||||
options.redirect.out.type = reproc::redirect::pipe;
|
||||
options.redirect.err.type = reproc::redirect::pipe;
|
||||
|
||||
const std::string cwd = target_prefix.string();
|
||||
options.working_directory = cwd.c_str();
|
||||
|
||||
auto [wrapped_command, script_file] = prepare_wrapped_call(
|
||||
context().prefix_params,
|
||||
command,
|
||||
WrappedCallOptions::from_context(ctx)
|
||||
);
|
||||
m_pyc_script_file = std::move(script_file);
|
||||
|
||||
LOG_INFO << "Running wrapped python compilation command " << util::join(" ", command);
|
||||
std::error_code ec = m_pyc_process->start(wrapped_command, options);
|
||||
|
||||
if (ec == std::errc::no_such_file_or_directory)
|
||||
{
|
||||
LOG_ERROR << "Program not found. Make sure it's available from the PATH. "
|
||||
<< ec.message();
|
||||
m_pyc_process = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TransactionContext::try_pyc_compilation(const std::vector<fs::u8path>& py_files)
|
||||
{
|
||||
throw_if_not_ready();
|
||||
// throw_if_not_ready();
|
||||
|
||||
static std::mutex pyc_compilation_mutex;
|
||||
std::lock_guard<std::mutex> lock(pyc_compilation_mutex);
|
||||
|
||||
if (!has_python)
|
||||
if (!python_params().has_python)
|
||||
{
|
||||
LOG_WARNING << "Can't compile pyc: Python not found";
|
||||
return false;
|
||||
|
@ -298,7 +170,7 @@ namespace mamba
|
|||
|
||||
void TransactionContext::wait_for_pyc_compilation()
|
||||
{
|
||||
throw_if_not_ready();
|
||||
// throw_if_not_ready();
|
||||
|
||||
if (m_pyc_process)
|
||||
{
|
||||
|
@ -338,4 +210,126 @@ namespace mamba
|
|||
m_pyc_process = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto TransactionContext::transaction_params() const -> const TransactionParams&
|
||||
{
|
||||
return m_transaction_params;
|
||||
}
|
||||
|
||||
auto TransactionContext::prefix_params() const -> const PrefixParams&
|
||||
{
|
||||
return m_transaction_params.prefix_params;
|
||||
}
|
||||
|
||||
auto TransactionContext::link_params() const -> const LinkParams&
|
||||
{
|
||||
return m_transaction_params.link_params;
|
||||
}
|
||||
|
||||
auto TransactionContext::python_params() const -> const PythonParams&
|
||||
{
|
||||
return m_python_params;
|
||||
}
|
||||
|
||||
const std::vector<specs::MatchSpec>& TransactionContext::requested_specs() const
|
||||
{
|
||||
return m_requested_specs;
|
||||
}
|
||||
|
||||
bool TransactionContext::start_pyc_compilation_process()
|
||||
{
|
||||
// TODO for now, we are sure that the TransactionContext is ready
|
||||
// here since this method is called by the Link class, which requires
|
||||
// an initialized TransactionContext in its constructor.
|
||||
// This should be enforced by removing the default constructor of
|
||||
// TransactionContext.
|
||||
|
||||
// throw_if_not_ready();
|
||||
|
||||
if (m_pyc_process)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
std::signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
const auto complete_python_path = prefix_params().target_prefix / python_params().python_path;
|
||||
std::vector<std::string> command = {
|
||||
complete_python_path.string(), "-Wi", "-m", "compileall", "-q", "-l", "-i", "-"
|
||||
};
|
||||
|
||||
auto py_ver_split = util::split(python_params().python_version, ".");
|
||||
|
||||
try
|
||||
{
|
||||
if (std::stoull(py_ver_split[0]) >= 3 && std::stoull(py_ver_split[1]) > 5)
|
||||
{
|
||||
m_pyc_compileall = std::make_unique<TemporaryFile>();
|
||||
std::ofstream compileall_f = open_ofstream(m_pyc_compileall->path());
|
||||
compile_python_sources(compileall_f);
|
||||
compileall_f.close();
|
||||
|
||||
command = { complete_python_path.string(),
|
||||
"-Wi",
|
||||
"-u",
|
||||
m_pyc_compileall->path().string() };
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR << "Bad conversion of Python version '" << python_params().python_version
|
||||
<< "': " << e.what();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pyc_process = std::make_unique<reproc::process>();
|
||||
|
||||
reproc::options options;
|
||||
#ifndef _WIN32
|
||||
options.env.behavior = reproc::env::empty;
|
||||
#endif
|
||||
std::map<std::string, std::string> envmap;
|
||||
envmap["MAMBA_EXTRACT_THREADS"] = std::to_string(
|
||||
m_transaction_params.threads_params.extract_threads
|
||||
);
|
||||
auto qemu_ld_prefix = util::get_env("QEMU_LD_PREFIX");
|
||||
if (qemu_ld_prefix)
|
||||
{
|
||||
envmap["QEMU_LD_PREFIX"] = qemu_ld_prefix.value();
|
||||
}
|
||||
options.env.extra = envmap;
|
||||
|
||||
options.stop = {
|
||||
{ reproc::stop::wait, reproc::milliseconds(10000) },
|
||||
{ reproc::stop::terminate, reproc::milliseconds(5000) },
|
||||
{ reproc::stop::kill, reproc::milliseconds(2000) },
|
||||
};
|
||||
|
||||
options.redirect.out.type = reproc::redirect::pipe;
|
||||
options.redirect.err.type = reproc::redirect::pipe;
|
||||
|
||||
const std::string cwd = prefix_params().target_prefix.string();
|
||||
options.working_directory = cwd.c_str();
|
||||
|
||||
auto [wrapped_command, script_file] = prepare_wrapped_call(
|
||||
prefix_params(),
|
||||
command,
|
||||
transaction_params().is_mamba_exe
|
||||
);
|
||||
m_pyc_script_file = std::move(script_file);
|
||||
|
||||
LOG_INFO << "Running wrapped python compilation command " << util::join(" ", command);
|
||||
std::error_code ec = m_pyc_process->start(wrapped_command, options);
|
||||
|
||||
if (ec == std::errc::no_such_file_or_directory)
|
||||
{
|
||||
LOG_ERROR << "Program not found. Make sure it's available from the PATH. "
|
||||
<< ec.message();
|
||||
m_pyc_process = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@ extern "C"
|
|||
#include <nlohmann/json.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/error_handling.hpp"
|
||||
#include "mamba/core/execution.hpp"
|
||||
#include "mamba/core/invoke.hpp"
|
||||
|
@ -565,7 +564,7 @@ namespace mamba
|
|||
return deleted_files;
|
||||
}
|
||||
|
||||
std::size_t remove_or_rename(const Context& context, const fs::u8path& path)
|
||||
std::size_t remove_or_rename(const fs::u8path& target_prefix, const fs::u8path& path)
|
||||
{
|
||||
std::error_code ec;
|
||||
std::size_t result = 0;
|
||||
|
@ -620,13 +619,12 @@ namespace mamba
|
|||
{
|
||||
// The conda-meta directory is locked by transaction execute
|
||||
auto trash_index = open_ofstream(
|
||||
context.prefix_params.target_prefix / "conda-meta" / "mamba_trash.txt",
|
||||
target_prefix / "conda-meta" / "mamba_trash.txt",
|
||||
std::ios::app | std::ios::binary
|
||||
);
|
||||
|
||||
// TODO add some unicode tests here?
|
||||
trash_index << fs::relative(trash_file, context.prefix_params.target_prefix).string()
|
||||
<< "\n";
|
||||
trash_index << fs::relative(trash_file, target_prefix).string() << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1395,20 +1393,16 @@ namespace mamba
|
|||
return infile;
|
||||
}
|
||||
|
||||
WrappedCallOptions WrappedCallOptions::from_context(const Context& context)
|
||||
namespace
|
||||
{
|
||||
return {
|
||||
/* .is_mamba_exe = */ context.command_params.is_mamba_exe,
|
||||
/* .dev_mode = */ context.dev,
|
||||
/* .debug_wrapper_scripts = */ false,
|
||||
};
|
||||
constexpr bool debug_wrapper_scripts = false;
|
||||
}
|
||||
|
||||
std::unique_ptr<TemporaryFile> wrap_call(
|
||||
const fs::u8path& root_prefix,
|
||||
const fs::u8path& prefix,
|
||||
const std::vector<std::string>& arguments,
|
||||
const WrappedCallOptions options
|
||||
bool is_mamba_exe
|
||||
)
|
||||
{
|
||||
// todo add abspath here
|
||||
|
@ -1423,16 +1417,9 @@ namespace mamba
|
|||
|
||||
std::string bat_name = get_self_exe_path().stem().string();
|
||||
|
||||
if (options.dev_mode)
|
||||
{
|
||||
conda_bat = (fs::u8path(CONDA_PACKAGE_ROOT) / "shell" / "condabin" / "conda.bat").string();
|
||||
}
|
||||
else
|
||||
{
|
||||
conda_bat = util::get_env("CONDA_BAT")
|
||||
.value_or((fs::absolute(root_prefix) / "condabin" / bat_name).string());
|
||||
}
|
||||
if (!fs::exists(conda_bat) && options.is_mamba_exe)
|
||||
conda_bat = util::get_env("CONDA_BAT")
|
||||
.value_or((fs::absolute(root_prefix) / "condabin" / bat_name).string());
|
||||
if (!fs::exists(conda_bat) && is_mamba_exe)
|
||||
{
|
||||
// this adds in the needed .bat files for activation
|
||||
init_root_prefix_cmdexe(root_prefix);
|
||||
|
@ -1442,7 +1429,7 @@ namespace mamba
|
|||
|
||||
std::ofstream out = open_ofstream(tf->path());
|
||||
|
||||
std::string silencer = options.debug_wrapper_scripts ? "" : "@";
|
||||
std::string silencer = debug_wrapper_scripts ? "" : "@";
|
||||
|
||||
out << silencer << "ECHO OFF\n";
|
||||
out << silencer << "SET PYTHONIOENCODING=utf-8\n";
|
||||
|
@ -1452,21 +1439,7 @@ namespace mamba
|
|||
"do set \"_CONDA_OLD_CHCP=%%B\"\n";
|
||||
out << silencer << "chcp 65001 > NUL\n";
|
||||
|
||||
if (options.dev_mode)
|
||||
{
|
||||
// from conda.core.initialize import CONDA_PACKAGE_ROOT
|
||||
out << silencer << "SET CONDA_DEV=1\n";
|
||||
// In dev mode, conda is really:
|
||||
// 'python -m conda'
|
||||
// *with* PYTHONPATH set.
|
||||
out << silencer << "SET PYTHONPATH=" << CONDA_PACKAGE_ROOT << "\n";
|
||||
out << silencer << "SET CONDA_EXE=" << "python.exe" << "\n"; // TODO this should be
|
||||
// `sys.executable`
|
||||
out << silencer << "SET _CE_M=-m\n";
|
||||
out << silencer << "SET _CE_CONDA=conda\n";
|
||||
}
|
||||
|
||||
if (options.debug_wrapper_scripts)
|
||||
if (debug_wrapper_scripts)
|
||||
{
|
||||
out << "echo *** environment before *** 1>&2\n";
|
||||
out << "SET 1>&2\n";
|
||||
|
@ -1475,7 +1448,7 @@ namespace mamba
|
|||
out << silencer << "CALL \"" << conda_bat << "\" activate " << prefix << "\n";
|
||||
out << silencer << "IF %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%\n";
|
||||
|
||||
if (options.debug_wrapper_scripts)
|
||||
if (debug_wrapper_scripts)
|
||||
{
|
||||
out << "echo *** environment after *** 1>&2\n";
|
||||
out << "SET 1>&2\n";
|
||||
|
@ -1487,33 +1460,15 @@ namespace mamba
|
|||
|
||||
std::string shebang, dev_arg;
|
||||
|
||||
if (!options.is_mamba_exe)
|
||||
if (!is_mamba_exe)
|
||||
{
|
||||
// During tests, we sometimes like to have a temp env with e.g. an old python
|
||||
// in it and have it run tests against the very latest development sources.
|
||||
// For that to work we need extra smarts here, we want it to be instead:
|
||||
if (options.dev_mode)
|
||||
if (auto exe = util::get_env("CONDA_EXE"))
|
||||
{
|
||||
shebang += std::string(root_prefix / "bin" / "python");
|
||||
shebang += " -m conda";
|
||||
|
||||
dev_arg = "--dev";
|
||||
shebang = exe.value();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto exe = util::get_env("CONDA_EXE"))
|
||||
{
|
||||
shebang = exe.value();
|
||||
}
|
||||
else
|
||||
{
|
||||
shebang = std::string(root_prefix / "bin" / "conda");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.dev_mode)
|
||||
{
|
||||
// out << ">&2 export PYTHONPATH=" << CONDA_PACKAGE_ROOT << "\n";
|
||||
shebang = std::string(root_prefix / "bin" / "conda");
|
||||
}
|
||||
|
||||
hook_quoted << std::quoted(shebang, '\'') << " 'shell.posix' 'hook' " << dev_arg;
|
||||
|
@ -1525,7 +1480,7 @@ namespace mamba
|
|||
hook_quoted << "\"$MAMBA_EXE\" 'shell' 'hook' '-s' 'bash' '-r' "
|
||||
<< std::quoted(root_prefix.string(), '\'');
|
||||
}
|
||||
if (options.debug_wrapper_scripts)
|
||||
if (debug_wrapper_scripts)
|
||||
{
|
||||
out << "set -x\n";
|
||||
out << ">&2 echo \"*** environment before ***\"\n"
|
||||
|
@ -1534,7 +1489,7 @@ namespace mamba
|
|||
}
|
||||
out << "eval \"$(" << hook_quoted.str() << ")\"\n";
|
||||
|
||||
if (!options.is_mamba_exe)
|
||||
if (!is_mamba_exe)
|
||||
{
|
||||
out << "conda activate " << dev_arg << " " << std::quoted(prefix.string()) << "\n";
|
||||
}
|
||||
|
@ -1545,7 +1500,7 @@ namespace mamba
|
|||
}
|
||||
|
||||
|
||||
if (options.debug_wrapper_scripts)
|
||||
if (debug_wrapper_scripts)
|
||||
{
|
||||
out << ">&2 echo \"*** environment after ***\"\n"
|
||||
<< ">&2 env\n";
|
||||
|
@ -1559,7 +1514,7 @@ namespace mamba
|
|||
PreparedWrappedCall prepare_wrapped_call(
|
||||
const PrefixParams& prefix_params,
|
||||
const std::vector<std::string>& cmd,
|
||||
WrappedCallOptions options
|
||||
bool is_mamba_exe
|
||||
)
|
||||
{
|
||||
std::vector<std::string> command_args;
|
||||
|
@ -1576,7 +1531,12 @@ namespace mamba
|
|||
);
|
||||
}
|
||||
|
||||
script_file = wrap_call(prefix_params.root_prefix, prefix_params.target_prefix, cmd, options);
|
||||
script_file = wrap_call(
|
||||
prefix_params.root_prefix,
|
||||
prefix_params.target_prefix,
|
||||
cmd,
|
||||
is_mamba_exe
|
||||
);
|
||||
|
||||
command_args = { comspec.value(), "/D", "/C", script_file->path().string() };
|
||||
}
|
||||
|
@ -1594,7 +1554,12 @@ namespace mamba
|
|||
shell_path = "sh";
|
||||
}
|
||||
|
||||
script_file = wrap_call(prefix_params.root_prefix, prefix_params.target_prefix, cmd, options);
|
||||
script_file = wrap_call(
|
||||
prefix_params.root_prefix,
|
||||
prefix_params.target_prefix,
|
||||
cmd,
|
||||
is_mamba_exe
|
||||
);
|
||||
command_args.push_back(shell_path.string());
|
||||
command_args.push_back(script_file->path().string());
|
||||
}
|
||||
|
|
|
@ -1080,11 +1080,11 @@ namespace mamba
|
|||
|
||||
TEST_BOOL_CONFIGURABLE(retry_clean_cache, config.at("retry_clean_cache").value<bool>());
|
||||
|
||||
TEST_BOOL_CONFIGURABLE(allow_softlinks, ctx.allow_softlinks);
|
||||
TEST_BOOL_CONFIGURABLE(allow_softlinks, ctx.link_params.allow_softlinks);
|
||||
|
||||
TEST_BOOL_CONFIGURABLE(always_softlink, ctx.always_softlink);
|
||||
TEST_BOOL_CONFIGURABLE(always_softlink, ctx.link_params.always_softlink);
|
||||
|
||||
TEST_BOOL_CONFIGURABLE(always_copy, ctx.always_copy);
|
||||
TEST_BOOL_CONFIGURABLE(always_copy, ctx.link_params.always_copy);
|
||||
|
||||
TEST_CASE_METHOD(Configuration, "always_softlink_and_copy")
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "mamba/core/channel_context.hpp"
|
||||
#include "mamba/core/context.hpp"
|
||||
#include "mamba/core/environments_manager.hpp"
|
||||
#include "mamba/core/fsutil.hpp"
|
||||
#include "mamba/core/history.hpp"
|
||||
#include "mamba/core/link.hpp"
|
||||
|
@ -131,15 +132,19 @@ namespace mamba
|
|||
ctx.envs_dirs = { ctx.prefix_params.root_prefix / "envs" };
|
||||
fs::u8path prefix = "/home/user/micromamba/envs/testprefix";
|
||||
|
||||
REQUIRE(env_name(ctx, prefix) == "testprefix");
|
||||
auto& pp = ctx.prefix_params;
|
||||
REQUIRE(env_name(ctx.envs_dirs, pp.root_prefix, prefix) == "testprefix");
|
||||
prefix = "/home/user/micromamba/envs/a.txt";
|
||||
REQUIRE(env_name(ctx, prefix) == "a.txt");
|
||||
REQUIRE(env_name(ctx.envs_dirs, pp.root_prefix, prefix) == "a.txt");
|
||||
prefix = "/home/user/micromamba/envs/a.txt";
|
||||
REQUIRE(env_name(ctx, prefix) == "a.txt");
|
||||
REQUIRE(env_name(ctx.envs_dirs, pp.root_prefix, prefix) == "a.txt");
|
||||
prefix = "/home/user/micromamba/envs/abc/a.txt";
|
||||
REQUIRE(env_name(ctx, prefix) == "/home/user/micromamba/envs/abc/a.txt");
|
||||
REQUIRE(
|
||||
env_name(ctx.envs_dirs, pp.root_prefix, prefix)
|
||||
== "/home/user/micromamba/envs/abc/a.txt"
|
||||
);
|
||||
prefix = "/home/user/env";
|
||||
REQUIRE(env_name(ctx, prefix) == "/home/user/env");
|
||||
REQUIRE(env_name(ctx.envs_dirs, pp.root_prefix, prefix) == "/home/user/env");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -929,10 +929,10 @@ bind_submodule_impl(pybind11::module_ m)
|
|||
.def_readwrite("json", &Context::OutputParams::json)
|
||||
.def_readwrite("quiet", &Context::OutputParams::quiet);
|
||||
|
||||
py::class_<Context::ThreadsParams>(ctx, "ThreadsParams")
|
||||
py::class_<ThreadsParams>(ctx, "ThreadsParams")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("download_threads", &Context::ThreadsParams::download_threads)
|
||||
.def_readwrite("extract_threads", &Context::ThreadsParams::extract_threads);
|
||||
.def_readwrite("download_threads", &ThreadsParams::download_threads)
|
||||
.def_readwrite("extract_threads", &ThreadsParams::extract_threads);
|
||||
|
||||
py::class_<PrefixParams>(ctx, "PrefixParams")
|
||||
.def(py::init<>())
|
||||
|
|
|
@ -328,7 +328,7 @@ set_env_command(CLI::App* com, mamba::Configuration& config)
|
|||
{
|
||||
const auto& prefix = ctx.prefix_params.target_prefix;
|
||||
// Remove env directory or rename it (e.g. if used)
|
||||
remove_or_rename(ctx, mamba::util::expand_home(prefix.string()));
|
||||
mamba::remove_or_rename(prefix, mamba::util::expand_home(prefix.string()));
|
||||
|
||||
mamba::EnvironmentsManager env_manager{ ctx };
|
||||
// Unregister environment
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "mamba/api/configuration.hpp"
|
||||
#include "mamba/api/install.hpp"
|
||||
#include "mamba/core/environments_manager.hpp"
|
||||
#include "mamba/core/error_handling.hpp"
|
||||
#include "mamba/core/execution.hpp"
|
||||
#include "mamba/core/util_os.hpp"
|
||||
|
@ -66,7 +67,7 @@ set_ps_command(CLI::App* subcom, Context& context)
|
|||
auto prefix = el["prefix"].get<std::string>();
|
||||
if (!prefix.empty())
|
||||
{
|
||||
prefix = env_name(context, prefix);
|
||||
prefix = env_name(context.envs_dirs, context.prefix_params.root_prefix, prefix);
|
||||
}
|
||||
|
||||
table.add_row({
|
||||
|
|
Loading…
Reference in New Issue