Windows menuinst (#3846)

This commit is contained in:
Hind-M 2025-03-25 06:20:47 +01:00 committed by GitHub
parent b3a48ce365
commit 7c972d2d47
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 94 additions and 39 deletions

View File

@ -253,6 +253,12 @@ namespace mamba
namespace
{
enum class MenuInstVersion : std::uint8_t
{
Version1 = 1,
Version2 = 2,
};
void create_remove_shortcut_impl(
const Context& ctx,
const fs::u8path& json_file,
@ -333,56 +339,85 @@ namespace mamba
}
};
// Check menuinst schema version (through the presence of "$id" and "$schema" keys)
// cf. https://github.com/conda/ceps/blob/3da0fb0ece/cep-11.md#backwards-compatibility
auto menuinst_version = MenuInstVersion::Version1; // v1-legacy
if (j.contains("$id") && j.contains("$schema"))
{
menuinst_version = MenuInstVersion::Version2; // v2
}
for (auto& item : j["menu_items"])
{
std::string name = item["name"];
std::string full_name = util::concat(name, name_suffix);
std::string name;
std::vector<std::string> arguments;
fs::u8path script;
if (item.contains("pywscript"))
// cf. https://github.com/conda/menuinst/pull/180
if (menuinst_version == MenuInstVersion::Version1)
{
script = root_pyw;
arguments = cwp_pyw_args;
auto tmp = util::split(item["pywscript"], " ");
std::copy(tmp.begin(), tmp.end(), back_inserter(arguments));
}
else if (item.contains("pyscript"))
{
script = root_py;
arguments = cwp_py_args;
auto tmp = util::split(item["pyscript"], " ");
std::copy(tmp.begin(), tmp.end(), back_inserter(arguments));
}
else if (item.contains("webbrowser"))
{
script = root_pyw;
arguments = { "-m", "webbrowser", "-t", item["webbrowser"] };
}
else if (item.contains("script"))
{
script = root_py;
arguments = { cwp_path.string(), target_prefix.string() };
auto tmp = util::split(item["script"], " ");
std::copy(tmp.begin(), tmp.end(), back_inserter(arguments));
extend_script_args(item, arguments);
}
else if (item.contains("system"))
{
auto tmp = util::split(item["system"], " ");
script = tmp[0];
if (tmp.size() > 1)
name = item["name"]; // Should be a string
if (item.contains("pywscript"))
{
std::copy(tmp.begin() + 1, tmp.end(), back_inserter(arguments));
script = root_pyw;
arguments = cwp_pyw_args;
auto tmp = util::split(item["pywscript"], " ");
std::copy(tmp.begin(), tmp.end(), back_inserter(arguments));
}
else if (item.contains("pyscript"))
{
script = root_py;
arguments = cwp_py_args;
auto tmp = util::split(item["pyscript"], " ");
std::copy(tmp.begin(), tmp.end(), back_inserter(arguments));
}
else if (item.contains("webbrowser"))
{
script = root_pyw;
arguments = { "-m", "webbrowser", "-t", item["webbrowser"] };
}
else if (item.contains("script"))
{
script = root_py;
arguments = { cwp_path.string(), target_prefix.string() };
auto tmp = util::split(item["script"], " ");
std::copy(tmp.begin(), tmp.end(), back_inserter(arguments));
extend_script_args(item, arguments);
}
else if (item.contains("system"))
{
auto tmp = util::split(item["system"], " ");
script = tmp[0];
if (tmp.size() > 1)
{
std::copy(tmp.begin() + 1, tmp.end(), back_inserter(arguments));
}
extend_script_args(item, arguments);
}
else
{
LOG_ERROR << "Unknown shortcut type found in " << json_file;
throw std::runtime_error("Unknown shortcut type.");
}
extend_script_args(item, arguments);
}
else
else // MenuInstVersion::Version2
{
LOG_ERROR << "Unknown shortcut type found in " << json_file;
throw std::runtime_error("Unknown shortcut type.");
// `item["name"]` should be an object containing items with
// "target_environment_is_base" and "target_environment_is_not_base"(default)
// as keys
name = item["name"]["target_environment_is_not_base"];
// cf.
// https://conda.github.io/menuinst/defining-shortcuts/#migrating-pywscript-and-pyscript-to-menuinst-v2
for (const auto& el : item["command"])
{
arguments.push_back(el.get<std::string>());
}
script = arguments[0];
}
std::string full_name = util::concat(name, name_suffix);
fs::u8path dst = target_dir / (full_name + ".lnk");
fs::u8path workdir = item.value("workdir", "");
fs::u8path iconpath = item.value("icon", "");

View File

@ -98,3 +98,23 @@ class TestMenuinst:
shutil.rmtree(root_prefix)
os.environ["MAMBA_ROOT_PREFIX"] = self.root_prefix
# Testing a package (spyder) using menuinst v2 schema
@pytest.mark.skipif(
not sys.platform.startswith("win"),
reason="skipping windows-only tests",
)
def test_spyder_shortcut(self):
env_name = random_string()
create("python=3.12", "spyder=6.0.3", "-n", env_name, no_dry_run=True)
d = menuinst.win32.dirs_src["user"]["start"][0]
lnk = os.path.join(
d, "{{ DISTRIBUTION_NAME }} spyder", "Spyder 6 ({{ ENV_NAME }}) (" + env_name + ").lnk"
)
reset_lnk = os.path.join(
d,
"{{ DISTRIBUTION_NAME }} spyder",
"Reset Spyder 6 ({{ ENV_NAME }}) to default settings (" + env_name + ").lnk",
)
assert os.path.exists(lnk)
assert os.path.exists(reset_lnk)