mirror of https://github.com/mamba-org/mamba.git
format all files
This commit is contained in:
parent
7f9c5adb77
commit
42f2cd88ba
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
||||
/**********************
|
||||
|
|
|
@ -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, ^) \
|
||||
|
|
|
@ -33,7 +33,6 @@ namespace mamba
|
|||
operator Pool*();
|
||||
|
||||
private:
|
||||
|
||||
std::pair<spdlog::logger*, std::string> m_debug_logger;
|
||||
Pool* m_pool;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
{
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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(); });
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue