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);
|
||||
|
||||
/**
|
||||
* 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 *
|
||||
********************/
|
||||
|
@ -149,5 +212,40 @@ namespace mamba::specs
|
|||
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
|
||||
|
|
|
@ -16,33 +16,6 @@
|
|||
|
||||
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``.
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//
|
||||
// The full license is in the file LICENSE, distributed with this software.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
@ -18,7 +16,7 @@ namespace mamba::specs
|
|||
{
|
||||
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())
|
||||
{
|
||||
if (str_clean == platform_name(p))
|
||||
|
@ -116,4 +114,45 @@ namespace mamba::specs
|
|||
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
|
||||
{
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(
|
||||
NoArchType,
|
||||
{
|
||||
{ NoArchType::Generic, "generic" },
|
||||
{ NoArchType::Python, "python" },
|
||||
}
|
||||
)
|
||||
|
||||
void to_json(nlohmann::json& j, const RepoDataPackage& p)
|
||||
{
|
||||
j["name"] = p.name;
|
||||
|
|
|
@ -12,30 +12,57 @@ using namespace mamba::specs;
|
|||
|
||||
TEST_SUITE("specs::platform")
|
||||
{
|
||||
TEST_CASE("name")
|
||||
TEST_CASE("Platform")
|
||||
{
|
||||
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("name")
|
||||
{
|
||||
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);
|
||||
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("name")
|
||||
{
|
||||
CHECK_EQ(noarch_name(NoArchType::No), "no");
|
||||
CHECK_EQ(noarch_name(NoArchType::Generic), "generic");
|
||||
CHECK_EQ(noarch_name(NoArchType::Python), "python");
|
||||
}
|
||||
|
||||
TEST_CASE("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",
|
||||
SUBCASE("parse")
|
||||
{
|
||||
CHECK_EQ(noarch_parse(""), std::nullopt);
|
||||
CHECK_EQ(noarch_parse(" Python "), NoArchType::Python);
|
||||
CHECK_EQ(noarch_parse(" geNeric"), NoArchType::Generic);
|
||||
CHECK_EQ(noarch_parse("Nothing we know"), std::nullopt);
|
||||
}
|
||||
|
||||
};
|
||||
CHECK_EQ(expected, known_platform_names());
|
||||
SUBCASE("known_noarch")
|
||||
{
|
||||
static constexpr decltype(known_noarch_names()) expected{ "no", "generic", "python" };
|
||||
CHECK_EQ(expected, known_noarch_names());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
using namespace mamba::specs;
|
||||
namespace nl = nlohmann;
|
||||
|
||||
TEST_SUITE("repo_data")
|
||||
TEST_SUITE("specs::repo_data")
|
||||
{
|
||||
TEST_CASE("RepoDataPackage_to_json")
|
||||
{
|
||||
|
|
|
@ -77,6 +77,15 @@ namespace mambapy
|
|||
.def_static("build_platform", &build_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");
|
||||
|
||||
py::enum_<CondaURL::Credentials>(py_conda_url, "Credentials")
|
||||
|
|
|
@ -57,7 +57,23 @@ def test_Platform():
|
|||
|
||||
with pytest.raises(KeyError):
|
||||
# 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():
|
||||
|
|
Loading…
Reference in New Issue