mirror of https://github.com/mamba-org/mamba.git
NoArchType as standalone enum (#3108)
* NoArch as standalone enum * Bind NoArchType
This commit is contained in:
parent
53a5171360
commit
dae5e0e378
|
@ -81,6 +81,69 @@ namespace mamba::specs
|
||||||
*/
|
*/
|
||||||
void from_json(const nlohmann::json& j, Platform& p);
|
void from_json(const nlohmann::json& j, Platform& p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Noarch packages are packages that are not architecture specific.
|
||||||
|
*
|
||||||
|
* Noarch packages only have to be built once.
|
||||||
|
*/
|
||||||
|
enum struct NoArchType
|
||||||
|
{
|
||||||
|
/** Not a noarch type. */
|
||||||
|
No,
|
||||||
|
|
||||||
|
/** Noarch generic packages allow users to distribute docs, datasets, and source code. */
|
||||||
|
Generic,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A noarch python package is a python package without any precompiled python files.
|
||||||
|
*
|
||||||
|
* Normally, precompiled files (`.pyc` or `__pycache__`) are bundled with the package.
|
||||||
|
* However, these files are tied to a specific version of Python and must therefore be
|
||||||
|
* generated for every target platform and architecture.
|
||||||
|
* This complicates the build process.
|
||||||
|
* For noarch Python packages these files are generated when installing the package by
|
||||||
|
* invoking the compilation process through the python binary that is installed in the
|
||||||
|
* same environment.
|
||||||
|
*
|
||||||
|
* @see https://www.anaconda.com/blog/condas-new-noarch-packages
|
||||||
|
* @see
|
||||||
|
* https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/packages.html#noarch-python
|
||||||
|
*/
|
||||||
|
Python,
|
||||||
|
|
||||||
|
// For reflexion purposes only
|
||||||
|
count_,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr auto known_noarch_count() -> std::size_t
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(NoArchType::count_);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto known_noarch() -> std::array<NoArchType, known_noarch_count()>;
|
||||||
|
|
||||||
|
constexpr auto known_noarch_names() -> std::array<std::string_view, known_noarch_count()>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the enumeration to its conda string.
|
||||||
|
*/
|
||||||
|
constexpr auto noarch_name(NoArchType noarch) -> std::string_view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the enum matching the noarch name.
|
||||||
|
*/
|
||||||
|
auto noarch_parse(std::string_view str) -> std::optional<NoArchType>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize to JSON string.
|
||||||
|
*/
|
||||||
|
void to_json(nlohmann::json& j, const NoArchType& noarch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize from JSON string.
|
||||||
|
*/
|
||||||
|
void from_json(const nlohmann::json& j, NoArchType& noarch);
|
||||||
|
|
||||||
/********************
|
/********************
|
||||||
* Implementation *
|
* Implementation *
|
||||||
********************/
|
********************/
|
||||||
|
@ -149,5 +212,40 @@ namespace mamba::specs
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr auto noarch_name(NoArchType noarch) -> std::string_view
|
||||||
|
{
|
||||||
|
switch (noarch)
|
||||||
|
{
|
||||||
|
case NoArchType::No:
|
||||||
|
return "no";
|
||||||
|
case NoArchType::Generic:
|
||||||
|
return "generic";
|
||||||
|
case NoArchType::Python:
|
||||||
|
return "python";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto known_noarch() -> std::array<NoArchType, known_noarch_count()>
|
||||||
|
{
|
||||||
|
auto out = std::array<NoArchType, known_noarch_count()>{};
|
||||||
|
for (std::size_t idx = 0; idx < out.size(); ++idx)
|
||||||
|
{
|
||||||
|
out[idx] = static_cast<NoArchType>(idx);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto known_noarch_names() -> std::array<std::string_view, known_noarch_count()>
|
||||||
|
{
|
||||||
|
auto out = std::array<std::string_view, known_noarch_count()>{};
|
||||||
|
auto iter = out.begin();
|
||||||
|
for (auto p : known_noarch())
|
||||||
|
{
|
||||||
|
*(iter++) = noarch_name(p);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,33 +16,6 @@
|
||||||
|
|
||||||
namespace mamba::specs
|
namespace mamba::specs
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Noarch packages are packages that are not architecture specific.
|
|
||||||
*
|
|
||||||
* Noarch packages only have to be built once.
|
|
||||||
*/
|
|
||||||
enum struct NoArchType
|
|
||||||
{
|
|
||||||
/** Noarch generic packages allow users to distribute docs, datasets, and source code. */
|
|
||||||
Generic,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A noarch python package is a python package without any precompiled python files.
|
|
||||||
*
|
|
||||||
* Normally, precompiled files (`.pyc` or `__pycache__`) are bundled with the package.
|
|
||||||
* However, these files are tied to a specific version of Python and must therefore be
|
|
||||||
* generated for every target platform and architecture.
|
|
||||||
* This complicates the build process.
|
|
||||||
* For noarch Python packages these files are generated when installing the package by
|
|
||||||
* invoking the compilation process through the python binary that is installed in the
|
|
||||||
* same environment.
|
|
||||||
*
|
|
||||||
* @see https://www.anaconda.com/blog/condas-new-noarch-packages
|
|
||||||
* @see
|
|
||||||
* https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/packages.html#noarch-python
|
|
||||||
*/
|
|
||||||
Python,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A single record in the Conda ``repodata.json``.
|
* A single record in the Conda ``repodata.json``.
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
//
|
//
|
||||||
// The full license is in the file LICENSE, distributed with this software.
|
// The full license is in the file LICENSE, distributed with this software.
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
@ -18,7 +16,7 @@ namespace mamba::specs
|
||||||
{
|
{
|
||||||
auto platform_parse(std::string_view str) -> std::optional<Platform>
|
auto platform_parse(std::string_view str) -> std::optional<Platform>
|
||||||
{
|
{
|
||||||
std::string const str_clean = util::to_lower(util::strip(str));
|
const std::string str_clean = util::to_lower(util::strip(str));
|
||||||
for (const auto p : known_platforms())
|
for (const auto p : known_platforms())
|
||||||
{
|
{
|
||||||
if (str_clean == platform_name(p))
|
if (str_clean == platform_name(p))
|
||||||
|
@ -116,4 +114,45 @@ namespace mamba::specs
|
||||||
throw std::invalid_argument(fmt::format("Invalid platform: {}", j_str));
|
throw std::invalid_argument(fmt::format("Invalid platform: {}", j_str));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto noarch_parse(std::string_view str) -> std::optional<NoArchType>
|
||||||
|
{
|
||||||
|
const std::string str_clean = util::to_lower(util::strip(str));
|
||||||
|
for (const auto p : known_noarch())
|
||||||
|
{
|
||||||
|
if (str_clean == noarch_name(p))
|
||||||
|
{
|
||||||
|
return { p };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void to_json(nlohmann::json& j, const NoArchType& noarch)
|
||||||
|
{
|
||||||
|
if (noarch != NoArchType::No)
|
||||||
|
{
|
||||||
|
j = noarch_name(noarch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void from_json(const nlohmann::json& j, NoArchType& noarch)
|
||||||
|
{
|
||||||
|
// Legacy deserilization
|
||||||
|
if (j.is_boolean())
|
||||||
|
{
|
||||||
|
noarch = j.get<bool>() ? NoArchType::Generic : NoArchType::No;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto str = j.get<std::string_view>();
|
||||||
|
if (const auto maybe = noarch_parse(str))
|
||||||
|
{
|
||||||
|
noarch = *maybe;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::invalid_argument(fmt::format("Invalid noarch: {}", str));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,6 @@
|
||||||
|
|
||||||
namespace mamba::specs
|
namespace mamba::specs
|
||||||
{
|
{
|
||||||
NLOHMANN_JSON_SERIALIZE_ENUM(
|
|
||||||
NoArchType,
|
|
||||||
{
|
|
||||||
{ NoArchType::Generic, "generic" },
|
|
||||||
{ NoArchType::Python, "python" },
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
void to_json(nlohmann::json& j, const RepoDataPackage& p)
|
void to_json(nlohmann::json& j, const RepoDataPackage& p)
|
||||||
{
|
{
|
||||||
j["name"] = p.name;
|
j["name"] = p.name;
|
||||||
|
|
|
@ -12,30 +12,57 @@ using namespace mamba::specs;
|
||||||
|
|
||||||
TEST_SUITE("specs::platform")
|
TEST_SUITE("specs::platform")
|
||||||
{
|
{
|
||||||
TEST_CASE("name")
|
TEST_CASE("Platform")
|
||||||
{
|
{
|
||||||
CHECK_EQ(platform_name(Platform::linux_riscv32), "linux-riscv32");
|
SUBCASE("name")
|
||||||
CHECK_EQ(platform_name(Platform::osx_arm64), "osx-arm64");
|
{
|
||||||
CHECK_EQ(platform_name(Platform::win_64), "win-64");
|
CHECK_EQ(platform_name(Platform::linux_riscv32), "linux-riscv32");
|
||||||
|
CHECK_EQ(platform_name(Platform::osx_arm64), "osx-arm64");
|
||||||
|
CHECK_EQ(platform_name(Platform::win_64), "win-64");
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("parse")
|
||||||
|
{
|
||||||
|
CHECK_EQ(platform_parse("linux-armv6l"), Platform::linux_armv6l);
|
||||||
|
CHECK_EQ(platform_parse(" win-32 "), Platform::win_32);
|
||||||
|
CHECK_EQ(platform_parse(" OSX-64"), Platform::osx_64);
|
||||||
|
CHECK_EQ(platform_parse("linus-46"), std::nullopt);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("known_platform")
|
||||||
|
{
|
||||||
|
static constexpr decltype(known_platform_names()) expected{
|
||||||
|
"noarch", "linux-32", "linux-64", "linux-armv6l", "linux-armv7l",
|
||||||
|
"linux-aarch64", "linux-ppc64le", "linux-ppc64", "linux-s390x", "linux-riscv32",
|
||||||
|
"linux-riscv64", "osx-64", "osx-arm64", "win-32", "win-64",
|
||||||
|
"win-arm64", "zos-z",
|
||||||
|
|
||||||
|
};
|
||||||
|
CHECK_EQ(expected, known_platform_names());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("parse")
|
TEST_CASE("NoArch")
|
||||||
{
|
{
|
||||||
CHECK_EQ(platform_parse("linux-armv6l"), Platform::linux_armv6l);
|
SUBCASE("name")
|
||||||
CHECK_EQ(platform_parse(" win-32 "), Platform::win_32);
|
{
|
||||||
CHECK_EQ(platform_parse(" OSX-64"), Platform::osx_64);
|
CHECK_EQ(noarch_name(NoArchType::No), "no");
|
||||||
CHECK_EQ(platform_parse("linus-46"), std::nullopt);
|
CHECK_EQ(noarch_name(NoArchType::Generic), "generic");
|
||||||
}
|
CHECK_EQ(noarch_name(NoArchType::Python), "python");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("known_platform")
|
SUBCASE("parse")
|
||||||
{
|
{
|
||||||
static constexpr decltype(known_platform_names()) expected{
|
CHECK_EQ(noarch_parse(""), std::nullopt);
|
||||||
"noarch", "linux-32", "linux-64", "linux-armv6l", "linux-armv7l",
|
CHECK_EQ(noarch_parse(" Python "), NoArchType::Python);
|
||||||
"linux-aarch64", "linux-ppc64le", "linux-ppc64", "linux-s390x", "linux-riscv32",
|
CHECK_EQ(noarch_parse(" geNeric"), NoArchType::Generic);
|
||||||
"linux-riscv64", "osx-64", "osx-arm64", "win-32", "win-64",
|
CHECK_EQ(noarch_parse("Nothing we know"), std::nullopt);
|
||||||
"win-arm64", "zos-z",
|
}
|
||||||
|
|
||||||
};
|
SUBCASE("known_noarch")
|
||||||
CHECK_EQ(expected, known_platform_names());
|
{
|
||||||
|
static constexpr decltype(known_noarch_names()) expected{ "no", "generic", "python" };
|
||||||
|
CHECK_EQ(expected, known_noarch_names());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
using namespace mamba::specs;
|
using namespace mamba::specs;
|
||||||
namespace nl = nlohmann;
|
namespace nl = nlohmann;
|
||||||
|
|
||||||
TEST_SUITE("repo_data")
|
TEST_SUITE("specs::repo_data")
|
||||||
{
|
{
|
||||||
TEST_CASE("RepoDataPackage_to_json")
|
TEST_CASE("RepoDataPackage_to_json")
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,6 +77,15 @@ namespace mambapy
|
||||||
.def_static("build_platform", &build_platform);
|
.def_static("build_platform", &build_platform);
|
||||||
py::implicitly_convertible<py::str, Platform>();
|
py::implicitly_convertible<py::str, Platform>();
|
||||||
|
|
||||||
|
py::enum_<NoArchType>(m, "NoArchType")
|
||||||
|
.value("No", NoArchType::No)
|
||||||
|
.value("Generic", NoArchType::Generic)
|
||||||
|
.value("Python", NoArchType::Python)
|
||||||
|
.def(py::init(&enum_from_str<NoArchType>))
|
||||||
|
.def_static("parse", &noarch_parse)
|
||||||
|
.def_static("count", &known_noarch_count);
|
||||||
|
py::implicitly_convertible<py::str, NoArchType>();
|
||||||
|
|
||||||
auto py_conda_url = py::class_<CondaURL>(m, "CondaURL");
|
auto py_conda_url = py::class_<CondaURL>(m, "CondaURL");
|
||||||
|
|
||||||
py::enum_<CondaURL::Credentials>(py_conda_url, "Credentials")
|
py::enum_<CondaURL::Credentials>(py_conda_url, "Credentials")
|
||||||
|
|
|
@ -57,7 +57,23 @@ def test_Platform():
|
||||||
|
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(KeyError):
|
||||||
# No parsing, explicit name
|
# No parsing, explicit name
|
||||||
Platform("linux-64") == Platform.linux_64
|
Platform("linux-64")
|
||||||
|
|
||||||
|
|
||||||
|
def test_NoArchType():
|
||||||
|
NoArchType = libmambapy.specs.NoArchType
|
||||||
|
|
||||||
|
assert NoArchType.No.name == "No"
|
||||||
|
assert NoArchType.Generic.name == "Generic"
|
||||||
|
assert NoArchType.Python.name == "Python"
|
||||||
|
|
||||||
|
assert len(NoArchType.__members__) == NoArchType.count()
|
||||||
|
assert NoArchType.parse(" Python") == NoArchType.Python
|
||||||
|
assert NoArchType("Generic") == NoArchType.Generic
|
||||||
|
|
||||||
|
with pytest.raises(KeyError):
|
||||||
|
# No parsing, explicit name, needs "Generic"
|
||||||
|
NoArchType("generic")
|
||||||
|
|
||||||
|
|
||||||
def test_CondaURL_Credentials():
|
def test_CondaURL_Credentials():
|
||||||
|
|
Loading…
Reference in New Issue