format all files

This commit is contained in:
Wolf Vollprecht 2022-02-22 15:58:57 +01:00
parent 7f9c5adb77
commit 42f2cd88ba
53 changed files with 1317 additions and 1126 deletions

View File

@ -126,14 +126,14 @@ namespace mamba
virtual void set_rc_yaml_value(const YAML::Node& value, const std::string& source) = 0;
virtual void set_rc_yaml_values(const std::map<std::string, YAML::Node>& values,
const std::vector<std::string>& sources) = 0;
const std::vector<std::string>& sources)
= 0;
virtual void set_cli_yaml_value(const YAML::Node& value) = 0;
virtual void set_cli_yaml_value(const std::string& value) = 0;
virtual void set_yaml_value(const YAML::Node& value) = 0;
virtual void set_yaml_value(const std::string& value) = 0;
virtual void compute(int options,
const ConfigurationLevel& level) = 0;
virtual void compute(int options, const ConfigurationLevel& level) = 0;
virtual bool is_valid_serialization(const std::string& value) const = 0;
@ -187,8 +187,7 @@ namespace mamba
void set_yaml_value(const YAML::Node& value) override;
void set_yaml_value(const std::string& value) override;
void compute(int options,
const ConfigurationLevel& level) override;
void compute(int options, const ConfigurationLevel& level) override;
bool is_valid_serialization(const std::string& value) const override;
bool is_sequence() const override;
@ -227,7 +226,6 @@ namespace mamba
class Configurable
{
public:
template <class T>
Configurable(const std::string& name, T* context);
@ -292,7 +290,7 @@ namespace mamba
template <class T>
Configurable&& set_rc_values(const std::map<std::string, T>& mapped_values,
const std::vector<std::string>& sources);
const std::vector<std::string>& sources);
template <class T>
Configurable&& set_value(const T& value);
@ -309,7 +307,7 @@ namespace mamba
template <class T>
using value_hook_type = typename detail::ConfigurableImpl<T>::value_hook_type;
template <class T>
using post_merge_hook_type =typename detail::ConfigurableImpl<T>::post_merge_hook_type;
using post_merge_hook_type = typename detail::ConfigurableImpl<T>::post_merge_hook_type;
using post_context_hook_type = detail::ConfigurableImplBase::post_context_hook_type;
template <class T>
@ -335,14 +333,14 @@ namespace mamba
Configurable&& set_rc_yaml_value(const YAML::Node& value, const std::string& source);
Configurable&& set_rc_yaml_values(const std::map<std::string, YAML::Node>& values,
const std::vector<std::string>& sources);
const std::vector<std::string>& sources);
Configurable&& set_cli_yaml_value(const YAML::Node& value);
Configurable&& set_cli_yaml_value(const std::string& value);
Configurable&& set_yaml_value(const YAML::Node& value);
Configurable&& set_yaml_value(const std::string& value);
Configurable&& compute(int options = 0,
const ConfigurationLevel& level = ConfigurationLevel::kDefault);
const ConfigurationLevel& level = ConfigurationLevel::kDefault);
bool is_valid_serialization(const std::string& value) const;
bool is_sequence() const;
@ -351,7 +349,6 @@ namespace mamba
void dump_json(nlohmann::json& node, const std::string& name) const;
private:
template <class T>
detail::ConfigurableImpl<T>& get_wrapped();
@ -382,8 +379,7 @@ namespace mamba
Configurable& at(const std::string& name);
using grouped_config_type = std::pair<std::string, std::vector<Configurable*>>;
std::vector<grouped_config_type>
get_grouped_config();
std::vector<grouped_config_type> get_grouped_config();
std::vector<fs::path> sources();
std::vector<fs::path> valid_sources();
@ -485,7 +481,8 @@ namespace mamba
}
template <class T>
void ConfigurableImpl<T>::set_rc_yaml_value(const YAML::Node& value, const std::string& source)
void ConfigurableImpl<T>::set_rc_yaml_value(const YAML::Node& value,
const std::string& source)
{
try
{
@ -499,8 +496,9 @@ namespace mamba
}
template <class T>
void ConfigurableImpl<T>::set_rc_yaml_values(const std::map<std::string, YAML::Node>& values,
const std::vector<std::string>& sources)
void ConfigurableImpl<T>::set_rc_yaml_values(
const std::map<std::string, YAML::Node>& values,
const std::vector<std::string>& sources)
{
std::map<std::string, T> converted_values;
for (auto& y : values)
@ -601,8 +599,7 @@ namespace mamba
}
template <class T>
void ConfigurableImpl<T>::compute(int options,
const ConfigurationLevel& level)
void ConfigurableImpl<T>::compute(int options, const ConfigurationLevel& level)
{
bool hook_disabled = options & MAMBA_CONF_DISABLE_HOOK;
bool force_compute = options & MAMBA_CONF_FORCE_COMPUTE;
@ -612,7 +609,8 @@ namespace mamba
else
LOG_TRACE << "Compute configurable '" << this->m_name << "'";
if (!force_compute && (Configuration::instance().is_loading() && (m_compute_counter > 0)))
if (!force_compute
&& (Configuration::instance().is_loading() && (m_compute_counter > 0)))
throw std::runtime_error("Multiple computation of '" + m_name
+ "' detected during loading sequence.");
@ -648,8 +646,8 @@ namespace mamba
catch (const YAML::Exception& e)
{
LOG_ERROR << "Bad conversion of configurable '" << this->m_name
<< "' from environment variable '" << env_var << "' with value '"
<< env_var_value.value() << "'";
<< "' from environment variable '" << env_var
<< "' with value '" << env_var_value.value() << "'";
throw e;
}
}
@ -761,7 +759,7 @@ namespace mamba
template <class T>
Configurable&& Configurable::set_rc_values(const std::map<std::string, T>& mapped_values,
const std::vector<std::string>& sources)
const std::vector<std::string>& sources)
{
get_wrapped<T>().set_rc_values(mapped_values, sources);
return std::move(*this);

View File

@ -27,11 +27,26 @@ namespace mamba
storage_type m_storage;
cli_config() = default;
cli_config(const T& value) : m_storage(value) {}
storage_type& storage() { return m_storage; }
bool has_value() const { return m_storage.has_value(); }
const T& value() const { return m_storage.value(); }
void reset() { m_storage.reset(); }
cli_config(const T& value)
: m_storage(value)
{
}
storage_type& storage()
{
return m_storage;
}
bool has_value() const
{
return m_storage.has_value();
}
const T& value() const
{
return m_storage.value();
}
void reset()
{
m_storage.reset();
}
};
template <>
@ -41,9 +56,18 @@ namespace mamba
storage_type m_storage;
cli_config() = default;
cli_config(int value) : m_storage(value) {}
storage_type& storage() { return m_storage; }
bool has_value() const { return m_storage != 0; }
cli_config(int value)
: m_storage(value)
{
}
storage_type& storage()
{
return m_storage;
}
bool has_value() const
{
return m_storage != 0;
}
bool value() const
{
if (m_storage == 1)
@ -52,9 +76,12 @@ namespace mamba
return false;
else
throw std::runtime_error(
"Invalid boolean storage, should be {'-1': false, '0': undefined, '1': true}");
"Invalid boolean storage, should be {'-1': false, '0': undefined, '1': true}");
}
void reset()
{
m_storage = 0;
}
void reset() { m_storage = 0; }
};
/**********************

View File

@ -30,14 +30,14 @@
#define ENUM_FLAG_OPERATOR(T, X) \
inline T operator X(T lhs, T rhs) \
{ \
return (T)(static_cast<std::underlying_type_t<T>>(lhs) \
X static_cast<std::underlying_type_t<T>>(rhs)); \
return (T) (static_cast<std::underlying_type_t<T>>(lhs) \
X static_cast<std::underlying_type_t<T>>(rhs)); \
}
#define ENUM_FLAGS(T) \
enum class T; \
inline T operator~(T t) \
{ \
return (T)(~static_cast<std::underlying_type_t<T>>(t)); \
return (T) (~static_cast<std::underlying_type_t<T>>(t)); \
} \
ENUM_FLAG_OPERATOR(T, |) \
ENUM_FLAG_OPERATOR(T, ^) \

View File

@ -33,7 +33,6 @@ namespace mamba
operator Pool*();
private:
std::pair<spdlog::logger*, std::string> m_debug_logger;
Pool* m_pool;
};

View File

@ -103,17 +103,19 @@ namespace mamba
{
increase_thread_count();
auto f = std::bind(std::forward<Function>(func), std::forward<Args>(args)...);
m_thread = std::thread([f]() {
try
m_thread = std::thread(
[f]()
{
f();
}
catch (thread_interrupted&)
{
errno = EINTR;
}
decrease_thread_count();
});
try
{
f();
}
catch (thread_interrupted&)
{
errno = EINTR;
}
decrease_thread_count();
});
}
/**********************

View File

@ -91,14 +91,14 @@ namespace mamba
return T{ seed_seq };
}
template<typename T = std::mt19937>
template <typename T = std::mt19937>
inline auto local_random_generator() -> T&
{
thread_local auto rng = random_generator<T>();
return rng;
}
template<typename T = int, typename G = std::mt19937>
template <typename T = int, typename G = std::mt19937>
inline T random_int(T min, T max, G& generator = local_random_generator())
{
return std::uniform_int_distribution<T>{ min, max }(generator);

View File

@ -15,13 +15,13 @@ namespace mamba
bool is_admin();
fs::path get_self_exe_path();
using PID =
using PID =
#ifdef _WIN32
DWORD
DWORD
#else
int
int
#endif
;
;
std::string get_process_name_by_pid(const PID pid);
#ifdef _WIN32

View File

@ -30,8 +30,8 @@ namespace mamba
bool clean_trash = options & MAMBA_CLEAN_TRASH;
bool clean_force_pkgs_dirs = options & MAMBA_CLEAN_FORCE_PKGS_DIRS;
if (!(clean_all || clean_index || clean_pkgs || clean_tarballs || clean_locks
|| clean_trash || clean_force_pkgs_dirs))
if (!(clean_all || clean_index || clean_pkgs || clean_tarballs || clean_locks || clean_trash
|| clean_force_pkgs_dirs))
{
Console::stream() << "Nothing to do." << std::endl;
return;
@ -144,13 +144,15 @@ namespace mamba
}
}
auto get_file_size = [](const auto& s) -> std::string {
auto get_file_size = [](const auto& s) -> std::string
{
std::stringstream ss;
to_human_readable_filesize(ss, s);
return ss.str();
};
auto collect_tarballs = [&]() {
auto collect_tarballs = [&]()
{
std::vector<fs::path> res;
std::size_t total_size = 0;
std::vector<printers::FormattedString> header = { "Package file", "Size" };
@ -176,9 +178,9 @@ namespace mamba
total_size += p.file_size();
}
}
std::sort(rows.begin(), rows.end(), [](const auto& a, const auto& b) {
return a[0].s < b[0].s;
});
std::sort(rows.begin(),
rows.end(),
[](const auto& a, const auto& b) { return a[0].s < b[0].s; });
t.add_rows(pkg_cache->path().string(), rows);
}
if (total_size)
@ -210,7 +212,8 @@ namespace mamba
}
}
auto get_folder_size = [](auto& p) {
auto get_folder_size = [](auto& p)
{
std::size_t size = 0;
for (auto& fp : fs::recursive_directory_iterator(p))
{
@ -222,7 +225,8 @@ namespace mamba
return size;
};
auto collect_package_folders = [&]() {
auto collect_package_folders = [&]()
{
std::vector<fs::path> res;
std::size_t total_size = 0;
std::vector<printers::FormattedString> header = { "Package folder", "Size" };
@ -252,9 +256,9 @@ namespace mamba
total_size += folder_size;
}
}
std::sort(rows.begin(), rows.end(), [](const auto& a, const auto& b) {
return a[0].s < b[0].s;
});
std::sort(rows.begin(),
rows.end(),
[](const auto& a, const auto& b) { return a[0].s < b[0].s; });
t.add_rows(pkg_cache->path().string(), rows);
}
if (total_size)
@ -295,7 +299,7 @@ namespace mamba
if (clean_force_pkgs_dirs)
{
for (auto* cache: caches.writable_caches())
for (auto* cache : caches.writable_caches())
{
fs::remove_all(cache->path());
}

View File

@ -89,7 +89,8 @@ namespace mamba
const std::string& Configurable::long_description() const
{
return p_impl->m_long_description.empty() ? p_impl->m_description : p_impl->m_long_description;
return p_impl->m_long_description.empty() ? p_impl->m_description
: p_impl->m_long_description;
}
Configurable&& Configurable::long_description(const std::string& desc)
@ -269,14 +270,15 @@ namespace mamba
return std::move(*this);
}
Configurable&& Configurable::set_rc_yaml_value(const YAML::Node& value, const std::string& source)
Configurable&& Configurable::set_rc_yaml_value(const YAML::Node& value,
const std::string& source)
{
p_impl->set_rc_yaml_value(value, source);
return std::move(*this);
}
Configurable&& Configurable::set_rc_yaml_values(const std::map<std::string, YAML::Node>& values,
const std::vector<std::string>& sources)
const std::vector<std::string>& sources)
{
p_impl->set_rc_yaml_values(values, sources);
return std::move(*this);
@ -306,8 +308,7 @@ namespace mamba
return std::move(*this);
}
Configurable&& Configurable::compute(int options,
const ConfigurationLevel& level)
Configurable&& Configurable::compute(int options, const ConfigurationLevel& level)
{
p_impl->compute(options, level);
return std::move(*this);
@ -378,8 +379,7 @@ namespace mamba
return;
}
auto& cacert
= Configuration::instance().at("cacert_path").value<std::string>();
auto& cacert = Configuration::instance().at("cacert_path").value<std::string>();
if (!cacert.empty())
{
value = cacert;
@ -834,10 +834,7 @@ namespace mamba
return fs::exists(path) && (!fs::is_directory(path)) && has_config_name(path.string());
}
void print_node(YAML::Emitter& out,
YAML::Node value,
YAML::Node source,
bool show_source);
void print_node(YAML::Emitter& out, YAML::Node value, YAML::Node source, bool show_source);
void print_scalar_node(YAML::Emitter& out,
YAML::Node value,
@ -904,10 +901,7 @@ namespace mamba
out << YAML::EndMap;
}
void print_node(YAML::Emitter& out,
YAML::Node value,
YAML::Node source,
bool show_source)
void print_node(YAML::Emitter& out, YAML::Node value, YAML::Node source, bool show_source)
{
if (value.IsScalar())
{
@ -923,9 +917,7 @@ namespace mamba
}
}
void print_configurable(YAML::Emitter& out,
const Configurable& config,
bool show_source)
void print_configurable(YAML::Emitter& out, const Configurable& config, bool show_source)
{
auto value = config.yaml_value();
auto source = YAML::Node(config.source());
@ -946,9 +938,7 @@ namespace mamba
out << YAML::Comment(std::string(54, '#'));
}
void dump_configurable(nl::json& node,
const Configurable& c,
const std::string& name)
void dump_configurable(nl::json& node, const Configurable& c, const std::string& name)
{
c.dump_json(node, name);
}
@ -1902,15 +1892,14 @@ namespace mamba
namespace detail
{
void dump_configurable(nl::json& node,
const Configurable& c,
const std::string& name);
void dump_configurable(nl::json& node, const Configurable& c, const std::string& name);
}
std::string dump_json(int opts, const std::vector<std::string>& names,
std::string dump_json(int opts,
const std::vector<std::string>& names,
const std::vector<Configuration::grouped_config_type>& grouped_config)
{
//bool show_values = opts & MAMBA_SHOW_CONFIG_VALUES;
// bool show_values = opts & MAMBA_SHOW_CONFIG_VALUES;
bool show_sources = opts & MAMBA_SHOW_CONFIG_SRCS;
bool show_descs = opts & MAMBA_SHOW_CONFIG_DESCS;
bool show_long_descs = opts & MAMBA_SHOW_CONFIG_LONG_DESCS;
@ -1982,7 +1971,8 @@ namespace mamba
return root.dump(4);
}
std::string dump_yaml(int opts, const std::vector<std::string>& names,
std::string dump_yaml(int opts,
const std::vector<std::string>& names,
const std::vector<Configuration::grouped_config_type>& grouped_config)
{
bool show_values = opts & MAMBA_SHOW_CONFIG_VALUES;

View File

@ -82,7 +82,8 @@ namespace mamba
const fs::path pkgs_dirs(ctx.root_prefix / "pkgs");
MultiPackageCache package_caches({ pkgs_dirs });
auto execute_transaction = [&](MTransaction& transaction) {
auto execute_transaction = [&](MTransaction& transaction)
{
if (ctx.json)
transaction.log_json();

View File

@ -114,7 +114,8 @@ namespace mamba
}
MTransaction transaction(solver, package_caches, repo_ptrs);
auto execute_transaction = [&](MTransaction& transaction) {
auto execute_transaction = [&](MTransaction& transaction)
{
if (ctx.json)
transaction.log_json();

View File

@ -267,9 +267,9 @@ namespace mamba
if (old_conda_shlvl == 0)
{
bool no_condabin
= std::none_of(path_list.begin(), path_list.end(), [](const std::string& s) {
return ends_with(s, "condabin");
});
= std::none_of(path_list.begin(),
path_list.end(),
[](const std::string& s) { return ends_with(s, "condabin"); });
if (no_condabin)
{
auto condabin_dir = Context::instance().root_prefix / "condabin";

View File

@ -610,7 +610,8 @@ namespace mamba
name = name.substr(0, platform_spec_ind);
}
auto add_channel = [&](const std::string& name) {
auto add_channel = [&](const std::string& name)
{
auto channel = &make_channel(name + platform_spec);
if (added.insert(channel).second)
{
@ -643,16 +644,20 @@ namespace mamba
whitelist.end(),
accepted_urls.begin(),
[](const std::string& url) { return make_channel(url).base_url(); });
std::for_each(urls.begin(), urls.end(), [&accepted_urls](const std::string& s) {
auto it = std::find(
accepted_urls.begin(), accepted_urls.end(), make_channel(s).base_url());
if (it == accepted_urls.end())
{
std::ostringstream str;
str << "Channel " << s << " not allowed";
throw std::runtime_error(str.str().c_str());
}
});
std::for_each(urls.begin(),
urls.end(),
[&accepted_urls](const std::string& s)
{
auto it = std::find(accepted_urls.begin(),
accepted_urls.end(),
make_channel(s).base_url());
if (it == accepted_urls.end())
{
std::ostringstream str;
str << "Channel " << s << " not allowed";
throw std::runtime_error(str.str().c_str());
}
});
}
}

View File

@ -23,12 +23,12 @@ namespace mamba
envs_dirs = { root_prefix / "envs" };
pkgs_dirs = { root_prefix / "pkgs",
fs::path("~") / ".mamba" / "pkgs"
fs::path("~") / ".mamba" / "pkgs"
#ifdef _WIN32
,
fs::path(env::get("APPDATA").value_or("")) / ".mamba" / "pkgs"
,
fs::path(env::get("APPDATA").value_or("")) / ".mamba" / "pkgs"
#endif
};
};
keep_temp_files = env::get("MAMBA_KEEP_TEMP") ? true : false;
keep_temp_directories = env::get("MAMBA_KEEP_TEMP_DIRS") ? true : false;
@ -47,8 +47,10 @@ namespace mamba
set_default_signal_handler();
std::shared_ptr<spdlog::logger> l = std::make_shared<Logger>("libmamba", log_pattern, "\n");
std::shared_ptr<spdlog::logger> libcurl_logger = std::make_shared<Logger>("libcurl", log_pattern, "");
std::shared_ptr<spdlog::logger> libsolv_logger = std::make_shared<Logger>("libsolv", log_pattern, "");
std::shared_ptr<spdlog::logger> libcurl_logger
= std::make_shared<Logger>("libcurl", log_pattern, "");
std::shared_ptr<spdlog::logger> libsolv_logger
= std::make_shared<Logger>("libsolv", log_pattern, "");
spdlog::register_logger(libcurl_logger);
spdlog::register_logger(libsolv_logger);

View File

@ -215,13 +215,10 @@ namespace mamba
}
}
int curl_debug_callback(CURL *handle,
curl_infotype type,
char *data,
size_t size,
void *userptr)
int curl_debug_callback(
CURL* handle, curl_infotype type, char* data, size_t size, void* userptr)
{
auto* logger = (spdlog::logger*)(userptr);
auto* logger = (spdlog::logger*) (userptr);
switch (type)
{
case CURLINFO_TEXT:
@ -358,8 +355,7 @@ namespace mamba
// remove \r\n header ending
auto header_end = header.find_first_of("\r\n");
value = header.substr(colon_idx,
(header_end > colon_idx) ? header_end - colon_idx : 0);
value = header.substr(colon_idx, (header_end > colon_idx) ? header_end - colon_idx : 0);
// http headers are case insensitive!
std::string lkey = to_lower(key);
@ -381,7 +377,8 @@ namespace mamba
std::function<void(ProgressBarRepr&)> DownloadTarget::download_repr()
{
return [&](ProgressBarRepr& r) -> void {
return [&](ProgressBarRepr& r) -> void
{
r.current.set_value(
fmt::format("{:>7}", to_human_readable_filesize(m_progress_bar.current(), 1)));
@ -440,9 +437,8 @@ namespace mamba
void DownloadTarget::set_mod_etag_headers(const nlohmann::json& mod_etag)
{
auto to_header = [](const std::string& key, const std::string& value) {
return std::string(key + ": " + value);
};
auto to_header = [](const std::string& key, const std::string& value)
{ return std::string(key + ": " + value); };
if (mod_etag.find("_etag") != mod_etag.end())
{
@ -753,9 +749,8 @@ namespace mamba
if (sort)
std::sort(m_targets.begin(),
m_targets.end(),
[](DownloadTarget* a, DownloadTarget* b) -> bool {
return a->expected_size() > b->expected_size();
});
[](DownloadTarget* a, DownloadTarget* b) -> bool
{ return a->expected_size() > b->expected_size(); });
LOG_INFO << "Starting to download targets";

View File

@ -75,7 +75,8 @@ namespace mamba
bool History::parse_comment_line(const std::string& line, UserRequest& req)
{
std::size_t colon_idx = line.find_first_of(':');
if (colon_idx == std::string::npos) return false;
if (colon_idx == std::string::npos)
return false;
std::string key(strip(line.substr(1, colon_idx - 1)));
std::string value(strip(line.substr(colon_idx + 1)));
@ -171,7 +172,8 @@ namespace mamba
{
std::unordered_map<std::string, MatchSpec> map;
auto to_specs = [](const std::vector<std::string>& sv) {
auto to_specs = [](const std::vector<std::string>& sv)
{
std::vector<MatchSpec> v;
v.reserve(sv.size());
for (const auto& el : sv)
@ -246,7 +248,8 @@ namespace mamba
}
auto specs_output = [](const std::string& action,
const std::vector<std::string>& specs) -> std::string {
const std::vector<std::string>& specs) -> std::string
{
if (specs.empty())
return "";
std::stringstream spec_ss;

View File

@ -104,7 +104,8 @@ namespace mamba
return;
}
auto extract_kv = [&spec_str](const std::string& kv_string, auto& map) {
auto extract_kv = [&spec_str](const std::string& kv_string, auto& map)
{
static std::regex kv_re("([a-zA-Z0-9_-]+?)=([\"\']?)([^\'\"]*?)(\\2)(?:[\'\", ]|$)");
std::cmatch kv_match;
const char* text_iter = kv_string.c_str();

View File

@ -220,7 +220,8 @@ namespace mamba
distribution_name[0] = std::toupper(distribution_name[0]);
}
auto to_forward_slash = [](const fs::path& p) {
auto to_forward_slash = [](const fs::path& p)
{
std::string ps = p.string();
replace_all(ps, "\\", "/");
return ps;
@ -313,7 +314,8 @@ namespace mamba
fs::create_directories(target_dir);
}
auto extend_script_args = [](const auto& item, auto& arguments) {
auto extend_script_args = [](const auto& item, auto& arguments)
{
// this is pretty bad ...
if (item.contains("scriptargument"))
{

View File

@ -112,7 +112,8 @@ namespace mamba
std::size_t total_length = std::accumulate(cell_sizes.begin(), cell_sizes.end(), 0);
total_length = std::accumulate(m_padding.begin(), m_padding.end(), total_length);
auto print_row = [this, &cell_sizes, &out](const std::vector<FormattedString>& row) {
auto print_row = [this, &cell_sizes, &out](const std::vector<FormattedString>& row)
{
for (size_t j = 0; j < row.size(); ++j)
{
if (row[j].flag != format::none)
@ -490,10 +491,10 @@ namespace mamba
}
Logger::Logger(const std::string& name, const std::string& pattern, const std::string& eol)
: spdlog::logger(name,
std::make_shared<spdlog::sinks::stderr_color_sink_mt>())
: spdlog::logger(name, std::make_shared<spdlog::sinks::stderr_color_sink_mt>())
{
auto f = std::make_unique<spdlog::pattern_formatter>(pattern, spdlog::pattern_time_type::local, eol);
auto f = std::make_unique<spdlog::pattern_formatter>(
pattern, spdlog::pattern_time_type::local, eol);
set_formatter(std::move(f));
}
@ -502,10 +503,12 @@ namespace mamba
using spdlog::details::log_msg;
if (tracer_.enabled())
{
tracer_.foreach_pop([this](const log_msg& msg) {
if (this->should_log(msg.level))
this->sink_it_(msg);
});
tracer_.foreach_pop(
[this](const log_msg& msg)
{
if (this->should_log(msg.level))
this->sink_it_(msg);
});
}
}

View File

@ -233,10 +233,11 @@ namespace mamba
fs::path out_file_abs = fs::absolute(out_file);
if (ends_with(out_file.string(), ".tar.bz2"))
{
create_archive(
directory, out_file_abs, bzip2, compression_level, [](const std::string&) {
return false;
});
create_archive(directory,
out_file_abs,
bzip2,
compression_level,
[](const std::string&) { return false; });
}
else if (ends_with(out_file.string(), ".conda"))
{

View File

@ -78,17 +78,15 @@ namespace mamba
PackageInfo::compare_fun PackageInfo::less(const std::string& member)
{
auto getter = get_field_getter(member);
return [getter](const PackageInfo& lhs, const PackageInfo& rhs) {
return getter(lhs) < getter(rhs);
};
return [getter](const PackageInfo& lhs, const PackageInfo& rhs)
{ return getter(lhs) < getter(rhs); };
}
PackageInfo::compare_fun PackageInfo::equal(const std::string& member)
{
auto getter = get_field_getter(member);
return [getter](const PackageInfo& lhs, const PackageInfo& rhs) {
return getter(lhs) == getter(rhs);
};
return [getter](const PackageInfo& lhs, const PackageInfo& rhs)
{ return getter(lhs) == getter(rhs); };
}
PackageInfo::PackageInfo(Solvable* s)

View File

@ -76,7 +76,8 @@ namespace mamba
auto info_dir = directory / "info";
auto paths_json_path = info_dir / "paths.json";
auto parse_file_mode = [](nlohmann::json& j) -> FileMode {
auto parse_file_mode = [](nlohmann::json& j) -> FileMode
{
if (j.find("file_mode") != j.end())
{
// check if "text" or "binary"
@ -92,7 +93,8 @@ namespace mamba
return FileMode::UNDEFINED;
};
auto parse_path_type = [](nlohmann::json& j) -> PathType {
auto parse_path_type = [](nlohmann::json& j) -> PathType
{
if (j.find("path_type") != j.end())
{
// TODO find a DIRECTORY path type

View File

@ -12,7 +12,7 @@ namespace mamba
{
void libsolv_debug_callback(Pool* pool, void* userptr, int type, const char* str)
{
auto* dbg = (std::pair<spdlog::logger*, std::string>*)(userptr);
auto* dbg = (std::pair<spdlog::logger*, std::string>*) (userptr);
dbg->second += str;
if (dbg->second.size() == 0 || dbg->second.back() != '\n')
{

View File

@ -612,8 +612,9 @@ namespace mamba
else
{
ProgressScaleWriter w{ width };
double in_progress = static_cast<double>(p_progress_bar->current() + p_progress_bar->in_progress())
/ static_cast<double>(p_progress_bar->total()) * 100.;
double in_progress
= static_cast<double>(p_progress_bar->current() + p_progress_bar->in_progress())
/ static_cast<double>(p_progress_bar->total()) * 100.;
sstream << w.repr(p_progress_bar->progress(), in_progress);
}
}
@ -628,7 +629,9 @@ namespace mamba
spinner = { "|", "/", "-", "|", "\\", "|", "/", "-", "|", "\\" };
constexpr int spinner_rounds = 2;
auto pos = static_cast<std::size_t>(std::round(progress * ((spinner_rounds * spinner.size()) / 100.0))) % spinner.size();
auto pos = static_cast<std::size_t>(
std::round(progress * ((spinner_rounds * spinner.size()) / 100.0)))
% spinner.size();
sstream << fmt::format("{:^4}", spinner[pos]);
}
else
@ -1124,21 +1127,25 @@ namespace mamba
void ProgressBarManager::sort_bars(bool max_height_exceeded)
{
if (!max_height_exceeded)
std::sort(m_progress_bars.begin(), m_progress_bars.end(), [](auto& a, auto& b) {
return a->prefix() > b->prefix();
});
std::sort(m_progress_bars.begin(),
m_progress_bars.end(),
[](auto& a, auto& b) { return a->prefix() > b->prefix(); });
else
std::sort(m_progress_bars.begin(), m_progress_bars.end(), [](auto& a, auto& b) {
if (!a->started() && b->started())
return false;
if (!b->started() && a->started())
return true;
if (a->status() == ChronoState::unset && b->status() != ChronoState::unset)
return true;
if (b->status() == ChronoState::unset && a->status() != ChronoState::unset)
return false;
return a->last_active_time() > b->last_active_time();
});
std::sort(
m_progress_bars.begin(),
m_progress_bars.end(),
[](auto& a, auto& b)
{
if (!a->started() && b->started())
return false;
if (!b->started() && a->started())
return true;
if (a->status() == ChronoState::unset && b->status() != ChronoState::unset)
return true;
if (b->status() == ChronoState::unset && a->status() != ChronoState::unset)
return false;
return a->last_active_time() > b->last_active_time();
});
}
/***************
@ -1393,7 +1400,8 @@ namespace mamba
if (delay.count())
{
std::thread t(
[&](const time_point_t& stop_time_point) {
[&](const time_point_t& stop_time_point)
{
std::lock_guard<std::mutex> lock(m_mutex);
while (now() < stop_time_point && status() < ChronoState::stopped)
std::this_thread::sleep_for(std::chrono::milliseconds(100));

View File

@ -147,7 +147,8 @@ namespace mamba
m_pool.get().create_whatprovides();
}
auto print_solvable = [](auto& pkg) {
auto print_solvable = [](auto& pkg)
{
std::string title = pkg->name + " " + pkg->version + " " + pkg->build_string;
std::cout << title << std::endl;
std::cout << std::string(title.size(), '-') << std::endl;
@ -210,13 +211,16 @@ namespace mamba
query_result::dependency_graph g;
Pool* pool = m_pool.get();
std::sort(solvables.elements, solvables.elements + solvables.count, [pool](Id a, Id b) {
Solvable* sa;
Solvable* sb;
sa = pool_id2solvable(pool, a);
sb = pool_id2solvable(pool, b);
return (pool_evrcmp(pool, sa->evr, sb->evr, EVRCMP_COMPARE) > 0);
});
std::sort(solvables.elements,
solvables.elements + solvables.count,
[pool](Id a, Id b)
{
Solvable* sa;
Solvable* sb;
sa = pool_id2solvable(pool, a);
sb = pool_id2solvable(pool, b);
return (pool_evrcmp(pool, sa->evr, sb->evr, EVRCMP_COMPARE) > 0);
});
for (int i = 0; i < solvables.count; i++)
{
@ -292,7 +296,8 @@ namespace mamba
int depth = tree ? -1 : 1;
auto find_latest = [&](Queue& solvables) -> Solvable* {
auto find_latest = [&](Queue& solvables) -> Solvable*
{
Solvable* latest = pool_id2solvable(m_pool.get(), solvables.elements[0]);
for (int i = 1; i < solvables.count; ++i)
{
@ -357,10 +362,14 @@ namespace mamba
if (!rhs.m_ordered_pkg_list.empty())
{
auto tmp(rhs.m_ordered_pkg_list);
std::for_each(tmp.begin(), tmp.end(), [offset_lbd](auto& entry) {
std::transform(
entry.second.begin(), entry.second.end(), entry.second.begin(), offset_lbd);
});
std::for_each(tmp.begin(),
tmp.end(),
[offset_lbd](auto& entry) {
std::transform(entry.second.begin(),
entry.second.end(),
entry.second.begin(),
offset_lbd);
});
swap(m_ordered_pkg_list, tmp);
}
}
@ -473,7 +482,8 @@ namespace mamba
}
}
auto format_row = [&](auto& pkg) {
auto format_row = [&](auto& pkg)
{
std::vector<mamba::printers::FormattedString> row;
for (std::size_t i = 0; i < cmds.size(); ++i)
{

View File

@ -644,7 +644,8 @@ namespace mamba
// just ask different possible installations of PowerShell where their
// profiles are.
auto find_powershell_paths = [&profile_var](const std::string& exe) -> std::string {
auto find_powershell_paths = [&profile_var](const std::string& exe) -> std::string
{
try
{
std::string out, err;

View File

@ -65,100 +65,102 @@ namespace mamba
{
namespace detail
{
nlohmann::json read_mod_and_etag(const fs::path& file)
{
// parse json at the beginning of the stream such as
// {"_url": "https://conda.anaconda.org/conda-forge/linux-64",
// "_etag": "W/\"6092e6a2b6cec6ea5aade4e177c3edda-8\"",
// "_mod": "Sat, 04 Apr 2020 03:29:49 GMT",
// "_cache_control": "public, max-age=1200"
nlohmann::json read_mod_and_etag(const fs::path& file)
{
// parse json at the beginning of the stream such as
// {"_url": "https://conda.anaconda.org/conda-forge/linux-64",
// "_etag": "W/\"6092e6a2b6cec6ea5aade4e177c3edda-8\"",
// "_mod": "Sat, 04 Apr 2020 03:29:49 GMT",
// "_cache_control": "public, max-age=1200"
auto extract_subjson = [](std::ifstream& s) -> std::string {
char next;
std::string result;
bool escaped = false;
int i = 0, N = 4;
std::size_t idx = 0;
std::size_t prev_keystart;
bool in_key = false;
std::string key = "";
while (s.get(next))
auto extract_subjson = [](std::ifstream& s) -> std::string
{
idx++;
if (next == '"')
char next;
std::string result;
bool escaped = false;
int i = 0, N = 4;
std::size_t idx = 0;
std::size_t prev_keystart;
bool in_key = false;
std::string key = "";
while (s.get(next))
{
if (!escaped)
idx++;
if (next == '"')
{
if ((i / 2) % 2 == 0)
if (!escaped)
{
in_key = !in_key;
if (in_key)
if ((i / 2) % 2 == 0)
{
prev_keystart = idx + 1;
}
else
{
if (key != "_mod" && key != "_etag" && key != "_cache_control" && key != "_url")
in_key = !in_key;
if (in_key)
{
// bail out
auto last_comma = result.find_last_of(",", prev_keystart - 2);
if (last_comma != std::string::npos && last_comma > 0)
{
result = result.substr(0, last_comma);
result.push_back('}');
return result;
}
else
{
return std::string();
}
prev_keystart = idx + 1;
}
else
{
if (key != "_mod" && key != "_etag" && key != "_cache_control"
&& key != "_url")
{
// bail out
auto last_comma
= result.find_last_of(",", prev_keystart - 2);
if (last_comma != std::string::npos && last_comma > 0)
{
result = result.substr(0, last_comma);
result.push_back('}');
return result;
}
else
{
return std::string();
}
}
key.clear();
}
key.clear();
}
i++;
}
// 4 keys == 4 ticks
if (i == 4 * N)
{
result += "\"}";
return result;
}
i++;
}
// 4 keys == 4 ticks
if (i == 4 * N)
if (in_key && next != '"')
{
result += "\"}";
return result;
key.push_back(next);
}
}
if (in_key && next != '"')
{
key.push_back(next);
escaped = (!escaped && next == '\\');
result.push_back(next);
}
return std::string();
};
escaped = (!escaped && next == '\\');
result.push_back(next);
std::ifstream in_file = open_ifstream(file);
auto json = extract_subjson(in_file);
nlohmann::json result;
try
{
result = nlohmann::json::parse(json);
return result;
}
catch (...)
{
LOG_WARNING << "Could not parse mod/etag header";
return nlohmann::json();
}
return std::string();
};
std::ifstream in_file = open_ifstream(file);
auto json = extract_subjson(in_file);
nlohmann::json result;
try
{
result = nlohmann::json::parse(json);
return result;
}
catch (...)
{
LOG_WARNING << "Could not parse mod/etag header";
return nlohmann::json();
}
}
}
MSubdirData::MSubdirData(const std::string& name,
const std::string& repodata_url,
const std::string& repodata_fn,
@ -293,9 +295,7 @@ namespace mamba
if (m_loaded)
{
Console::stream() << fmt::format("{:<50} {:>20}",
m_name,
std::string("Using cache"));
Console::stream() << fmt::format("{:<50} {:>20}", m_name, std::string("Using cache"));
}
else
{

View File

@ -166,7 +166,8 @@ namespace mamba
std::function<void(ProgressBarRepr&)> PackageDownloadExtractTarget::extract_repr()
{
return [&](ProgressBarRepr& r) -> void {
return [&](ProgressBarRepr& r) -> void
{
if (r.progress_bar().started())
r.postfix.set_value("Extracting");
else
@ -176,7 +177,8 @@ namespace mamba
std::function<void(ProgressProxy&)> PackageDownloadExtractTarget::extract_progress_callback()
{
return [&](ProgressProxy& bar) -> void {
return [&](ProgressProxy& bar) -> void
{
if (bar.started())
bar.set_progress(0, 1);
};
@ -590,7 +592,8 @@ namespace mamba
if (solver.only_deps == false)
{
auto to_string_vec = [](const std::vector<MatchSpec>& vec) -> std::vector<std::string> {
auto to_string_vec = [](const std::vector<MatchSpec>& vec) -> std::vector<std::string>
{
std::vector<std::string> res;
for (const auto& el : vec)
res.push_back(el.str());
@ -935,7 +938,8 @@ namespace mamba
to_unlink.push_back(solvable_to_json(s));
}
auto add_json = [](const auto& jlist, const char* s) {
auto add_json = [](const auto& jlist, const char* s)
{
if (!jlist.empty())
{
Console::instance().json_down(s);
@ -1021,62 +1025,67 @@ namespace mamba
auto* dl_bar = aggregated_pbar_manager.aggregated_bar("Download");
if (dl_bar)
dl_bar->set_repr_hook([&](ProgressBarRepr& repr) -> void {
auto active_tasks = dl_bar->active_tasks().size();
if (active_tasks == 0)
dl_bar->set_repr_hook(
[&](ProgressBarRepr& repr) -> void
{
repr.prefix.set_value(fmt::format("{:<16}", "Downloading"));
repr.postfix.set_value(fmt::format("{:<25}", ""));
}
else
{
repr.prefix.set_value(fmt::format(
"{:<11} {:>4}", "Downloading", fmt::format("({})", active_tasks)));
repr.postfix.set_value(fmt::format("{:<25}", dl_bar->last_active_task()));
}
repr.current.set_value(
fmt::format("{:>7}", to_human_readable_filesize(dl_bar->current(), 1)));
repr.separator.set_value("/");
auto active_tasks = dl_bar->active_tasks().size();
if (active_tasks == 0)
{
repr.prefix.set_value(fmt::format("{:<16}", "Downloading"));
repr.postfix.set_value(fmt::format("{:<25}", ""));
}
else
{
repr.prefix.set_value(fmt::format(
"{:<11} {:>4}", "Downloading", fmt::format("({})", active_tasks)));
repr.postfix.set_value(
fmt::format("{:<25}", dl_bar->last_active_task()));
}
repr.current.set_value(
fmt::format("{:>7}", to_human_readable_filesize(dl_bar->current(), 1)));
repr.separator.set_value("/");
std::string total_str;
if (dl_bar->total() == std::numeric_limits<std::size_t>::max())
total_str = "??.?MB";
else
total_str = to_human_readable_filesize(dl_bar->total(), 1);
repr.total.set_value(fmt::format("{:>7}", total_str));
std::string total_str;
if (dl_bar->total() == std::numeric_limits<std::size_t>::max())
total_str = "??.?MB";
else
total_str = to_human_readable_filesize(dl_bar->total(), 1);
repr.total.set_value(fmt::format("{:>7}", total_str));
auto speed = dl_bar->avg_speed(std::chrono::milliseconds(500));
repr.speed.set_value(
speed ? fmt::format("@ {:>7}/s", to_human_readable_filesize(speed, 1))
: "");
});
auto speed = dl_bar->avg_speed(std::chrono::milliseconds(500));
repr.speed.set_value(
speed ? fmt::format("@ {:>7}/s", to_human_readable_filesize(speed, 1))
: "");
});
auto* extract_bar = aggregated_pbar_manager.aggregated_bar("Extract");
if (extract_bar)
extract_bar->set_repr_hook([&](ProgressBarRepr& repr) -> void {
auto active_tasks = extract_bar->active_tasks().size();
if (active_tasks == 0)
extract_bar->set_repr_hook(
[&](ProgressBarRepr& repr) -> void
{
repr.prefix.set_value(fmt::format("{:<16}", "Extracting"));
repr.postfix.set_value(fmt::format("{:<25}", ""));
}
else
{
repr.prefix.set_value(fmt::format(
"{:<11} {:>4}", "Extracting", fmt::format("({})", active_tasks)));
repr.postfix.set_value(
fmt::format("{:<25}", extract_bar->last_active_task()));
}
repr.current.set_value(fmt::format("{:>3}", extract_bar->current()));
repr.separator.set_value("/");
auto active_tasks = extract_bar->active_tasks().size();
if (active_tasks == 0)
{
repr.prefix.set_value(fmt::format("{:<16}", "Extracting"));
repr.postfix.set_value(fmt::format("{:<25}", ""));
}
else
{
repr.prefix.set_value(fmt::format(
"{:<11} {:>4}", "Extracting", fmt::format("({})", active_tasks)));
repr.postfix.set_value(
fmt::format("{:<25}", extract_bar->last_active_task()));
}
repr.current.set_value(fmt::format("{:>3}", extract_bar->current()));
repr.separator.set_value("/");
std::string total_str;
if (extract_bar->total() == std::numeric_limits<std::size_t>::max())
total_str = "?";
else
total_str = std::to_string(extract_bar->total());
repr.total.set_value(fmt::format("{:>3}", total_str));
});
std::string total_str;
if (extract_bar->total() == std::numeric_limits<std::size_t>::max())
total_str = "?";
else
total_str = std::to_string(extract_bar->total());
repr.total.set_value(fmt::format("{:>3}", total_str));
});
pbar_manager.start();
pbar_manager.watch_print();
@ -1208,8 +1217,9 @@ namespace mamba
std::size_t total_size = 0;
auto* pool = m_transaction->pool;
auto format_row = [this, pool, &total_size](
rows& r, Solvable* s, printers::format flag, std::string diff) {
auto format_row =
[this, pool, &total_size](rows& r, Solvable* s, printers::format flag, std::string diff)
{
std::ptrdiff_t dlsize = solvable_lookup_num(s, SOLVABLE_DOWNLOADSIZE, -1);
printers::FormattedString dlsize_s;
if (dlsize != -1)

View File

@ -546,7 +546,8 @@ namespace mamba
}
else
{
auto quote_arg = [](const std::string& s) {
auto quote_arg = [](const std::string& s)
{
char quote_char;
if (s.find('"') != s.npos)
{
@ -1002,23 +1003,27 @@ namespace mamba
std::mutex m;
std::condition_variable cv;
thread t([&cv, &ret, &fd, &lock]() {
ret = fcntl(fd, F_SETLKW, &lock);
cv.notify_one();
});
thread t(
[&cv, &ret, &fd, &lock]()
{
ret = fcntl(fd, F_SETLKW, &lock);
cv.notify_one();
});
auto th = t.native_handle();
int err = 0;
set_signal_handler([&th, &cv, &ret, &err](sigset_t sigset) -> int {
int signum = 0;
sigwait(&sigset, &signum);
pthread_cancel(th);
err = EINTR;
ret = -1;
cv.notify_one();
return signum;
});
set_signal_handler(
[&th, &cv, &ret, &err](sigset_t sigset) -> int
{
int signum = 0;
sigwait(&sigset, &signum);
pthread_cancel(th);
err = EINTR;
ret = -1;
cv.notify_one();
return signum;
});
t.detach();

View File

@ -13,7 +13,8 @@ namespace mamba
static const auto aux_file_path = fs::absolute("history_test/parse/conda-meta/aux_file");
// Backup history file and restore it at the end of the test, whatever the output.
struct ScopedHistoryFileBackup {
struct ScopedHistoryFileBackup
{
ScopedHistoryFileBackup()
{
fs::remove(aux_file_path);
@ -46,7 +47,8 @@ namespace mamba
std::cout << check_buffer.str() << std::endl;
// Re-inject history into history file: history file should then have the same duplicate content as the buffer.
// Re-inject history into history file: history file should then have the same duplicate
// content as the buffer.
for (const auto& req : user_reqs)
{
history_instance.add_entry(req);
@ -61,18 +63,20 @@ namespace mamba
history_file.close();
ASSERT_EQ(updated_history_buffer.str(), check_buffer.str());
}
#ifndef _WIN32
TEST(history, parse_segfault)
{
pid_t child = fork();
if (child) {
if (child)
{
int wstatus;
waitpid(child, &wstatus, 0);
ASSERT_TRUE(WIFEXITED(wstatus));
} else {
}
else
{
History history_instance("history_test/parse_segfault");
history_instance.get_user_requests();
exit(0);

View File

@ -29,9 +29,7 @@ namespace mamba
public:
Configuration()
{
mamba::Configuration::instance()
.at("show_banner")
.set_default_value(false);
mamba::Configuration::instance().at("show_banner").set_default_value(false);
}
protected:
@ -46,9 +44,7 @@ namespace mamba
mamba::Configuration::instance()
.at("rc_files")
.set_value<std::vector<fs::path>>({ fs::path(unique_location) });
mamba::Configuration::instance()
.at("show_banner")
.set_default_value(false);
mamba::Configuration::instance().at("show_banner").set_default_value(false);
mamba::Configuration::instance().load();
}
@ -70,12 +66,8 @@ namespace mamba
}
mamba::Configuration::instance().reset_configurables();
mamba::Configuration::instance()
.at("rc_files")
.set_value(sources);
mamba::Configuration::instance()
.at("show_banner")
.set_default_value(false);
mamba::Configuration::instance().at("rc_files").set_value(sources);
mamba::Configuration::instance().at("show_banner").set_default_value(false);
mamba::Configuration::instance().load();
}

View File

@ -272,26 +272,26 @@ namespace mamba
}
INSTANTIATE_TEST_SUITE_P(output,
OutputPromptTests,
testing::Values(std::make_tuple("y", 'y', true),
std::make_tuple("yes", 'y', true),
std::make_tuple("Y", 'y', true),
std::make_tuple("Yes", 'y', true),
std::make_tuple("", 'y', true),
std::make_tuple("n", 'y', false),
std::make_tuple("no", 'y', false),
std::make_tuple("N", 'y', false),
std::make_tuple("No", 'y', false),
OutputPromptTests,
testing::Values(std::make_tuple("y", 'y', true),
std::make_tuple("yes", 'y', true),
std::make_tuple("Y", 'y', true),
std::make_tuple("Yes", 'y', true),
std::make_tuple("", 'y', true),
std::make_tuple("n", 'y', false),
std::make_tuple("no", 'y', false),
std::make_tuple("N", 'y', false),
std::make_tuple("No", 'y', false),
std::make_tuple("y", 'n', true),
std::make_tuple("yes", 'n', true),
std::make_tuple("Y", 'n', true),
std::make_tuple("Yes", 'n', true),
std::make_tuple("", 'n', false),
std::make_tuple("n", 'n', false),
std::make_tuple("no", 'n', false),
std::make_tuple("N", 'n', false),
std::make_tuple("No", 'n', false)));
std::make_tuple("y", 'n', true),
std::make_tuple("yes", 'n', true),
std::make_tuple("Y", 'n', true),
std::make_tuple("Yes", 'n', true),
std::make_tuple("", 'n', false),
std::make_tuple("n", 'n', false),
std::make_tuple("no", 'n', false),
std::make_tuple("N", 'n', false),
std::make_tuple("No", 'n', false)));
TEST(context, env_name)
{
@ -508,21 +508,29 @@ namespace mamba
fs::path cache_folder = fs::path("repodata_json_cache");
auto j = detail::read_mod_and_etag(cache_folder / "test_1.json");
EXPECT_EQ(j["_mod"], "Fri, 11 Feb 2022 13:52:44 GMT");
EXPECT_EQ(j["_url"], "file:///Users/wolfvollprecht/Programs/mamba/mamba/tests/channel_a/linux-64/repodata.json");
EXPECT_EQ(
j["_url"],
"file:///Users/wolfvollprecht/Programs/mamba/mamba/tests/channel_a/linux-64/repodata.json");
j = detail::read_mod_and_etag(cache_folder / "test_2.json");
EXPECT_EQ(j["_mod"], "Fri, 11 Feb 2022 13:52:44 GMT");
EXPECT_EQ(j["_url"], "file:///Users/wolfvollprecht/Programs/mamba/mamba/tests/channel_a/linux-64/repodata.json");
EXPECT_EQ(
j["_url"],
"file:///Users/wolfvollprecht/Programs/mamba/mamba/tests/channel_a/linux-64/repodata.json");
j = detail::read_mod_and_etag(cache_folder / "test_5.json");
EXPECT_EQ(j["_mod"], "Fri, 11 Feb 2022 13:52:44 GMT");
EXPECT_EQ(j["_url"], "file:///Users/wolfvollprecht/Programs/mamba/mamba/tests/channel_a/linux-64/repodata.json");
EXPECT_EQ(
j["_url"],
"file:///Users/wolfvollprecht/Programs/mamba/mamba/tests/channel_a/linux-64/repodata.json");
j = detail::read_mod_and_etag(cache_folder / "test_4.json");
EXPECT_EQ(j["_cache_control"], "{{}}\",,,\"");
EXPECT_EQ(j["_etag"], "\n\n\"\"randome ecx,,ssd\n,,\"");
EXPECT_EQ(j["_mod"], "Fri, 11 Feb 2022 13:52:44 GMT");
EXPECT_EQ(j["_url"], "file:///Users/wolfvollprecht/Programs/mamba/mamba/tests/channel_a/linux-64/repodata.json");
EXPECT_EQ(
j["_url"],
"file:///Users/wolfvollprecht/Programs/mamba/mamba/tests/channel_a/linux-64/repodata.json");
j = detail::read_mod_and_etag(cache_folder / "test_3.json");
EXPECT_TRUE(j.empty());
@ -532,6 +540,7 @@ namespace mamba
EXPECT_EQ(j["_url"], "https://conda.anaconda.org/intake/osx-arm64");
// EXPECT_EQ(j["_mod"], "Fri, 11 Feb 2022 13:52:44 GMT");
// EXPECT_EQ(j["_url"], "file:///Users/wolfvollprecht/Programs/mamba/mamba/tests/channel_a/linux-64/repodata.json");
// EXPECT_EQ(j["_url"],
// "file:///Users/wolfvollprecht/Programs/mamba/mamba/tests/channel_a/linux-64/repodata.json");
}
} // namespace mamba

View File

@ -19,26 +19,30 @@ namespace mamba
EXPECT_EQ(current_command, "mamba");
Console::instance().init_progress_bar_manager(ProgressBarMode::multi);
{
interruption_guard g([&res]() {
// Test for double free (segfault if that happens)
std::cout << "Interruption guard is interrupting" << std::endl;
Console::instance().init_progress_bar_manager(ProgressBarMode::multi);
interruption_guard g(
[&res]()
{
std::unique_lock<std::mutex> lk(res_mutex);
res -= 100;
}
reset_sig_interrupted();
});
// Test for double free (segfault if that happens)
std::cout << "Interruption guard is interrupting" << std::endl;
Console::instance().init_progress_bar_manager(ProgressBarMode::multi);
{
std::unique_lock<std::mutex> lk(res_mutex);
res -= 100;
}
reset_sig_interrupted();
});
for (size_t i = 0; i < 5; ++i)
{
mamba::thread t([&res]() {
mamba::thread t(
[&res]()
{
std::unique_lock<std::mutex> lk(res_mutex);
++res;
}
std::this_thread::sleep_for(std::chrono::milliseconds(300));
});
{
std::unique_lock<std::mutex> lk(res_mutex);
++res;
}
std::this_thread::sleep_for(std::chrono::milliseconds(300));
});
t.detach();
}
if (interrupt)

View File

@ -8,7 +8,8 @@ namespace mamba
{
TEST(local_random_generator, one_rng_per_thread_and_type)
{
auto same_thread_checks = []{
auto same_thread_checks = []
{
auto& a = local_random_generator();
auto& b = local_random_generator();
EXPECT_EQ(&a, &b);
@ -24,9 +25,7 @@ namespace mamba
void* pointer_to_this_thread_rng = same_thread_checks();
void* pointer_to_another_thread_rng = nullptr;
std::thread another_thread{[&]{
pointer_to_another_thread_rng = same_thread_checks();
}};
std::thread another_thread{ [&] { pointer_to_another_thread_rng = same_thread_checks(); } };
another_thread.join();
EXPECT_NE(pointer_to_this_thread_rng, pointer_to_another_thread_rng);
@ -37,7 +36,7 @@ namespace mamba
constexpr int arbitrary_min = -20;
constexpr int arbitrary_max = 20;
constexpr int attempts = 2000;
for(int i = 0; i < attempts; ++i)
for (int i = 0; i < attempts; ++i)
{
const int value = random_int(arbitrary_min, arbitrary_max);
EXPECT_GE(value, arbitrary_min);

View File

@ -43,18 +43,20 @@ main(int argc, char** argv)
CLI::App* lock_com = app.add_subcommand("lock", "Lock a path");
lock_com->add_option("path", path, "Path to lock");
lock_com->add_option("-t,--timeout", timeout, "Timeout in seconds");
lock_com->callback([&]() {
mamba::Context::instance().lock_timeout = timeout;
try
lock_com->callback(
[&]()
{
mamba::LockFile lock(path);
std::cout << 1;
}
catch (...)
{
std::cout << 0;
}
});
mamba::Context::instance().lock_timeout = timeout;
try
{
mamba::LockFile lock(path);
std::cout << 1;
}
catch (...)
{
std::cout << 0;
}
});
CLI::App* is_locked_com = app.add_subcommand("is-locked", "Check if a path is locked");
is_locked_com->add_option("path", path, "Path to check");

View File

@ -50,9 +50,9 @@ PYBIND11_MODULE(bindings, m)
py::class_<fs::path>(m, "Path")
.def(py::init<std::string>())
.def("__str__", [](fs::path& self) -> std::string { return self.string(); })
.def("__repr__", [](fs::path& self) -> std::string {
return std::string("fs::path[") + std::string(self) + "]";
});
.def("__repr__",
[](fs::path& self) -> std::string
{ return std::string("fs::path[") + std::string(self) + "]"; });
py::implicitly_convertible<std::string, fs::path>();
py::class_<mamba::LockFile>(m, "LockFile").def(py::init<fs::path>());
@ -132,7 +132,8 @@ PYBIND11_MODULE(bindings, m)
.def("find",
[](const Query& q,
const std::string& query,
const query::RESULT_FORMAT format) -> std::string {
const query::RESULT_FORMAT format) -> std::string
{
std::stringstream res_stream;
switch (format)
{
@ -151,7 +152,8 @@ PYBIND11_MODULE(bindings, m)
.def("whoneeds",
[](const Query& q,
const std::string& query,
const query::RESULT_FORMAT format) -> std::string {
const query::RESULT_FORMAT format) -> std::string
{
// QueryResult res = q.whoneeds(query, tree);
std::stringstream res_stream;
query_result res = q.whoneeds(query, (format == query::TREE));
@ -173,7 +175,8 @@ PYBIND11_MODULE(bindings, m)
.def("depends",
[](const Query& q,
const std::string& query,
const query::RESULT_FORMAT format) -> std::string {
const query::RESULT_FORMAT format) -> std::string
{
query_result res = q.depends(query, (format == query::TREE));
std::stringstream res_stream;
switch (format)
@ -296,7 +299,8 @@ PYBIND11_MODULE(bindings, m)
m.def("generate_ed25519_keypair", &validate::generate_ed25519_keypair_hex);
m.def(
"sign",
[](const std::string& data, const std::string& sk) {
[](const std::string& data, const std::string& sk)
{
std::string signature;
if (!validate::sign(data, sk, signature))
throw std::runtime_error("Signing failed");
@ -310,7 +314,8 @@ PYBIND11_MODULE(bindings, m)
.def_readwrite("scheme", &validate::Key::scheme)
.def_readwrite("keyval", &validate::Key::keyval)
.def_property_readonly("json_str",
[](const validate::Key& key) {
[](const validate::Key& key)
{
nlohmann::json j;
validate::to_json(j, key);
return j.dump();
@ -368,20 +373,18 @@ PYBIND11_MODULE(bindings, m)
.def(py::init<const std::string&>(), py::arg("json_str"))
.def(
"update",
[](validate::v06::RootImpl& role, const std::string& json_str) {
return role.update(nlohmann::json::parse(json_str));
},
[](validate::v06::RootImpl& role, const std::string& json_str)
{ return role.update(nlohmann::json::parse(json_str)); },
py::arg("json_str"))
.def(
"create_key_mgr",
[](validate::v06::RootImpl& role, const std::string& json_str) {
return role.create_key_mgr(nlohmann::json::parse(json_str));
},
[](validate::v06::RootImpl& role, const std::string& json_str)
{ return role.create_key_mgr(nlohmann::json::parse(json_str)); },
py::arg("json_str"));
py::class_<Channel, std::unique_ptr<Channel, py::nodelete>>(m, "Channel")
.def(py::init(
[](const std::string& value) { return const_cast<Channel*>(&make_channel(value)); }))
.def(py::init([](const std::string& value)
{ return const_cast<Channel*>(&make_channel(value)); }))
.def_property_readonly("scheme", &Channel::scheme)
.def_property_readonly("location", &Channel::location)
.def_property_readonly("name", &Channel::name)
@ -396,33 +399,34 @@ PYBIND11_MODULE(bindings, m)
&Channel::platform_url,
py::arg("platform"),
py::arg("with_credentials") = true)
.def("__repr__", [](const Channel& c) {
auto s = c.name();
s += "[";
bool first = true;
for (const auto& platform : c.platforms())
{
if (!first)
s += ",";
s += platform;
first = false;
}
s += "]";
return s;
});
.def("__repr__",
[](const Channel& c)
{
auto s = c.name();
s += "[";
bool first = true;
for (const auto& platform : c.platforms())
{
if (!first)
s += ",";
s += platform;
first = false;
}
s += "]";
return s;
});
m.def("clean", &clean);
py::class_<Configuration, std::unique_ptr<Configuration, py::nodelete>>(m, "Configuration")
.def(py::init([]() {
return std::unique_ptr<Configuration, py::nodelete>(&Configuration::instance());
}))
.def(py::init(
[]()
{ return std::unique_ptr<Configuration, py::nodelete>(&Configuration::instance()); }))
.def_property(
"show_banner",
[]() -> bool { return Configuration::instance().at("show_banner").value<bool>(); },
[](py::object&, bool val) {
Configuration::instance().at("show_banner").set_value(val);
});
[](py::object&, bool val)
{ Configuration::instance().at("show_banner").set_value(val); });
m.def("get_channels", &get_channels);

View File

@ -20,11 +20,13 @@ set_package_command(CLI::App* com)
auto extract_subcom = com->add_subcommand("extract");
extract_subcom->add_option("archive", infile, "Archive to extract");
extract_subcom->add_option("dest", dest, "Destination folder");
extract_subcom->callback([&]() {
std::cout << "Extracting " << fs::absolute(infile) << " to " << fs::absolute(dest)
<< std::endl;
extract(fs::absolute(infile), fs::absolute(dest));
});
extract_subcom->callback(
[&]()
{
std::cout << "Extracting " << fs::absolute(infile) << " to " << fs::absolute(dest)
<< std::endl;
extract(fs::absolute(infile), fs::absolute(dest));
});
auto compress_subcom = com->add_subcommand("compress");
compress_subcom->add_option("folder", infile, "Folder to compress");
@ -33,16 +35,18 @@ set_package_command(CLI::App* com)
"-c,--compression-level",
compression_level,
"Compression level from 0-9 (tar.bz2, default is 9), and 1-22 (conda, default is 15)");
compress_subcom->callback([&]() {
std::cout << "Compressing " << fs::absolute(infile) << " to " << dest << std::endl;
compress_subcom->callback(
[&]()
{
std::cout << "Compressing " << fs::absolute(infile) << " to " << dest << std::endl;
if (ends_with(dest, ".tar.bz2") && compression_level == -1)
compression_level = 9;
if (ends_with(dest, ".conda") && compression_level == -1)
compression_level = 15;
if (ends_with(dest, ".tar.bz2") && compression_level == -1)
compression_level = 9;
if (ends_with(dest, ".conda") && compression_level == -1)
compression_level = 15;
create_package(fs::absolute(infile), fs::absolute(dest), compression_level);
});
create_package(fs::absolute(infile), fs::absolute(dest), compression_level);
});
auto transmute_subcom = com->add_subcommand("transmute");
transmute_subcom->add_option("infile", infile, "Folder to compress");
@ -50,20 +54,22 @@ set_package_command(CLI::App* com)
"-c,--compression-level",
compression_level,
"Compression level from 0-9 (tar.bz2, default is 9), and 1-22 (conda, default is 15)");
transmute_subcom->callback([&]() {
if (ends_with(infile, ".tar.bz2"))
transmute_subcom->callback(
[&]()
{
if (compression_level == -1)
compression_level = 15;
dest = infile.substr(0, infile.size() - 8) + ".conda";
}
else
{
if (compression_level == -1)
compression_level = 9;
dest = infile.substr(0, infile.size() - 8) + ".tar.bz2";
}
std::cout << "Transmuting " << fs::absolute(infile) << " to " << dest << std::endl;
transmute(fs::absolute(infile), fs::absolute(dest), compression_level);
});
if (ends_with(infile, ".tar.bz2"))
{
if (compression_level == -1)
compression_level = 15;
dest = infile.substr(0, infile.size() - 8) + ".conda";
}
else
{
if (compression_level == -1)
compression_level = 9;
dest = infile.substr(0, infile.size() - 8) + ".tar.bz2";
}
std::cout << "Transmuting " << fs::absolute(infile) << " to " << dest << std::endl;
transmute(fs::absolute(infile), fs::absolute(dest), compression_level);
});
}

View File

@ -24,43 +24,46 @@ set_activate_command(CLI::App* subcom)
stack,
"Activate the specified environment without first deactivating the current one");
subcom->callback([&]() {
std::string guessed_shell = guess_shell();
std::string shell_hook_command = "", shell_hook = "";
if (guessed_shell == "powershell")
shell_hook_command
= "micromamba.exe shell hook -s powershell | Out-String | Invoke-Expression";
else
shell_hook_command = "eval \"$(micromamba shell hook --shell=" + guessed_shell + ")\"";
if (guessed_shell != "cmd.exe")
subcom->callback(
[&]()
{
shell_hook = unindent((R"(
std::string guessed_shell = guess_shell();
std::string shell_hook_command = "", shell_hook = "";
if (guessed_shell == "powershell")
shell_hook_command
= "micromamba.exe shell hook -s powershell | Out-String | Invoke-Expression";
else
shell_hook_command
= "eval \"$(micromamba shell hook --shell=" + guessed_shell + ")\"";
if (guessed_shell != "cmd.exe")
{
shell_hook = unindent((R"(
To initialize the current )"
+ guessed_shell + R"( shell, run:
+ guessed_shell + R"( shell, run:
$ )" + shell_hook_command
+ R"(
+ R"(
and then activate or deactivate with:
$ micromamba activate
)")
.c_str());
}
.c_str());
}
std::string message = unindent((R"(
std::string message = unindent((R"(
'micromamba' is running as a subprocess and can't modify the parent shell.
Thus you must initialize your shell before using activate and deactivate.
)" + shell_hook + R"(
To automatically initialize all future ()"
+ guessed_shell + R"() shells, run:
+ guessed_shell + R"() shells, run:
$ micromamba shell init --shell=)"
+ guessed_shell + R"( --prefix=~/micromamba
+ guessed_shell + R"( --prefix=~/micromamba
Supported shells are {bash, zsh, xonsh, cmd.exe, powershell, fish}.)")
.c_str());
.c_str());
std::cout << "\n" << message << "\n" << std::endl;
throw std::runtime_error("Shell not initialized");
});
std::cout << "\n" << message << "\n" << std::endl;
throw std::runtime_error("Shell not initialized");
});
}

View File

@ -40,19 +40,23 @@ init_clean_parser(CLI::App* subcom)
.group("cli")
.description("Remove *.mamba_trash files from all environments"));
auto& clean_force_pkgs_dirs
= config.insert(Configurable("clean_force_pkgs_dirs", false)
.group("cli")
.description("Remove *all* writable package caches. This option is not included with the --all flags."));
auto& clean_force_pkgs_dirs = config.insert(
Configurable("clean_force_pkgs_dirs", false)
.group("cli")
.description(
"Remove *all* writable package caches. This option is not included with the --all flags."));
subcom->add_flag("-a,--all", clean_all.get_cli_config<bool>(), clean_all.description());
subcom->add_flag("-i,--index-cache", clean_index.get_cli_config<bool>(), clean_index.description());
subcom->add_flag(
"-i,--index-cache", clean_index.get_cli_config<bool>(), clean_index.description());
subcom->add_flag("-p,--packages", clean_pkgs.get_cli_config<bool>(), clean_pkgs.description());
subcom->add_flag(
"-t,--tarballs", clean_tarballs.get_cli_config<bool>(), clean_tarballs.description());
subcom->add_flag("-l,--locks", clean_locks.get_cli_config<bool>(), clean_locks.description());
subcom->add_flag("--trash", clean_trash.get_cli_config<bool>(), clean_trash.description());
subcom->add_flag("-f,--force-pkgs-dirs", clean_force_pkgs_dirs.get_cli_config<bool>(), clean_force_pkgs_dirs.description());
subcom->add_flag("-f,--force-pkgs-dirs",
clean_force_pkgs_dirs.get_cli_config<bool>(),
clean_force_pkgs_dirs.description());
}
void
@ -60,30 +64,32 @@ set_clean_command(CLI::App* subcom)
{
init_clean_parser(subcom);
subcom->callback([&]() {
auto& config = Configuration::instance();
int options = 0;
if (config.at("clean_all").compute().value<bool>())
options = options | MAMBA_CLEAN_ALL;
if (config.at("clean_index_cache").compute().value<bool>())
options = options | MAMBA_CLEAN_INDEX;
if (config.at("clean_packages").compute().value<bool>())
options = options | MAMBA_CLEAN_PKGS;
if (config.at("clean_tarballs").compute().value<bool>())
options = options | MAMBA_CLEAN_TARBALLS;
if (config.at("clean_locks").compute().value<bool>())
options = options | MAMBA_CLEAN_LOCKS;
if (config.at("clean_trash").compute().value<bool>())
options = options | MAMBA_CLEAN_TRASH;
if (config.at("clean_force_pkgs_dirs").compute().value<bool>())
subcom->callback(
[&]()
{
if (Console::prompt("Remove all contents from the package caches?"))
{
options = options | MAMBA_CLEAN_FORCE_PKGS_DIRS;
}
}
auto& config = Configuration::instance();
int options = 0;
clean(options);
});
if (config.at("clean_all").compute().value<bool>())
options = options | MAMBA_CLEAN_ALL;
if (config.at("clean_index_cache").compute().value<bool>())
options = options | MAMBA_CLEAN_INDEX;
if (config.at("clean_packages").compute().value<bool>())
options = options | MAMBA_CLEAN_PKGS;
if (config.at("clean_tarballs").compute().value<bool>())
options = options | MAMBA_CLEAN_TARBALLS;
if (config.at("clean_locks").compute().value<bool>())
options = options | MAMBA_CLEAN_LOCKS;
if (config.at("clean_trash").compute().value<bool>())
options = options | MAMBA_CLEAN_TRASH;
if (config.at("clean_force_pkgs_dirs").compute().value<bool>())
{
if (Console::prompt("Remove all contents from the package caches?"))
{
options = options | MAMBA_CLEAN_FORCE_PKGS_DIRS;
}
}
clean(options);
});
}

View File

@ -18,14 +18,18 @@ init_rc_options(CLI::App* subcom)
std::string cli_group = "Configuration options";
auto& rc_files = config.at("rc_files");
subcom->add_option("--rc-file", rc_files.get_cli_config<std::vector<fs::path>>(), rc_files.description())
subcom
->add_option(
"--rc-file", rc_files.get_cli_config<std::vector<fs::path>>(), rc_files.description())
->group(cli_group);
auto& no_rc = config.at("no_rc");
subcom->add_flag("--no-rc", no_rc.get_cli_config<bool>(), no_rc.description())->group(cli_group);
subcom->add_flag("--no-rc", no_rc.get_cli_config<bool>(), no_rc.description())
->group(cli_group);
auto& no_env = config.at("no_env");
subcom->add_flag("--no-env", no_env.get_cli_config<bool>(), no_env.description())->group(cli_group);
subcom->add_flag("--no-env", no_env.get_cli_config<bool>(), no_env.description())
->group(cli_group);
}
@ -44,22 +48,25 @@ init_general_options(CLI::App* subcom)
"Set verbosity (higher verbosity with multiple -v, e.g. -vvv)")
->group(cli_group);
std::map<std::string, spdlog::level::level_enum> le_map = {
{"critical", spdlog::level::critical},
{"error", spdlog::level::err},
{"warning", spdlog::level::warn},
{"info", spdlog::level::info},
{"debug", spdlog::level::debug},
{"trace", spdlog::level::trace},
{"off", spdlog::level::off}
};
std::map<std::string, spdlog::level::level_enum> le_map
= { { "critical", spdlog::level::critical },
{ "error", spdlog::level::err },
{ "warning", spdlog::level::warn },
{ "info", spdlog::level::info },
{ "debug", spdlog::level::debug },
{ "trace", spdlog::level::trace },
{ "off", spdlog::level::off } };
auto& log_level = config.at("log_level");
subcom->add_option("--log-level", log_level.get_cli_config<spdlog::level::level_enum>(), log_level.description())
subcom
->add_option("--log-level",
log_level.get_cli_config<spdlog::level::level_enum>(),
log_level.description())
->group(cli_group)
->transform(CLI::CheckedTransformer(le_map, CLI::ignore_case));
auto& quiet = config.at("quiet");
subcom->add_flag("-q,--quiet", quiet.get_cli_config<bool>(), quiet.description())->group(cli_group);
subcom->add_flag("-q,--quiet", quiet.get_cli_config<bool>(), quiet.description())
->group(cli_group);
auto& always_yes = config.at("always_yes");
subcom->add_flag("-y,--yes", always_yes.get_cli_config<bool>(), always_yes.description())
@ -77,7 +84,9 @@ init_general_options(CLI::App* subcom)
->group(cli_group);
auto& experimental = config.at("experimental");
subcom->add_flag("--experimental", experimental.get_cli_config<bool>(), experimental.description())
subcom
->add_flag(
"--experimental", experimental.get_cli_config<bool>(), experimental.description())
->group(cli_group);
auto& debug = config.at("debug");
@ -90,7 +99,8 @@ init_general_options(CLI::App* subcom)
->group("");
auto& print_config_only = config.at("print_config_only");
subcom->add_flag("--print-config-only", print_config_only.get_cli_config<bool>(), "Debug config")
subcom
->add_flag("--print-config-only", print_config_only.get_cli_config<bool>(), "Debug config")
->group("");
}
@ -109,7 +119,8 @@ init_prefix_options(CLI::App* subcom)
->group(cli_group);
auto& name = config.at("env_name");
subcom->add_option("-n,--name", name.get_cli_config<std::string>(), name.description())->group(cli_group);
subcom->add_option("-n,--name", name.get_cli_config<std::string>(), name.description())
->group(cli_group);
}
@ -120,16 +131,21 @@ init_network_options(CLI::App* subcom)
std::string cli_group = "Network options";
auto& ssl_verify = config.at("ssl_verify");
subcom->add_option("--ssl-verify", ssl_verify.get_cli_config<std::string>(), ssl_verify.description())
subcom
->add_option(
"--ssl-verify", ssl_verify.get_cli_config<std::string>(), ssl_verify.description())
->group(cli_group);
auto& ssl_no_revoke = config.at("ssl_no_revoke");
subcom
->add_flag("--ssl-no-revoke", ssl_no_revoke.get_cli_config<bool>(), ssl_no_revoke.description())
->add_flag(
"--ssl-no-revoke", ssl_no_revoke.get_cli_config<bool>(), ssl_no_revoke.description())
->group(cli_group);
auto& cacert_path = config.at("cacert_path");
subcom->add_option("--cacert-path", cacert_path.get_cli_config<std::string>(), cacert_path.description())
subcom
->add_option(
"--cacert-path", cacert_path.get_cli_config<std::string>(), cacert_path.description())
->group(cli_group);
auto& local_repodata_ttl = config.at("local_repodata_ttl");
@ -156,7 +172,8 @@ init_channel_parser(CLI::App* subcom)
auto& channels = config.at("channels");
channels.set_post_merge_hook(channels_hook).needs({ "override_channels" });
subcom->add_option("-c,--channel", channels.get_cli_config<string_list>(), channels.description())
subcom
->add_option("-c,--channel", channels.get_cli_config<string_list>(), channels.description())
->type_size(1)
->allow_extra_args(false);
@ -171,11 +188,9 @@ init_channel_parser(CLI::App* subcom)
override_channels.get_cli_config<bool>(),
override_channels.description());
std::map<std::string, ChannelPriority> cp_map = {
{"disabled", ChannelPriority::kDisabled},
{"flexible", ChannelPriority::kFlexible},
{"strict", ChannelPriority::kStrict}
};
std::map<std::string, ChannelPriority> cp_map = { { "disabled", ChannelPriority::kDisabled },
{ "flexible", ChannelPriority::kFlexible },
{ "strict", ChannelPriority::kStrict } };
auto& channel_priority = config.at("channel_priority");
subcom
->add_option("--channel-priority",
@ -184,8 +199,9 @@ init_channel_parser(CLI::App* subcom)
->transform(CLI::CheckedTransformer(cp_map, CLI::ignore_case));
auto& channel_alias = config.at("channel_alias");
subcom->add_option(
"--channel-alias", channel_alias.get_cli_config<std::string>(), channel_alias.description());
subcom->add_option("--channel-alias",
channel_alias.get_cli_config<std::string>(),
channel_alias.description());
auto& strict_channel_priority
= config.insert(Configurable("strict_channel_priority", false)
@ -313,10 +329,13 @@ init_install_options(CLI::App* subcom)
auto& config = Configuration::instance();
auto& specs = config.at("specs");
subcom->add_option("specs", specs.get_cli_config<string_list>(), "Specs to install into the environment");
subcom->add_option(
"specs", specs.get_cli_config<string_list>(), "Specs to install into the environment");
auto& file_specs = config.at("file_specs");
subcom->add_option("-f,--file", file_specs.get_cli_config<string_list>(), file_specs.description())
subcom
->add_option(
"-f,--file", file_specs.get_cli_config<string_list>(), file_specs.description())
->type_size(1)
->allow_extra_args(false);
@ -324,10 +343,12 @@ init_install_options(CLI::App* subcom)
subcom->add_flag("--no-pin,!--pin", no_pin.get_cli_config<bool>(), no_pin.description());
auto& no_py_pin = config.at("no_py_pin");
subcom->add_flag("--no-py-pin,!--py-pin", no_py_pin.get_cli_config<bool>(), no_py_pin.description());
subcom->add_flag(
"--no-py-pin,!--py-pin", no_py_pin.get_cli_config<bool>(), no_py_pin.description());
auto& compile_pyc = config.at("compile_pyc");
subcom->add_flag("--pyc,!--no-pyc", compile_pyc.get_cli_config<bool>(), compile_pyc.description());
subcom->add_flag(
"--pyc,!--no-pyc", compile_pyc.get_cli_config<bool>(), compile_pyc.description());
auto& allow_uninstall = config.at("allow_uninstall");
subcom->add_flag("--allow-uninstall,!--no-allow-uninstall",
@ -367,20 +388,21 @@ init_install_options(CLI::App* subcom)
subcom->add_flag(
"--shortcuts,!--no-shortcuts", shortcuts.get_cli_config<bool>(), shortcuts.description());
std::map<std::string, VerificationLevel> vl_map = {
{"enabled", VerificationLevel::kEnabled},
{"warn", VerificationLevel::kWarn},
{"disabled", VerificationLevel::kDisabled}
};
std::map<std::string, VerificationLevel> vl_map
= { { "enabled", VerificationLevel::kEnabled },
{ "warn", VerificationLevel::kWarn },
{ "disabled", VerificationLevel::kDisabled } };
auto& safety_checks = config.at("safety_checks");
subcom
->add_option(
"--safety-checks", safety_checks.get_cli_config<VerificationLevel>(), safety_checks.description())
->add_option("--safety-checks",
safety_checks.get_cli_config<VerificationLevel>(),
safety_checks.description())
->transform(CLI::CheckedTransformer(vl_map, CLI::ignore_case));
auto& av = config.at("verify_artifacts");
subcom->add_flag("--verify-artifacts", av.get_cli_config<bool>(), av.description());
auto& platform = config.at("platform");
subcom->add_option("--platform", platform.get_cli_config<std::string>(), platform.description());
subcom->add_option(
"--platform", platform.get_cli_config<std::string>(), platform.description());
}

View File

@ -74,8 +74,8 @@ overwrite_callbacks(std::vector<CLI::App*>& apps,
bool& completed)
{
auto* app = apps.back();
app->callback(
[app, &completer_args, &completed]() { complete_options(app, completer_args, completed); });
app->callback([app, &completer_args, &completed]()
{ complete_options(app, completer_args, completed); });
for (auto* subc : app->get_subcommands(nullptr))
{
apps.push_back(subc);
@ -91,13 +91,15 @@ add_activate_completion(CLI::App* app, std::vector<std::string>& completer_args,
CLI::App* activate_subcom
= app->add_subcommand("activate", "Mock activate shell function for completion");
activate_subcom->callback([app, &completer_args, &completed]() {
if (completer_args.size() == 1)
activate_subcom->callback(
[app, &completer_args, &completed]()
{
completer_args = { "-n", completer_args.back() };
complete_options(app, completer_args, completed);
}
});
if (completer_args.size() == 1)
{
completer_args = { "-n", completer_args.back() };
complete_options(app, completer_args, completed);
}
});
}
void

View File

@ -101,7 +101,8 @@ init_config_describe_options(CLI::App* subcom)
auto& config = Configuration::instance();
auto& specs = config.at("specs");
subcom->add_option("configs", specs.get_cli_config<std::vector<std::string>>(), "Configuration keys");
subcom->add_option(
"configs", specs.get_cli_config<std::vector<std::string>>(), "Configuration keys");
auto& show_long_descriptions = config.at("show_config_long_descriptions");
subcom->add_flag("-l,--long-descriptions",
@ -121,14 +122,16 @@ init_config_list_options(CLI::App* subcom)
auto& config = Configuration::instance();
auto& show_sources = config.at("show_config_sources");
subcom->add_flag("-s,--sources", show_sources.get_cli_config<bool>(), show_sources.description());
subcom->add_flag(
"-s,--sources", show_sources.get_cli_config<bool>(), show_sources.description());
auto& show_all = config.at("show_all_rc_configs");
subcom->add_flag("-a,--all", show_all.get_cli_config<bool>(), show_all.description());
auto& show_descriptions = config.at("show_config_descriptions");
subcom->add_flag(
"-d,--descriptions", show_descriptions.get_cli_config<bool>(), show_descriptions.description());
subcom->add_flag("-d,--descriptions",
show_descriptions.get_cli_config<bool>(),
show_descriptions.description());
}
void
@ -136,10 +139,12 @@ set_config_list_command(CLI::App* subcom)
{
init_config_list_options(subcom);
subcom->callback([&]() {
config_list();
return 0;
});
subcom->callback(
[&]()
{
config_list();
return 0;
});
}
void
@ -147,10 +152,12 @@ set_config_sources_command(CLI::App* subcom)
{
init_config_options(subcom);
subcom->callback([&]() {
config_sources();
return 0;
});
subcom->callback(
[&]()
{
config_sources();
return 0;
});
}
void
@ -158,10 +165,12 @@ set_config_describe_command(CLI::App* subcom)
{
init_config_describe_options(subcom);
subcom->callback([&]() {
config_describe();
return 0;
});
subcom->callback(
[&]()
{
config_describe();
return 0;
});
}
void
@ -173,15 +182,16 @@ set_config_path_command(CLI::App* subcom)
.group("cli")
.description("Set configuration on system's rc file"),
true);
auto* system_flag
= subcom->add_flag("--system", system_path.get_cli_config<bool>(), system_path.description());
auto* system_flag = subcom->add_flag(
"--system", system_path.get_cli_config<bool>(), system_path.description());
auto& env_path = config.insert(Configurable("config_set_env_path", false)
.group("cli")
.description("Set configuration on env's rc file"),
true);
auto* env_flag = subcom->add_flag("--env", env_path.get_cli_config<bool>(), env_path.description())
->excludes(system_flag);
auto* env_flag
= subcom->add_flag("--env", env_path.get_cli_config<bool>(), env_path.description())
->excludes(system_flag);
auto& file_path = config.insert(Configurable("config_set_file_path", fs::path())
.group("cli")
@ -206,12 +216,14 @@ set_config_sequence_command(CLI::App* subcom)
using config_set_sequence_type = std::vector<std::pair<std::string, std::string>>;
auto& config = Configuration::instance();
auto& specs = config.insert(Configurable("config_set_sequence_spec",
config_set_sequence_type({}))
.group("Output, Prompt and Flow Control")
.description("Add value to a configurable sequence"),
true);
subcom->add_option("specs", specs.get_cli_config<config_set_sequence_type>(), specs.description())->required();
auto& specs
= config.insert(Configurable("config_set_sequence_spec", config_set_sequence_type({}))
.group("Output, Prompt and Flow Control")
.description("Add value to a configurable sequence"),
true);
subcom
->add_option("specs", specs.get_cli_config<config_set_sequence_type>(), specs.description())
->required();
}
void
@ -312,45 +324,49 @@ set_config_remove_key_command(CLI::App* subcom)
auto& remove_key = config.insert(Configurable("remove_key", std::string(""))
.group("Output, Prompt and Flow Control")
.description("Remove a configuration key and its values"));
subcom->add_option("remove_key", remove_key.get_cli_config<std::string>(), remove_key.description());
subcom->add_option(
"remove_key", remove_key.get_cli_config<std::string>(), remove_key.description());
subcom->callback([&]() {
config.at("use_target_prefix_fallback").set_value(true);
config.at("show_banner").set_value(false);
config.at("target_prefix_checks")
.set_value(MAMBA_ALLOW_EXISTING_PREFIX | MAMBA_ALLOW_MISSING_PREFIX
| MAMBA_ALLOW_NOT_ENV_PREFIX | MAMBA_NOT_EXPECT_EXISTING_PREFIX);
config.load();
fs::path rc_source = compute_config_path(false);
bool key_removed = false;
// convert rc file to YAML::Node
YAML::Node rc_YAML = YAML::LoadFile(rc_source);
// look for key to remove in file
for (auto v : rc_YAML)
subcom->callback(
[&]()
{
const std::string& rk = remove_key.value<std::string>();
if (v.first.as<std::string>() == rk)
config.at("use_target_prefix_fallback").set_value(true);
config.at("show_banner").set_value(false);
config.at("target_prefix_checks")
.set_value(MAMBA_ALLOW_EXISTING_PREFIX | MAMBA_ALLOW_MISSING_PREFIX
| MAMBA_ALLOW_NOT_ENV_PREFIX | MAMBA_NOT_EXPECT_EXISTING_PREFIX);
config.load();
fs::path rc_source = compute_config_path(false);
bool key_removed = false;
// convert rc file to YAML::Node
YAML::Node rc_YAML = YAML::LoadFile(rc_source);
// look for key to remove in file
for (auto v : rc_YAML)
{
rc_YAML.remove(rk);
key_removed = true;
break;
const std::string& rk = remove_key.value<std::string>();
if (v.first.as<std::string>() == rk)
{
rc_YAML.remove(rk);
key_removed = true;
break;
}
}
}
if (!key_removed)
{
std::cout << "Key is not present in file" << std::endl;
}
if (!key_removed)
{
std::cout << "Key is not present in file" << std::endl;
}
// if the rc file is being modified, it's necessary to rewrite it
std::ofstream rc_file = open_ofstream(rc_source, std::ofstream::in | std::ofstream::trunc);
rc_file << rc_YAML << std::endl;
// if the rc file is being modified, it's necessary to rewrite it
std::ofstream rc_file
= open_ofstream(rc_source, std::ofstream::in | std::ofstream::trunc);
rc_file << rc_YAML << std::endl;
config.operation_teardown();
});
config.operation_teardown();
});
}
void
@ -370,65 +386,69 @@ set_config_remove_command(CLI::App* subcom)
subcom->add_option(
"remove", remove_vec_map.get_cli_config<string_list>(), remove_vec_map.description());
subcom->callback([&]() {
config.at("use_target_prefix_fallback").set_value(true);
config.at("show_banner").set_value(false);
config.at("target_prefix_checks")
.set_value(MAMBA_ALLOW_EXISTING_PREFIX | MAMBA_ALLOW_MISSING_PREFIX
| MAMBA_ALLOW_NOT_ENV_PREFIX | MAMBA_NOT_EXPECT_EXISTING_PREFIX);
config.load();
fs::path rc_source = compute_config_path(false);
bool key_removed = false;
const string_list& rvm = remove_vec_map.value<string_list>();
std::string remove_vec_key = rvm.front();
std::string remove_vec_value = rvm.at(1);
if (rvm.size() > 2)
subcom->callback(
[&]()
{
std::cout << "Only one value can be removed at a time" << std::endl;
return;
}
config.at("use_target_prefix_fallback").set_value(true);
config.at("show_banner").set_value(false);
config.at("target_prefix_checks")
.set_value(MAMBA_ALLOW_EXISTING_PREFIX | MAMBA_ALLOW_MISSING_PREFIX
| MAMBA_ALLOW_NOT_ENV_PREFIX | MAMBA_NOT_EXPECT_EXISTING_PREFIX);
config.load();
// convert rc file to YAML::Node
YAML::Node rc_YAML = YAML::LoadFile(rc_source);
fs::path rc_source = compute_config_path(false);
bool key_removed = false;
// look for key to remove in file
for (auto v : rc_YAML)
{
if (v.first.as<std::string>() == remove_vec_key)
const string_list& rvm = remove_vec_map.value<string_list>();
std::string remove_vec_key = rvm.front();
std::string remove_vec_value = rvm.at(1);
if (rvm.size() > 2)
{
for (std::size_t i = 0; i < v.second.size(); ++i)
{
if (v.second.size() == 1 && v.second[i].as<std::string>() == remove_vec_value)
{
rc_YAML.remove(remove_vec_key);
key_removed = true;
break;
}
else if (v.second[i].as<std::string>() == remove_vec_value)
{
rc_YAML[remove_vec_key].remove(i);
key_removed = true;
break;
}
}
break;
std::cout << "Only one value can be removed at a time" << std::endl;
return;
}
}
if (!key_removed)
{
std::cout << "Key is not present in file" << std::endl;
}
// convert rc file to YAML::Node
YAML::Node rc_YAML = YAML::LoadFile(rc_source);
// if the rc file is being modified, it's necessary to rewrite it
std::ofstream rc_file = open_ofstream(rc_source, std::ofstream::in | std::ofstream::trunc);
rc_file << rc_YAML << std::endl;
// look for key to remove in file
for (auto v : rc_YAML)
{
if (v.first.as<std::string>() == remove_vec_key)
{
for (std::size_t i = 0; i < v.second.size(); ++i)
{
if (v.second.size() == 1
&& v.second[i].as<std::string>() == remove_vec_value)
{
rc_YAML.remove(remove_vec_key);
key_removed = true;
break;
}
else if (v.second[i].as<std::string>() == remove_vec_value)
{
rc_YAML[remove_vec_key].remove(i);
key_removed = true;
break;
}
}
break;
}
}
config.operation_teardown();
});
if (!key_removed)
{
std::cout << "Key is not present in file" << std::endl;
}
// if the rc file is being modified, it's necessary to rewrite it
std::ofstream rc_file
= open_ofstream(rc_source, std::ofstream::in | std::ofstream::trunc);
rc_file << rc_YAML << std::endl;
config.operation_teardown();
});
}
void
@ -442,37 +462,41 @@ set_config_set_command(CLI::App* subcom)
auto& set_value = config.insert(Configurable("set_value", std::vector<std::string>({}))
.group("Output, Prompt and Flow Control")
.description("Set configuration value on rc file"));
subcom->add_option("set_value", set_value.get_cli_config<string_list>(), set_value.description());
subcom->add_option(
"set_value", set_value.get_cli_config<string_list>(), set_value.description());
subcom->callback([&]() {
config.at("use_target_prefix_fallback").set_value(true);
config.at("show_banner").set_value(false);
config.at("target_prefix_checks")
.set_value(MAMBA_ALLOW_EXISTING_PREFIX | MAMBA_ALLOW_MISSING_PREFIX
| MAMBA_ALLOW_NOT_ENV_PREFIX | MAMBA_NOT_EXPECT_EXISTING_PREFIX);
config.load();
fs::path rc_source = compute_config_path(true);
YAML::Node rc_YAML = YAML::LoadFile(rc_source);
const string_list& sv = set_value.value<string_list>();
if (is_valid_rc_key(sv.at(0)) && sv.size() < 3)
subcom->callback(
[&]()
{
rc_YAML[sv.at(0)] = sv.at(1);
}
else
{
std::cout << "Key is invalid or more than one key was received" << std::endl;
}
config.at("use_target_prefix_fallback").set_value(true);
config.at("show_banner").set_value(false);
config.at("target_prefix_checks")
.set_value(MAMBA_ALLOW_EXISTING_PREFIX | MAMBA_ALLOW_MISSING_PREFIX
| MAMBA_ALLOW_NOT_ENV_PREFIX | MAMBA_NOT_EXPECT_EXISTING_PREFIX);
config.load();
// if the rc file is being modified, it's necessary to rewrite it
std::ofstream rc_file = open_ofstream(rc_source, std::ofstream::in | std::ofstream::trunc);
rc_file << rc_YAML << std::endl;
fs::path rc_source = compute_config_path(true);
config.operation_teardown();
});
YAML::Node rc_YAML = YAML::LoadFile(rc_source);
const string_list& sv = set_value.value<string_list>();
if (is_valid_rc_key(sv.at(0)) && sv.size() < 3)
{
rc_YAML[sv.at(0)] = sv.at(1);
}
else
{
std::cout << "Key is invalid or more than one key was received" << std::endl;
}
// if the rc file is being modified, it's necessary to rewrite it
std::ofstream rc_file
= open_ofstream(rc_source, std::ofstream::in | std::ofstream::trunc);
rc_file << rc_YAML << std::endl;
config.operation_teardown();
});
}
void
@ -486,41 +510,44 @@ set_config_get_command(CLI::App* subcom)
auto& get_value = config.insert(Configurable("get_value", std::string(""))
.group("Output, Prompt and Flow Control")
.description("Display configuration value from rc file"));
subcom->add_option("get_value", get_value.get_cli_config<std::string>(), get_value.description());
subcom->add_option(
"get_value", get_value.get_cli_config<std::string>(), get_value.description());
subcom->callback([&]() {
config.at("use_target_prefix_fallback").set_value(true);
config.at("show_banner").set_value(false);
config.at("target_prefix_checks")
.set_value(MAMBA_ALLOW_EXISTING_PREFIX | MAMBA_ALLOW_MISSING_PREFIX
| MAMBA_ALLOW_NOT_ENV_PREFIX | MAMBA_NOT_EXPECT_EXISTING_PREFIX);
config.load();
fs::path rc_source = compute_config_path(false);
bool value_found = false;
YAML::Node rc_YAML = YAML::LoadFile(rc_source.string());
for (auto v : rc_YAML)
subcom->callback(
[&]()
{
if (v.first.as<std::string>() == get_value.value<std::string>())
config.at("use_target_prefix_fallback").set_value(true);
config.at("show_banner").set_value(false);
config.at("target_prefix_checks")
.set_value(MAMBA_ALLOW_EXISTING_PREFIX | MAMBA_ALLOW_MISSING_PREFIX
| MAMBA_ALLOW_NOT_ENV_PREFIX | MAMBA_NOT_EXPECT_EXISTING_PREFIX);
config.load();
fs::path rc_source = compute_config_path(false);
bool value_found = false;
YAML::Node rc_YAML = YAML::LoadFile(rc_source.string());
for (auto v : rc_YAML)
{
YAML::Node aux_rc_YAML;
aux_rc_YAML[v.first] = v.second;
std::cout << aux_rc_YAML << std::endl;
value_found = true;
break;
if (v.first.as<std::string>() == get_value.value<std::string>())
{
YAML::Node aux_rc_YAML;
aux_rc_YAML[v.first] = v.second;
std::cout << aux_rc_YAML << std::endl;
value_found = true;
break;
}
}
}
if (!value_found)
{
std::cout << "Key is not present in file" << std::endl;
}
if (!value_found)
{
std::cout << "Key is not present in file" << std::endl;
}
config.operation_teardown();
});
config.operation_teardown();
});
}
void

View File

@ -48,15 +48,18 @@ set_constructor_command(CLI::App* subcom)
{
init_constructor_parser(subcom);
subcom->callback([&]() {
auto& c = Configuration::instance();
subcom->callback(
[&]()
{
auto& c = Configuration::instance();
auto& prefix = c.at("constructor_prefix").compute().value<fs::path>();
auto& extract_conda_pkgs = c.at("constructor_extract_conda_pkgs").compute().value<bool>();
auto& extract_tarball = c.at("constructor_extract_tarball").compute().value<bool>();
auto& prefix = c.at("constructor_prefix").compute().value<fs::path>();
auto& extract_conda_pkgs
= c.at("constructor_extract_conda_pkgs").compute().value<bool>();
auto& extract_tarball = c.at("constructor_extract_tarball").compute().value<bool>();
construct(prefix, extract_conda_pkgs, extract_tarball);
});
construct(prefix, extract_conda_pkgs, extract_tarball);
});
}

View File

@ -56,107 +56,112 @@ set_env_command(CLI::App* com)
export_subcom->add_flag(
"--from-history", from_history, "Build environment spec from explicit specs in history");
export_subcom->callback([]() {
auto& ctx = Context::instance();
auto& config = Configuration::instance();
config.at("show_banner").set_value(false);
config.load();
if (explicit_format)
export_subcom->callback(
[]()
{
PrefixData pd(ctx.target_prefix);
pd.load();
auto records = pd.sorted_records();
std::cout << "# This file may be used to create an environment using:\n"
<< "# $ conda create --name <env> --file <this file>\n"
<< "# platform: " << Context::instance().platform << "\n"
<< "@EXPLICIT\n";
auto& ctx = Context::instance();
auto& config = Configuration::instance();
config.at("show_banner").set_value(false);
config.load();
for (auto& record : records)
if (explicit_format)
{
std::string clean_url, token;
split_anaconda_token(record.url, clean_url, token);
std::cout << clean_url;
if (!no_md5)
PrefixData pd(ctx.target_prefix);
pd.load();
auto records = pd.sorted_records();
std::cout << "# This file may be used to create an environment using:\n"
<< "# $ conda create --name <env> --file <this file>\n"
<< "# platform: " << Context::instance().platform << "\n"
<< "@EXPLICIT\n";
for (auto& record : records)
{
std::cout << "#" << record.md5;
std::string clean_url, token;
split_anaconda_token(record.url, clean_url, token);
std::cout << clean_url;
if (!no_md5)
{
std::cout << "#" << record.md5;
}
std::cout << "\n";
}
std::cout << "\n";
}
}
else
{
PrefixData pd(ctx.target_prefix);
pd.load();
History& hist = pd.history();
auto versions_map = pd.records();
std::cout << "name: " << get_env_name(ctx.target_prefix) << "\n";
std::cout << "channels:\n";
auto requested_specs_map = hist.get_requested_specs_map();
std::stringstream dependencies;
std::set<std::string> channels;
for (auto& [k, v] : versions_map)
else
{
if (from_history && requested_specs_map.find(k) == requested_specs_map.end())
continue;
PrefixData pd(ctx.target_prefix);
pd.load();
History& hist = pd.history();
if (from_history)
auto versions_map = pd.records();
std::cout << "name: " << get_env_name(ctx.target_prefix) << "\n";
std::cout << "channels:\n";
auto requested_specs_map = hist.get_requested_specs_map();
std::stringstream dependencies;
std::set<std::string> channels;
for (auto& [k, v] : versions_map)
{
dependencies << "- " << requested_specs_map[k].str() << "\n";
}
else
{
dependencies << "- " << v.name << "=" << v.version;
if (!no_build)
dependencies << "=" << v.build_string;
dependencies << "\n";
if (from_history && requested_specs_map.find(k) == requested_specs_map.end())
continue;
if (from_history)
{
dependencies << "- " << requested_specs_map[k].str() << "\n";
}
else
{
dependencies << "- " << v.name << "=" << v.version;
if (!no_build)
dependencies << "=" << v.build_string;
dependencies << "\n";
}
auto& c = make_channel(v.url);
// remove platform
auto u = c.base_url();
channels.insert(rsplit(u, "/", 1)[0]);
}
auto& c = make_channel(v.url);
for (auto& c : channels)
std::cout << "- " << c << "\n";
std::cout << "dependencies:\n" << dependencies.str() << std::endl;
std::cout.flush();
}
});
// remove platform
auto u = c.base_url();
channels.insert(rsplit(u, "/", 1)[0]);
list_subcom->callback(
[]()
{
auto& ctx = Context::instance();
auto& config = Configuration::instance();
config.load();
EnvironmentsManager env_manager;
if (ctx.json)
{
nlohmann::json res;
auto pfxs = env_manager.list_all_known_prefixes();
std::vector<std::string> envs(pfxs.begin(), pfxs.end());
res["envs"] = envs;
std::cout << res.dump(4) << std::endl;
return;
}
for (auto& c : channels)
std::cout << "- " << c << "\n";
std::cout << "dependencies:\n" << dependencies.str() << std::endl;
std::cout.flush();
}
});
// format and print table
printers::Table t({ "Name", "Active", "Path" });
t.set_alignment({ printers::alignment::left,
printers::alignment::left,
printers::alignment::left });
t.set_padding({ 2, 2, 2 });
list_subcom->callback([]() {
auto& ctx = Context::instance();
auto& config = Configuration::instance();
config.load();
EnvironmentsManager env_manager;
if (ctx.json)
{
nlohmann::json res;
auto pfxs = env_manager.list_all_known_prefixes();
std::vector<std::string> envs(pfxs.begin(), pfxs.end());
res["envs"] = envs;
std::cout << res.dump(4) << std::endl;
return;
}
// format and print table
printers::Table t({ "Name", "Active", "Path" });
t.set_alignment(
{ printers::alignment::left, printers::alignment::left, printers::alignment::left });
t.set_padding({ 2, 2, 2 });
for (auto& env : env_manager.list_all_known_prefixes())
{
bool is_active = (env == ctx.target_prefix);
t.add_row({ get_env_name(env), is_active ? "*" : "", env.string() });
}
t.print(std::cout);
});
for (auto& env : env_manager.list_all_known_prefixes())
{
bool is_active = (env == ctx.target_prefix);
t.add_row({ get_env_name(env), is_active ? "*" : "", env.string() });
}
t.print(std::cout);
});
}

View File

@ -15,8 +15,9 @@ set_install_command(CLI::App* subcom)
auto& config = Configuration::instance();
auto& freeze_installed = config.at("freeze_installed");
subcom->add_flag(
"--freeze-installed", freeze_installed.get_cli_config<bool>(), freeze_installed.description());
subcom->add_flag("--freeze-installed",
freeze_installed.get_cli_config<bool>(),
freeze_installed.description());
subcom->callback([&]() { install(); });
}

View File

@ -32,10 +32,12 @@ set_list_command(CLI::App* subcom)
{
init_list_parser(subcom);
subcom->callback([]() {
auto& config = Configuration::instance();
auto& regex = config.at("list_regex").compute().value<std::string>();
subcom->callback(
[]()
{
auto& config = Configuration::instance();
auto& regex = config.at("list_regex").compute().value<std::string>();
list(regex);
});
list(regex);
});
}

View File

@ -20,11 +20,13 @@ set_package_command(CLI::App* subcom)
auto extract_subcom = subcom->add_subcommand("extract");
extract_subcom->add_option("archive", infile, "Archive to extract");
extract_subcom->add_option("dest", dest, "Destination folder");
extract_subcom->callback([&]() {
std::cout << "Extracting " << fs::absolute(infile) << " to " << fs::absolute(dest)
<< std::endl;
extract(fs::absolute(infile), fs::absolute(dest));
});
extract_subcom->callback(
[&]()
{
std::cout << "Extracting " << fs::absolute(infile) << " to " << fs::absolute(dest)
<< std::endl;
extract(fs::absolute(infile), fs::absolute(dest));
});
auto compress_subcom = subcom->add_subcommand("compress");
compress_subcom->add_option("folder", infile, "Folder to compress");
@ -33,16 +35,18 @@ set_package_command(CLI::App* subcom)
"-c,--compression-level",
compression_level,
"Compression level from 0-9 (tar.bz2, default is 9), and 1-22 (conda, default is 15)");
compress_subcom->callback([&]() {
std::cout << "Compressing " << fs::absolute(infile) << " to " << dest << std::endl;
compress_subcom->callback(
[&]()
{
std::cout << "Compressing " << fs::absolute(infile) << " to " << dest << std::endl;
if (ends_with(dest, ".tar.bz2") && compression_level == -1)
compression_level = 9;
if (ends_with(dest, ".conda") && compression_level == -1)
compression_level = 15;
if (ends_with(dest, ".tar.bz2") && compression_level == -1)
compression_level = 9;
if (ends_with(dest, ".conda") && compression_level == -1)
compression_level = 15;
create_package(fs::absolute(infile), fs::absolute(dest), compression_level);
});
create_package(fs::absolute(infile), fs::absolute(dest), compression_level);
});
auto transmute_subcom = subcom->add_subcommand("transmute");
transmute_subcom->add_option("infile", infile, "Folder to compress");
@ -50,20 +54,22 @@ set_package_command(CLI::App* subcom)
"-c,--compression-level",
compression_level,
"Compression level from 0-9 (tar.bz2, default is 9), and 1-22 (conda, default is 15)");
transmute_subcom->callback([&]() {
if (ends_with(infile, ".tar.bz2"))
transmute_subcom->callback(
[&]()
{
if (compression_level == -1)
compression_level = 15;
dest = infile.substr(0, infile.size() - 8) + ".conda";
}
else
{
if (compression_level == -1)
compression_level = 9;
dest = infile.substr(0, infile.size() - 8) + ".tar.bz2";
}
std::cout << "Transmuting " << fs::absolute(infile) << " to " << dest << std::endl;
transmute(fs::absolute(infile), fs::absolute(dest), compression_level);
});
if (ends_with(infile, ".tar.bz2"))
{
if (compression_level == -1)
compression_level = 15;
dest = infile.substr(0, infile.size() - 8) + ".conda";
}
else
{
if (compression_level == -1)
compression_level = 9;
dest = infile.substr(0, infile.size() - 8) + ".tar.bz2";
}
std::cout << "Transmuting " << fs::absolute(infile) << " to " << dest << std::endl;
transmute(fs::absolute(infile), fs::absolute(dest), compression_level);
});
}

View File

@ -22,7 +22,8 @@ set_remove_command(CLI::App* subcom)
auto& config = Configuration::instance();
auto& specs = config.at("specs");
subcom->add_option("specs", specs.get_cli_config<string_list>(), "Specs to remove from the environment");
subcom->add_option(
"specs", specs.get_cli_config<string_list>(), "Specs to remove from the environment");
static bool remove_all = false, force = false, prune = true;
subcom->add_flag("-a,--all", remove_all, "Remove all packages in the environment");
@ -32,14 +33,16 @@ set_remove_command(CLI::App* subcom)
"Force removal of package (note: consistency of environment is not guaranteed!");
subcom->add_flag("--prune,!--no-prune", prune, "Prune dependencies (default)");
subcom->callback([&]() {
int flags = 0;
if (prune)
flags |= MAMBA_REMOVE_PRUNE;
if (force)
flags |= MAMBA_REMOVE_FORCE;
if (remove_all)
flags |= MAMBA_REMOVE_ALL;
remove(flags);
});
subcom->callback(
[&]()
{
int flags = 0;
if (prune)
flags |= MAMBA_REMOVE_PRUNE;
if (force)
flags |= MAMBA_REMOVE_FORCE;
if (remove_all)
flags |= MAMBA_REMOVE_ALL;
remove(flags);
});
}

View File

@ -36,7 +36,9 @@ set_common_search(CLI::App* subcom, bool is_repoquery)
static std::string query_type;
if (is_repoquery)
{
subcom->add_option("query_type", query_type, "The type of query (search, depends or whoneeds)")
subcom
->add_option(
"query_type", query_type, "The type of query (search, depends or whoneeds)")
->check(CLI::IsMember(std::vector<std::string>({ "search", "depends", "whoneeds" })))
->required();
}
@ -58,38 +60,40 @@ set_common_search(CLI::App* subcom, bool is_repoquery)
subcom->add_flag("--local,!--remote", local, "Use installed data or remote repositories");
auto& platform = config.at("platform");
subcom->add_option("--platform", platform.get_cli_config<std::string>(), platform.description());
subcom->add_option(
"--platform", platform.get_cli_config<std::string>(), platform.description());
subcom->callback([&]() {
auto qtype = str_to_qtype(query_type);
QueryResultFormat format = QueryResultFormat::kTABLE;
switch (qtype)
subcom->callback(
[&]()
{
case QueryType::kSEARCH:
format = QueryResultFormat::kTABLE;
local = (local == 0) ? false : local > 0;
break;
case QueryType::kDEPENDS:
format = QueryResultFormat::kTABLE;
local = (local == 0) ? true : local > 0;
break;
case QueryType::kWHONEEDS:
format = QueryResultFormat::kTABLE;
local = (local == 0) ? true : local > 0;
break;
}
if (qtype == QueryType::kDEPENDS && show_as_tree)
format = QueryResultFormat::kTREE;
auto qtype = str_to_qtype(query_type);
QueryResultFormat format = QueryResultFormat::kTABLE;
switch (qtype)
{
case QueryType::kSEARCH:
format = QueryResultFormat::kTABLE;
local = (local == 0) ? false : local > 0;
break;
case QueryType::kDEPENDS:
format = QueryResultFormat::kTABLE;
local = (local == 0) ? true : local > 0;
break;
case QueryType::kWHONEEDS:
format = QueryResultFormat::kTABLE;
local = (local == 0) ? true : local > 0;
break;
}
if (qtype == QueryType::kDEPENDS && show_as_tree)
format = QueryResultFormat::kTREE;
if (qtype == QueryType::kSEARCH && pretty_print)
format = QueryResultFormat::kPRETTY;
if (qtype == QueryType::kSEARCH && pretty_print)
format = QueryResultFormat::kPRETTY;
// if (ctx.json)
// format = QueryResultFormat::kJSON;
repoquery(qtype, format, local, specs[0]);
});
// if (ctx.json)
// format = QueryResultFormat::kJSON;
repoquery(qtype, format, local, specs[0]);
});
}
void

View File

@ -12,18 +12,20 @@
#include <nlohmann/json.hpp>
#ifndef _WIN32
extern "C" {
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
extern "C"
{
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
}
#endif
namespace mamba {
namespace mamba
{
bool is_process_name_running(const std::string& name);
@ -33,86 +35,55 @@ namespace mamba {
assert(!program_name.empty());
static const std::vector prefixes = {
"curious",
"gentle",
"happy",
"stubborn",
"boring",
"interesting",
"funny",
"weird",
"surprising",
"serious",
"tender",
"obvious",
"great",
"proud",
"silent",
"loud",
"vacuous",
"focused",
"pretty",
"slick",
"tedious",
"stubborn",
"daring",
"tenacious",
"resilient",
"rigorous",
"friendly",
"creative",
"polite",
"frank",
"honest",
"warm",
"smart",
"intriguing",
"curious", "gentle", "happy", "stubborn", "boring", "interesting",
"funny", "weird", "surprising", "serious", "tender", "obvious",
"great", "proud", "silent", "loud", "vacuous", "focused",
"pretty", "slick", "tedious", "stubborn", "daring", "tenacious",
"resilient", "rigorous", "friendly", "creative", "polite", "frank",
"honest", "warm", "smart", "intriguing",
// TODO: add more here
};
static std::vector alt_names{
"program",
"application",
"app",
"code",
"blob",
"binary",
"script",
"program", "application", "app", "code", "blob", "binary", "script",
};
static std::vector prefixes_bag = prefixes;
std::string selected_name{ program_name };
while(true)
while (true)
{
std::string selected_prefix;
if(!prefixes_bag.empty())
if (!prefixes_bag.empty())
{
// Pick a random prefix from our bag of prefixes.
const auto selected_prefix_idx = random_int<std::size_t>(0, prefixes_bag.size() - 1);
const auto selected_prefix_it = std::next(prefixes_bag.begin(), selected_prefix_idx);
const auto selected_prefix_idx
= random_int<std::size_t>(0, prefixes_bag.size() - 1);
const auto selected_prefix_it
= std::next(prefixes_bag.begin(), selected_prefix_idx);
selected_prefix = *selected_prefix_it;
prefixes_bag.erase(selected_prefix_it);
}
else if(!alt_names.empty())
else if (!alt_names.empty())
{
// No more prefixes: we retry the same prefixes but with a different program name.
const auto selected_name_idx = random_int<std::size_t>(0, alt_names.size() - 1);
const auto selected_name_it = std::next(alt_names.begin(), selected_name_idx);
selected_name = *selected_name_it;
alt_names.erase(selected_name_it);
prefixes_bag = prefixes; // Re-fill the prefix bag.
continue; // Re-try with new prefix + new name.
prefixes_bag = prefixes; // Re-fill the prefix bag.
continue; // Re-try with new prefix + new name.
}
else
{
// No prefixes left in the bag nor alternative names, just generate a random prefix as a fail-safe.
// No prefixes left in the bag nor alternative names, just generate a random prefix
// as a fail-safe.
constexpr std::size_t arbitrary_prefix_length = 8;
selected_prefix = generate_random_alphanumeric_string(arbitrary_prefix_length);
selected_name = program_name;
}
const auto new_process_name = fmt::format("{}_{}", selected_prefix, selected_name);
if(!is_process_name_running(new_process_name))
if (!is_process_name_running(new_process_name))
return new_process_name;
}
}
@ -127,43 +98,47 @@ namespace mamba {
{
fs::create_directories(proc_dir());
auto lockfile = LockFile::try_lock(proc_dir());
if(!lockfile)
if (!lockfile)
{
throw std::runtime_error(fmt::format("'mamba run' failed to lock ({}) or lockfile was not properly deleted", proc_dir()));
throw std::runtime_error(
fmt::format("'mamba run' failed to lock ({}) or lockfile was not properly deleted",
proc_dir()));
}
return lockfile;
}
struct Predicate_AlwaysTrue
{
template<typename T>
constexpr bool operator()(T&&) noexcept { return true; }
template <typename T>
constexpr bool operator()(T&&) noexcept
{
return true;
}
};
template<typename Predicate = Predicate_AlwaysTrue>
template <typename Predicate = Predicate_AlwaysTrue>
nlohmann::json get_all_running_processes_info(Predicate filter = {})
{
nlohmann::json all_processes_info;
const auto open_mode = std::ios::binary | std::ios::in;
for(auto&& entry : fs::directory_iterator{proc_dir()})
for (auto&& entry : fs::directory_iterator{ proc_dir() })
{
const auto file_location = entry.path();
if(file_location.extension() != ".json")
if (file_location.extension() != ".json")
continue;
fs::ifstream pid_file{ file_location, open_mode };
if(!pid_file.is_open())
if (!pid_file.is_open())
{
LOG_WARNING << fmt::format("failed to open {}", file_location);
continue;
}
const auto running_processes_info = nlohmann::json::parse(pid_file);
if(filter(running_processes_info))
if (filter(running_processes_info))
all_processes_info.push_back(running_processes_info);
}
return all_processes_info;
@ -171,9 +146,8 @@ namespace mamba {
bool is_process_name_running(const std::string& name)
{
const auto other_processes_with_same_name = get_all_running_processes_info([&](auto&& process_info){
return process_info["child_name"] == name;
});
const auto other_processes_with_same_name = get_all_running_processes_info(
[&](auto&& process_info) { return process_info["child_name"] == name; });
return !other_processes_with_same_name.empty();
}
@ -183,17 +157,20 @@ namespace mamba {
const fs::path location;
public:
ScopedProcFile(const std::string& child_name, const std::vector<std::string>& command, std::unique_ptr<LockFile> proc_dir_lock = lock_proc_dir())
ScopedProcFile(const std::string& child_name,
const std::vector<std::string>& command,
std::unique_ptr<LockFile> proc_dir_lock = lock_proc_dir())
: location{ proc_dir() / fmt::format("{}.json", getpid()) }
{
assert(proc_dir_lock); // Lock must be hold for the duraction of this constructor.
assert(proc_dir_lock); // Lock must be hold for the duraction of this constructor.
const auto open_mode = std::ios::binary | std::ios::trunc | std::ios::in | std::ios::out;
const auto open_mode
= std::ios::binary | std::ios::trunc | std::ios::in | std::ios::out;
fs::fstream pid_file{ location, open_mode };
if(!pid_file.is_open())
if (!pid_file.is_open())
{
throw std::runtime_error(fmt::format("'mamba run' failed to open/create file: {}", location));
throw std::runtime_error(
fmt::format("'mamba run' failed to open/create file: {}", location));
}
nlohmann::json file_json;
@ -208,9 +185,10 @@ namespace mamba {
const auto lock = lock_proc_dir();
std::error_code errcode;
const bool is_removed = fs::remove(location, errcode);
if(!is_removed)
if (!is_removed)
{
LOG_WARNING << fmt::format("Failed to remove file '{}' : {}", location, errcode.message());
LOG_WARNING << fmt::format(
"Failed to remove file '{}' : {}", location, errcode.message());
}
}
};
@ -220,7 +198,8 @@ namespace mamba {
using namespace mamba; // NOLINT(build/namespaces)
#ifndef _WIN32
void daemonize()
void
daemonize()
{
pid_t pid, sid;
int fd;
@ -250,13 +229,13 @@ void daemonize()
if (fd != -1)
{
dup2 (fd, STDIN_FILENO);
dup2 (fd, STDOUT_FILENO);
dup2 (fd, STDERR_FILENO);
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
if (fd > 2)
{
close (fd);
close(fd);
}
}
}
@ -268,10 +247,17 @@ set_run_command(CLI::App* subcom)
init_prefix_options(subcom);
static std::string streams;
CLI::Option* stream_option = subcom->add_option("-a,--attach", streams, "Attach to stdin, stdout and/or stderr. -a \"\" for disabling stream redirection")->join(',');
CLI::Option* stream_option
= subcom
->add_option(
"-a,--attach",
streams,
"Attach to stdin, stdout and/or stderr. -a \"\" for disabling stream redirection")
->join(',');
static std::string cwd;
subcom->add_option("--cwd", cwd, "Current working directory for command to run in. Defaults to cwd");
subcom->add_option(
"--cwd", cwd, "Current working directory for command to run in. Defaults to cwd");
static bool detach = false;
#ifndef _WIN32
@ -282,169 +268,196 @@ set_run_command(CLI::App* subcom)
subcom->add_flag("--clean-env", clean_env, "Start with a clean environment");
static std::vector<std::string> env_vars;
subcom->add_option("-e,--env", env_vars, "Add env vars with -e ENVVAR or -e ENVVAR=VALUE")->allow_extra_args(false);
subcom->add_option("-e,--env", env_vars, "Add env vars with -e ENVVAR or -e ENVVAR=VALUE")
->allow_extra_args(false);
#ifndef _WIN32
static std::string specific_process_name;
subcom->add_option("--pname", specific_process_name, "Specifies the name of the process. If not set, a unique name enerated by deriving from the executable name will be generated.");
subcom->add_option(
"--pname",
specific_process_name,
"Specifies the name of the process. If not set, a unique name enerated by deriving from the executable name will be generated.");
#endif
subcom->prefix_command();
static reproc::process proc;
subcom->callback([subcom, stream_option]() {
auto& config = Configuration::instance();
config.at("show_banner").set_value(false);
config.load();
std::vector<std::string> command = subcom->remaining();
if (command.empty())
subcom->callback(
[subcom, stream_option]()
{
LOG_ERROR << "Did not receive any command to run inside environment";
exit(1);
}
auto& config = Configuration::instance();
config.at("show_banner").set_value(false);
config.load();
LOG_DEBUG << "Currently running processes: " << get_all_running_processes_info();
LOG_DEBUG << "Remaining args to run as command: " << join(" ", command);
std::vector<std::string> command = subcom->remaining();
if (command.empty())
{
LOG_ERROR << "Did not receive any command to run inside environment";
exit(1);
}
LOG_DEBUG << "Currently running processes: " << get_all_running_processes_info();
LOG_DEBUG << "Remaining args to run as command: " << join(" ", command);
// replace the wrapping bash with new process entirely
#ifndef _WIN32
if (command.front() != "exec")
command.insert(command.begin(), "exec");
if (command.front() != "exec")
command.insert(command.begin(), "exec");
// Lock the process directory to read and write in it until we are ready to launch the child process.
auto proc_dir_lock = lock_proc_dir();
// Lock the process directory to read and write in it until we are ready to launch the
// child process.
auto proc_dir_lock = lock_proc_dir();
const std::string process_name = [&]{
// Insert a unique process name associated to the command, either specified by the user or generated.
command.reserve(4); // We need at least 4 objects to not move around.
const auto exe_name_it = std::next(command.begin());
if(specific_process_name.empty())
const std::string process_name = [&]
{
const auto unique_name = generate_unique_process_name(*exe_name_it);
command.insert(exe_name_it, { {"-a"}, unique_name });
return unique_name;
}
else
{
if(is_process_name_running(specific_process_name))
// Insert a unique process name associated to the command, either specified by the
// user or generated.
command.reserve(4); // We need at least 4 objects to not move around.
const auto exe_name_it = std::next(command.begin());
if (specific_process_name.empty())
{
throw std::runtime_error(fmt::format("Another process with name '{}' is currently running.", specific_process_name));
}
command.insert(exe_name_it, { {"-a"}, specific_process_name });
return specific_process_name;
}
}();
// Writes the process file then unlock the directory. Deletes the process file once exit is called (in the destructor).
static ScopedProcFile scoped_proc_file{ process_name, command, std::move(proc_dir_lock) }; // Note: this object is static only so that calls to `std::exit()` will call the destructor.
#endif
auto [wrapped_command, script_file]
= prepare_wrapped_call(Context::instance().target_prefix, command);
LOG_DEBUG << "Running wrapped script: " << join(" ", command);
bool all_streams = stream_option->count() == 0u;
bool sinkout = !all_streams && streams.find("stdout") == std::string::npos;
bool sinkerr = !all_streams && streams.find("stderr") == std::string::npos;
bool sinkin = !all_streams && streams.find("stdin") == std::string::npos;
reproc::options opt;
if (cwd != "")
{
opt.working_directory = cwd.c_str();
}
if (clean_env)
{
opt.env.behavior = reproc::env::empty;
}
std::map<std::string, std::string> env_map;
if (env_vars.size())
{
for (auto& e : env_vars)
{
if (e.find_first_of("=") != std::string::npos)
{
auto split_e = split(e, "=", 1);
env_map[split_e[0]] = split_e[1];
const auto unique_name = generate_unique_process_name(*exe_name_it);
command.insert(exe_name_it, { { "-a" }, unique_name });
return unique_name;
}
else
{
auto val = env::get(e);
if (val)
if (is_process_name_running(specific_process_name))
{
env_map[e] = val.value();
throw std::runtime_error(
fmt::format("Another process with name '{}' is currently running.",
specific_process_name));
}
command.insert(exe_name_it, { { "-a" }, specific_process_name });
return specific_process_name;
}
}();
// Writes the process file then unlock the directory. Deletes the process file once exit
// is called (in the destructor).
static ScopedProcFile scoped_proc_file{
process_name, command, std::move(proc_dir_lock)
}; // Note: this object is static only so that calls to `std::exit()` will call the
// destructor.
#endif
auto [wrapped_command, script_file]
= prepare_wrapped_call(Context::instance().target_prefix, command);
LOG_DEBUG << "Running wrapped script: " << join(" ", command);
bool all_streams = stream_option->count() == 0u;
bool sinkout = !all_streams && streams.find("stdout") == std::string::npos;
bool sinkerr = !all_streams && streams.find("stderr") == std::string::npos;
bool sinkin = !all_streams && streams.find("stdin") == std::string::npos;
reproc::options opt;
if (cwd != "")
{
opt.working_directory = cwd.c_str();
}
if (clean_env)
{
opt.env.behavior = reproc::env::empty;
}
std::map<std::string, std::string> env_map;
if (env_vars.size())
{
for (auto& e : env_vars)
{
if (e.find_first_of("=") != std::string::npos)
{
auto split_e = split(e, "=", 1);
env_map[split_e[0]] = split_e[1];
}
else
{
LOG_WARNING << "Requested env var " << e << " does not exist in environment";
auto val = env::get(e);
if (val)
{
env_map[e] = val.value();
}
else
{
LOG_WARNING << "Requested env var " << e
<< " does not exist in environment";
}
}
}
opt.env.extra = env_map;
}
opt.env.extra = env_map;
}
opt.redirect.out.type = sinkout ? reproc::redirect::discard : reproc::redirect::parent;
opt.redirect.err.type = sinkerr ? reproc::redirect::discard : reproc::redirect::parent;
opt.redirect.in.type = sinkin ? reproc::redirect::discard : reproc::redirect::parent;
opt.redirect.out.type = sinkout ? reproc::redirect::discard : reproc::redirect::parent;
opt.redirect.err.type = sinkerr ? reproc::redirect::discard : reproc::redirect::parent;
opt.redirect.in.type = sinkin ? reproc::redirect::discard : reproc::redirect::parent;
#ifndef _WIN32
if (detach)
{
std::cout << fmt::format(fmt::fg(fmt::terminal_color::green), "Running wrapped script {} in the background", join(" ", command)) << std::endl;
daemonize();
}
if (detach)
{
std::cout << fmt::format(fmt::fg(fmt::terminal_color::green),
"Running wrapped script {} in the background",
join(" ", command))
<< std::endl;
daemonize();
}
#endif
int status;
PID pid;
std::error_code ec;
int status;
PID pid;
std::error_code ec;
ec = proc.start(wrapped_command, opt);
ec = proc.start(wrapped_command, opt);
std::tie(pid, ec) = proc.pid();
std::tie(pid, ec) = proc.pid();
if (ec)
{
std::cerr << ec.message() << std::endl;
exit(1);
}
if (ec)
{
std::cerr << ec.message() << std::endl;
exit(1);
}
#ifndef _WIN32
std::thread t([](){
signal(SIGTERM, [](int signum) {
LOG_INFO << "Received SIGTERM on micromamba run - terminating process";
reproc::stop_actions sa;
sa.first = reproc::stop_action{reproc::stop::terminate, std::chrono::milliseconds(3000)};
sa.second = reproc::stop_action{reproc::stop::kill, std::chrono::milliseconds(3000)};
proc.stop(sa);
});
std::thread t(
[]()
{
signal(SIGTERM,
[](int signum)
{
LOG_INFO
<< "Received SIGTERM on micromamba run - terminating process";
reproc::stop_actions sa;
sa.first = reproc::stop_action{ reproc::stop::terminate,
std::chrono::milliseconds(3000) };
sa.second = reproc::stop_action{ reproc::stop::kill,
std::chrono::milliseconds(3000) };
proc.stop(sa);
});
});
t.detach();
#endif
// check if we need this
if (!opt.redirect.discard && opt.redirect.file == nullptr
&& opt.redirect.path == nullptr)
{
opt.redirect.parent = true;
}
ec = reproc::drain(proc, reproc::sink::null, reproc::sink::null);
std::tie(status, ec) = proc.stop(opt.stop);
if (ec)
{
std::cerr << ec.message() << std::endl;
}
// exit with status code from reproc
exit(status);
});
t.detach();
#endif
// check if we need this
if (!opt.redirect.discard && opt.redirect.file == nullptr &&
opt.redirect.path == nullptr) {
opt.redirect.parent = true;
}
ec = reproc::drain(proc, reproc::sink::null, reproc::sink::null);
std::tie(status, ec) = proc.stop(opt.stop);
if (ec)
{
std::cerr << ec.message() << std::endl;
}
// exit with status code from reproc
exit(status);
});
}

View File

@ -24,7 +24,9 @@ init_shell_parser(CLI::App* subcom)
auto& shell_type = config.insert(
Configurable("shell_type", std::string("")).group("cli").description("A shell type"));
subcom->add_option("-s,--shell", shell_type.get_cli_config<std::string>(), shell_type.description())
subcom
->add_option(
"-s,--shell", shell_type.get_cli_config<std::string>(), shell_type.description())
->check(CLI::IsMember(std::set<std::string>(
{ "bash", "posix", "powershell", "cmd.exe", "xonsh", "zsh", "fish" })));
@ -71,13 +73,15 @@ set_shell_command(CLI::App* subcom)
{
init_shell_parser(subcom);
subcom->callback([&]() {
auto& config = Configuration::instance();
subcom->callback(
[&]()
{
auto& config = Configuration::instance();
auto& prefix = config.at("shell_prefix").compute().value<std::string>();
auto& action = config.at("shell_action").compute().value<std::string>();
auto& shell = config.at("shell_type").compute().value<std::string>();
auto& stack = config.at("shell_stack").compute().value<bool>();
mamba::shell(action, shell, prefix, stack);
});
auto& prefix = config.at("shell_prefix").compute().value<std::string>();
auto& action = config.at("shell_action").compute().value<std::string>();
auto& shell = config.at("shell_type").compute().value<std::string>();
auto& stack = config.at("shell_stack").compute().value<bool>();
mamba::shell(action, shell, prefix, stack);
});
}

View File

@ -30,7 +30,8 @@ set_umamba_command(CLI::App* com)
Context::instance().caller_version = umamba::version();
auto print_version = [](int count) {
auto print_version = [](int count)
{
std::cout << umamba::version() << std::endl;
exit(0);
};
@ -88,8 +89,8 @@ set_umamba_command(CLI::App* com)
CLI::App* run_subcom = com->add_subcommand("run", "Run an executable in an environment");
set_run_command(run_subcom);
CLI::App* search_subcom = com->add_subcommand(
"search", "Find packages in active environment or channels");
CLI::App* search_subcom
= com->add_subcommand("search", "Find packages in active environment or channels");
set_search_command(search_subcom);
com->require_subcommand(/* min */ 0, /* max */ 1);

View File

@ -70,6 +70,7 @@ set_run_command(CLI::App* subcom);
void
get_completions(CLI::App* app, int argc, char** argv);
void set_search_command(CLI::App* subcom);
void
set_search_command(CLI::App* subcom);
#endif