Skip to content

Commit

Permalink
Merge branch 'mamba-org:main' into reverse
Browse files Browse the repository at this point in the history
  • Loading branch information
SandrineP authored Jan 7, 2025
2 parents 34c06d4 + 0abd7d5 commit 4ced0b8
Show file tree
Hide file tree
Showing 18 changed files with 351 additions and 76 deletions.
2 changes: 2 additions & 0 deletions libmamba/include/mamba/core/package_fetcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ namespace mamba

struct CheckSumParams;

bool is_local_package() const;
bool use_explicit_https_url() const;
const std::string& filename() const;
std::string channel() const;
std::string url_path() const;
Expand Down
4 changes: 4 additions & 0 deletions libmamba/include/mamba/core/transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ namespace mamba
MultiPackageCache& package_caches,
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
5 changes: 4 additions & 1 deletion libmamba/src/api/channel_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@ namespace mamba
specs::CondaURL& prev_channel_url
)
{
static bool has_shown_anaconda_channel_warning = false;
for (const auto& platform : channel.platforms())
{
auto show_warning = ctx.show_anaconda_channel_warnings;
auto channel_name = channel.platform_url(platform).host();
if (channel_name == "repo.anaconda.com" && show_warning)
if (channel_name == "repo.anaconda.com" && show_warning
&& !has_shown_anaconda_channel_warning)
{
has_shown_anaconda_channel_warning = true;
LOG_WARNING << "'" << channel_name
<< "', a commercial channel hosted by Anaconda.com, is used.\n";
LOG_WARNING << "Please make sure you understand Anaconda Terms of Services.\n";
Expand Down
13 changes: 13 additions & 0 deletions libmamba/src/api/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,19 @@ namespace mamba
dirs.push_back(default_env_dir);
}

// Also add all the directories in the environment variable `CONDA_ENVS_PATH`.
auto conda_envs_path = util::get_env("CONDA_ENVS_PATH");
if (conda_envs_path)
{
auto paths_separator = util::pathsep();

auto paths = util::split(conda_envs_path.value(), paths_separator);
for (auto& p : paths)
{
dirs.push_back(fs::u8path(p));
}
}

// Check that the values exist as directories
for (auto& d : dirs)
{
Expand Down
12 changes: 12 additions & 0 deletions libmamba/src/api/install.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,12 @@ namespace mamba

trans.execute(ctx, channel_context, prefix_data);

// Print activation message only if the environment is freshly created
if (create_env)
{
print_activation_message(ctx);
}

if (!ctx.dry_run)
{
for (auto other_spec : config.at("others_pkg_mgrs_specs")
Expand Down Expand Up @@ -641,6 +647,12 @@ namespace mamba

transaction.execute(ctx, channel_context, prefix_data);

// Print activation message only if the environment is freshly created
if (create_env)
{
print_activation_message(ctx);
}

for (auto other_spec : others)
{
install_for_other_pkgmgr(ctx, other_spec, pip::Update::No);
Expand Down
31 changes: 21 additions & 10 deletions libmamba/src/core/package_fetcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,19 @@ namespace mamba
/*******************
* Private methods *
*******************/
bool PackageFetcher::is_local_package() const
{
return util::starts_with(m_package_info.package_url, "file://");
}

bool PackageFetcher::use_explicit_https_url() const
{
// This excludes OCI case, which uses explicitly a "oci://" scheme,
// but is resolved later to something starting with `oci_base_url`
constexpr std::string_view oci_base_url = "https://pkg-containers.githubusercontent.com/";
return util::starts_with(m_package_info.package_url, "https://")
&& !util::starts_with(m_package_info.package_url, oci_base_url);
}

const std::string& PackageFetcher::filename() const
{
Expand All @@ -325,26 +338,24 @@ namespace mamba

std::string PackageFetcher::channel() const
{
if (!util::starts_with(m_package_info.package_url, "file://"))
{
return m_package_info.channel;
}
else // local package case
if (is_local_package() || use_explicit_https_url())
{
// Use explicit url or local package path
// to fetch package, leaving the channel empty.
return "";
}
return m_package_info.channel;
}

std::string PackageFetcher::url_path() const
{
if (!util::starts_with(m_package_info.package_url, "file://"))
{
return util::concat(m_package_info.platform, '/', m_package_info.filename);
}
else // local package case
if (is_local_package() || use_explicit_https_url())
{
// Use explicit url or local package path
// to fetch package.
return m_package_info.package_url;
}
return util::concat(m_package_info.platform, '/', m_package_info.filename);
}

const std::string& PackageFetcher::url() const
Expand Down
78 changes: 40 additions & 38 deletions libmamba/src/core/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@ 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)
Expand Down Expand Up @@ -177,31 +203,33 @@ namespace mamba
[](const auto& pkg) { return explicit_spec(pkg); }
);

m_history_entry.update.reserve(pkgs_to_install.size());
for (auto& pkg : pkgs_to_install)
{
m_history_entry.update.push_back(explicit_spec(pkg).str());
}
m_history_entry.remove.reserve(pkgs_to_remove.size());
for (auto& pkg : pkgs_to_remove)
{
m_history_entry.remove.push_back(explicit_spec(pkg).str());
}

m_solution.actions.reserve(pkgs_to_install.size() + pkgs_to_remove.size());

std::transform(
std::move_iterator(pkgs_to_install.begin()),
std::move_iterator(pkgs_to_install.end()),
std::back_insert_iterator(m_solution.actions),
[](specs::PackageInfo&& pkg) { return solver::Solution::Install{ std::move(pkg) }; }
);

std::transform(
std::move_iterator(pkgs_to_remove.begin()),
std::move_iterator(pkgs_to_remove.end()),
std::back_insert_iterator(m_solution.actions),
[](specs::PackageInfo&& pkg) { return solver::Solution::Remove{ std::move(pkg) }; }
);

m_history_entry.remove.reserve(pkgs_to_remove.size());
for (auto& pkg : pkgs_to_remove)
{
m_history_entry.remove.push_back(explicit_spec(pkg).str());
}
m_history_entry.update.reserve(pkgs_to_install.size());
for (auto& pkg : pkgs_to_install)
{
m_history_entry.update.push_back(explicit_spec(pkg).str());
}

// if no action required, don't even start logging them
if (!empty())
{
Expand Down Expand Up @@ -438,33 +466,7 @@ namespace mamba
LOG_INFO << "Waiting for pyc compilation to finish";
m_transaction_context.wait_for_pyc_compilation();

// 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);

// Check if the target prefix is active
if (util::get_env("CONDA_PREFIX") == ctx.prefix_params.target_prefix)
{
Console::stream() << "\nTransaction finished\n";
}
else
{
Console::stream() << "\nTransaction finished\n\n"
"To 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";
}
Console::stream() << "\nTransaction finished\n";

prefix.history().add_entry(m_history_entry);
return true;
Expand Down
80 changes: 66 additions & 14 deletions libmamba/src/core/virtual_packages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "mamba/core/context.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"
Expand Down Expand Up @@ -65,9 +66,57 @@ namespace mamba
auto override_version = util::get_env("CONDA_OVERRIDE_CUDA");
if (override_version)
{
LOG_DEBUG << "CUDA version set by `CONDA_OVERRIDE_CUDA`: "
<< override_version.value();
return override_version.value();
}

std::string cuda_version;
std::string cuda_version_file = "/usr/local/cuda/version.json";

if (fs::exists(cuda_version_file))
{
LOG_DEBUG << "CUDA version file found: " << cuda_version_file;
std::ifstream f = open_ifstream(cuda_version_file);
nlohmann::json j;
f >> j;
if (auto it_cuda = j.find("cuda"); it_cuda != j.end())
{
auto cuda_val = *it_cuda;
if (auto it_cuda_version = cuda_val.find("version");
it_cuda_version != cuda_val.end())
{
cuda_version = it_cuda_version->get<std::string>();
LOG_DEBUG << "CUDA version found: " << cuda_version;

// Extract major, minor and patch version number from the version string
// and return only major.minor to match the cuda package version return
// by `nvidia-smi --query -u -x`
std::regex re("([0-9]+)\\.([0-9]+)\\.([0-9]+)");
std::smatch m;
if (std::regex_search(cuda_version, m, re) && m.size() >= 3)
{
std::ssub_match major = m[1];
std::ssub_match minor = m[2];
cuda_version = major.str() + "." + minor.str();
LOG_DEBUG << "CUDA version returned: " << cuda_version;
return cuda_version;
}
}
LOG_WARNING << "Could not extract CUDA version from: " << cuda_version;
}
else
{
LOG_WARNING << "CUDA version not found in the JSON file (`.cuda.version` is missing)";
}
}
else
{
LOG_DEBUG << "CUDA version file not found: " << cuda_version_file;
}

LOG_DEBUG << "Trying to find CUDA version by running `nvidia-smi --query -u -x`";

std::string out, err;
std::vector<std::string> args = { "nvidia-smi", "--query", "-u", "-x" };
auto [status, ec] = reproc::run(
Expand Down Expand Up @@ -125,26 +174,29 @@ namespace mamba
}
}

if (out.empty())
if (!out.empty())
{
LOG_DEBUG << "Could not find CUDA version by calling 'nvidia-smi' (skipped)\n";
return "";
}

std::regex re("<cuda_version>(.*)<\\/cuda_version>");
std::smatch m;
std::regex re("<cuda_version>(.*)<\\/cuda_version>");
std::smatch m;

if (std::regex_search(out, m, re))
{
if (m.size() == 2)
if (std::regex_search(out, m, re))
{
std::ssub_match cuda_version = m[1];
LOG_DEBUG << "CUDA driver version found: " << cuda_version;
return cuda_version.str();
if (m.size() == 2)
{
std::ssub_match cuda_version_match = m[1];
LOG_DEBUG << "CUDA driver version found: " << cuda_version_match;
return cuda_version_match.str();
}
}
}

LOG_DEBUG << "CUDA not found";
LOG_WARNING << "Could not find CUDA version by, in this order:\n";
LOG_WARNING << " - inspecting the `CONDA_OVERRIDE_CUDA` environment variable\n";
LOG_WARNING << " - parsing the : " << cuda_version_file << "\n";
LOG_WARNING << " - parsing the output of `nvidia-smi --query -u -x`\n";
LOG_WARNING << "\n";
LOG_WARNING << "We recommend setting the `CONDA_OVERRIDE_CUDA` environment variable\n";
LOG_WARNING << "to the desired CUDA version.";
return "";
}

Expand Down
24 changes: 23 additions & 1 deletion libmamba/src/solver/libsolv/unsolvable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ namespace mamba::solver::libsolv
std::optional<std::string>& dep = problem.dep;
SolverRuleinfo type = problem.type;

static bool hint_for_flexible_channel_priority = false;

switch (type)
{
case SOLVER_RULE_PKG_CONSTRAINS:
Expand Down Expand Up @@ -535,7 +537,27 @@ namespace mamba::solver::libsolv
default:
{
// Many more SolverRuleinfo that have not been encountered.
LOG_WARNING << "Problem type not implemented " << solv::enum_name(type);
if (!hint_for_flexible_channel_priority)
{
hint_for_flexible_channel_priority = true;
LOG_WARNING
<< "The specification of the environment does not seem solvable in your current setup.";
LOG_WARNING
<< "For instance, packages from different channels might be specified,";
LOG_WARNING
<< "whilst your current configuration might not allow their resolution.";
LOG_WARNING << "";
LOG_WARNING << "If it is the case, you need to either:";
LOG_WARNING
<< " - adapt the channel ordering (e.g. by reordering the `-c` flags in your command line)";
LOG_WARNING
<< " - use the flexible channel priority (e.g. using `--channel-priority flexible` in your command line)";
LOG_WARNING << "";
LOG_WARNING
<< "For reference, see this piece of documentation on channel priority:";
LOG_WARNING
<< "https://docs.conda.io/projects/conda/en/stable/user-guide/tasks/manage-channels.html#strict-channel-priority";
}
break;
}
}
Expand Down
Loading

0 comments on commit 4ced0b8

Please sign in to comment.