mamba/libmamba/src/api/shell.cpp

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
}