mirror of https://github.com/mamba-org/mamba.git
154 lines
4.7 KiB
C++
154 lines
4.7 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 <iostream>
|
|
|
|
#include <fmt/format.h>
|
|
|
|
#include "mamba/api/shell.hpp"
|
|
#include "mamba/core/activation.hpp"
|
|
#include "mamba/core/context.hpp"
|
|
#include "mamba/core/shell_init.hpp"
|
|
#include "mamba/core/output.hpp"
|
|
#include "mamba/fs/filesystem.hpp"
|
|
#include "mamba/util/path_manip.hpp"
|
|
|
|
#ifdef _WIN32
|
|
#include "mamba/core/util_os.hpp"
|
|
#endif
|
|
|
|
namespace mamba
|
|
{
|
|
namespace
|
|
{
|
|
auto make_activator(const Context& context, std::string_view name)
|
|
-> std::unique_ptr<Activator>
|
|
{
|
|
if (name == "bash" || name == "zsh" || name == "dash" || name == "posix")
|
|
{
|
|
return std::make_unique<mamba::PosixActivator>(context);
|
|
}
|
|
if (name == "csh" || name == "tcsh")
|
|
{
|
|
return std::make_unique<mamba::CshActivator>(context);
|
|
}
|
|
if (name == "cmd.exe")
|
|
{
|
|
return std::make_unique<mamba::CmdExeActivator>(context);
|
|
}
|
|
if (name == "powershell")
|
|
{
|
|
return std::make_unique<mamba::PowerShellActivator>(context);
|
|
}
|
|
if (name == "xonsh")
|
|
{
|
|
return std::make_unique<mamba::XonshActivator>(context);
|
|
}
|
|
if (name == "fish")
|
|
{
|
|
return std::make_unique<mamba::FishActivator>(context);
|
|
}
|
|
if (name == "nu")
|
|
{
|
|
return std::make_unique<mamba::NuActivator>(context);
|
|
}
|
|
throw std::invalid_argument(fmt::format("Shell type not handled: {}", name));
|
|
}
|
|
}
|
|
|
|
void shell_init(Context& ctx, const std::string& shell_type, const fs::u8path& prefix)
|
|
{
|
|
if (prefix.empty() || prefix == "base")
|
|
{
|
|
init_shell(ctx, shell_type, ctx.prefix_params.root_prefix);
|
|
}
|
|
else
|
|
{
|
|
init_shell(ctx, shell_type, fs::weakly_canonical(util::expand_home(prefix.string())));
|
|
}
|
|
}
|
|
|
|
void shell_deinit(Context& ctx, const std::string& shell_type, const fs::u8path& prefix)
|
|
{
|
|
if (prefix.empty() || prefix == "base")
|
|
{
|
|
deinit_shell(ctx, shell_type, ctx.prefix_params.root_prefix);
|
|
}
|
|
else
|
|
{
|
|
deinit_shell(ctx, shell_type, fs::weakly_canonical(util::expand_home(prefix.string())));
|
|
}
|
|
}
|
|
|
|
void shell_reinit(Context& ctx, const fs::u8path& prefix)
|
|
{
|
|
// re-initialize all the shell scripts after update
|
|
for (const auto& shell_type : find_initialized_shells())
|
|
{
|
|
shell_init(ctx, shell_type, prefix);
|
|
}
|
|
}
|
|
|
|
void shell_hook(Context& ctx, const std::string& shell_type)
|
|
{
|
|
auto activator = make_activator(ctx, shell_type);
|
|
// TODO do we need to do something with `shell_prefix -> root_prefix?`?
|
|
if (ctx.output_params.json)
|
|
{
|
|
Console::instance().json_write({ { "success", true },
|
|
{ "operation", "shell_hook" },
|
|
{ "context", { { "shell_type", shell_type } } },
|
|
{ "actions",
|
|
{ { "print", { activator->hook(shell_type) } } } } });
|
|
}
|
|
else
|
|
{
|
|
std::cout << activator->hook(shell_type);
|
|
}
|
|
}
|
|
|
|
void
|
|
shell_activate(Context& ctx, const fs::u8path& prefix, const std::string& shell_type, bool stack)
|
|
{
|
|
if (!fs::exists(prefix))
|
|
{
|
|
throw std::runtime_error(
|
|
fmt::format("Cannot activate, prefix does not exist at: {}", prefix)
|
|
);
|
|
}
|
|
|
|
auto activator = make_activator(ctx, shell_type);
|
|
std::cout << activator->activate(prefix, stack);
|
|
}
|
|
|
|
void shell_reactivate(Context& ctx, const std::string& shell_type)
|
|
{
|
|
auto activator = make_activator(ctx, shell_type);
|
|
std::cout << activator->reactivate();
|
|
}
|
|
|
|
void shell_deactivate(Context& ctx, const std::string& shell_type)
|
|
{
|
|
auto activator = make_activator(ctx, shell_type);
|
|
std::cout << activator->deactivate();
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
void shell_enable_long_path_support(Palette palette)
|
|
{
|
|
if (const bool success = enable_long_paths_support(/* force= */ true, palette); !success)
|
|
{
|
|
throw std::runtime_error("Error enabling Windows long-path support");
|
|
}
|
|
}
|
|
#else
|
|
void shell_enable_long_path_support(Palette)
|
|
{
|
|
throw std::invalid_argument("Long path support is a Windows only option");
|
|
}
|
|
#endif
|
|
}
|