mirror of https://github.com/mamba-org/mamba.git
173 lines
5.4 KiB
C++
173 lines
5.4 KiB
C++
// Copyright (c) 2019, 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 "mamba/api/configuration.hpp"
|
|
#include "mamba/api/shell.hpp"
|
|
|
|
#include "mamba/core/activation.hpp"
|
|
#include "mamba/core/context.hpp"
|
|
#include "mamba/core/environment.hpp"
|
|
#include "mamba/core/mamba_fs.hpp"
|
|
#include "mamba/core/shell_init.hpp"
|
|
#include "mamba/core/util_os.hpp"
|
|
|
|
|
|
namespace mamba
|
|
{
|
|
void detect_shell(std::string& shell_type)
|
|
{
|
|
if (shell_type.empty())
|
|
{
|
|
LOG_DEBUG << "No shell type provided";
|
|
|
|
std::string guessed_shell = guess_shell();
|
|
if (!guessed_shell.empty())
|
|
{
|
|
LOG_DEBUG << "Guessed shell: '" << guessed_shell << "'";
|
|
shell_type = guessed_shell;
|
|
}
|
|
|
|
if (shell_type.empty())
|
|
{
|
|
LOG_ERROR << "Please provide a shell type." << std::endl
|
|
<< "Run with --help for more information." << std::endl;
|
|
throw std::runtime_error("Unknown shell type. Aborting.");
|
|
}
|
|
}
|
|
}
|
|
|
|
void shell(const std::string& action,
|
|
std::string& shell_type,
|
|
const std::string& prefix,
|
|
bool stack)
|
|
{
|
|
auto& ctx = Context::instance();
|
|
auto& config = Configuration::instance();
|
|
|
|
config.at("show_banner").set_value(false);
|
|
config.at("use_target_prefix_fallback").set_value(false);
|
|
config.at("target_prefix_checks").set_value(MAMBA_NO_PREFIX_CHECK);
|
|
config.load();
|
|
|
|
detect_shell(shell_type);
|
|
|
|
std::string shell_prefix = env::expand_user(prefix);
|
|
std::unique_ptr<Activator> activator;
|
|
|
|
if (shell_type == "bash" || shell_type == "zsh" || shell_type == "posix")
|
|
{
|
|
activator = std::make_unique<mamba::PosixActivator>();
|
|
}
|
|
else if (shell_type == "cmd.exe")
|
|
{
|
|
activator = std::make_unique<mamba::CmdExeActivator>();
|
|
}
|
|
else if (shell_type == "powershell")
|
|
{
|
|
activator = std::make_unique<mamba::PowerShellActivator>();
|
|
}
|
|
else if (shell_type == "xonsh")
|
|
{
|
|
activator = std::make_unique<mamba::XonshActivator>();
|
|
}
|
|
else if (shell_type == "fish")
|
|
{
|
|
activator = std::make_unique<mamba::FishActivator>();
|
|
}
|
|
else
|
|
{
|
|
LOG_ERROR << "Not handled 'shell_type': " << shell_type;
|
|
return;
|
|
}
|
|
|
|
if (action == "init")
|
|
{
|
|
if (shell_prefix == "base")
|
|
{
|
|
shell_prefix = ctx.root_prefix;
|
|
}
|
|
if (shell_prefix.empty())
|
|
{
|
|
LOG_ERROR << "Empty prefix";
|
|
throw std::runtime_error("Calling shell init with empty prefix");
|
|
}
|
|
init_shell(shell_type, shell_prefix);
|
|
}
|
|
else if (action == "hook")
|
|
{
|
|
// TODO do we need to do something wtih `shell_prefix -> root_prefix?`?
|
|
if (ctx.json)
|
|
{
|
|
JsonLogger::instance().json_write(
|
|
{ { "success", true },
|
|
{ "operation", "shell_hook" },
|
|
{ "context", { { "shell_type", shell_type } } },
|
|
{ "actions", { { "print", { activator->hook() } } } } });
|
|
if (Context::instance().json)
|
|
Console::instance().print(JsonLogger::instance().json_log.unflatten().dump(4),
|
|
true);
|
|
}
|
|
else
|
|
{
|
|
std::cout << activator->hook();
|
|
}
|
|
}
|
|
else if (action == "activate")
|
|
{
|
|
if (shell_prefix == "base" || shell_prefix.empty())
|
|
{
|
|
shell_prefix = ctx.root_prefix;
|
|
}
|
|
if (shell_prefix.find_first_of("/\\") == std::string::npos)
|
|
{
|
|
shell_prefix = ctx.root_prefix / "envs" / shell_prefix;
|
|
}
|
|
if (!fs::exists(shell_prefix))
|
|
{
|
|
throw std::runtime_error("Cannot activate, prefix does not exist at: "
|
|
+ shell_prefix);
|
|
}
|
|
|
|
std::cout << activator->activate(shell_prefix, stack);
|
|
}
|
|
else if (action == "reactivate")
|
|
{
|
|
std::cout << activator->reactivate();
|
|
}
|
|
else if (action == "deactivate")
|
|
{
|
|
std::cout << activator->deactivate();
|
|
}
|
|
#ifdef _WIN32
|
|
else if (action == "enable-long-paths-support")
|
|
{
|
|
if (!enable_long_paths_support(true))
|
|
{
|
|
exit(1);
|
|
}
|
|
}
|
|
#endif
|
|
else if (action == "completion")
|
|
{
|
|
if (shell_type == "bash")
|
|
{
|
|
}
|
|
else
|
|
{
|
|
LOG_ERROR << "Shell auto-completion is not supported in '" << shell_type << "'";
|
|
throw std::runtime_error("Shell auto-completion is not supported in '" + shell_type
|
|
+ "'");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw std::runtime_error("Need an action (activate, deactivate or hook)");
|
|
}
|
|
|
|
config.operation_teardown();
|
|
}
|
|
} // mamba
|