From d3ab1eb9e6a183879fa186dbda20e73119899d6d Mon Sep 17 00:00:00 2001 From: Travis Hathaway Date: Wed, 26 Apr 2023 16:01:40 +0200 Subject: [PATCH] Add "sorted" macro to JSON data types (#180) * adding sorted macro to IndexJson * fixing typo * adding AboutJson --- .../rattler_conda_types/src/package/about.rs | 29 +++++---- .../rattler_conda_types/src/package/index.rs | 65 ++++++++++--------- ...__about__test__reconstruct_about_json.snap | 10 +-- ...t__test__reconstruct_about_json_mamba.snap | 12 ++-- ...__index__test__reconstruct_index_json.snap | 10 +-- ..._reconstruct_index_json_with_symlinks.snap | 8 +-- crates/rattler_macros/src/lib.rs | 4 ++ 7 files changed, 74 insertions(+), 64 deletions(-) diff --git a/crates/rattler_conda_types/src/package/about.rs b/crates/rattler_conda_types/src/package/about.rs index 166b5ba61..e0f8b0db8 100644 --- a/crates/rattler_conda_types/src/package/about.rs +++ b/crates/rattler_conda_types/src/package/about.rs @@ -9,25 +9,22 @@ use serde_with::{serde_as, skip_serializing_none, OneOrMany, Same}; use url::Url; +use rattler_macros::sorted; + /// The `about.json` file contains metadata about the package #[serde_as] +#[sorted] #[skip_serializing_none] #[derive(Debug, Deserialize, Serialize, Eq, PartialEq)] pub struct AboutJson { + /// A list of channels that where used during the build + #[serde(skip_serializing_if = "Vec::is_empty", default)] + pub channels: Vec, + /// Description of the package #[serde_as(deserialize_as = "Option")] pub description: Option, - /// Short summary description - #[serde_as(deserialize_as = "Option")] - pub summary: Option, - - /// Optionally, the license - pub license: Option, - - /// Optionally, the license family - pub license_family: Option, - /// URL to the development page of the package #[serde(skip_serializing_if = "Vec::is_empty", default)] #[serde_as( @@ -52,14 +49,20 @@ pub struct AboutJson { )] pub home: Vec, + /// Optionally, the license + pub license: Option, + + /// Optionally, the license family + pub license_family: Option, + /// URL to the latest source code of the package #[serde(default)] #[serde_as(deserialize_as = "LossyUrl")] pub source_url: Option, - /// A list of channels that where used during the build - #[serde(skip_serializing_if = "Vec::is_empty", default)] - pub channels: Vec, + /// Short summary description + #[serde_as(deserialize_as = "Option")] + pub summary: Option, } impl PackageFile for AboutJson { diff --git a/crates/rattler_conda_types/src/package/index.rs b/crates/rattler_conda_types/src/package/index.rs index 5fa294893..ab5f015e6 100644 --- a/crates/rattler_conda_types/src/package/index.rs +++ b/crates/rattler_conda_types/src/package/index.rs @@ -5,20 +5,19 @@ use crate::{NoArchType, Version}; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, skip_serializing_none, DisplayFromStr, OneOrMany}; +use rattler_macros::sorted; + /// A representation of the `index.json` file found in package archives. /// /// The `index.json` file contains information about the package build and dependencies of the package. /// This data makes up the repodata.json file in the repository. #[serde_as] +#[sorted] #[skip_serializing_none] #[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)] pub struct IndexJson { - /// The lowercase name of the package - pub name: String, - - /// The version of the package - #[serde_as(as = "DisplayFromStr")] - pub version: Version, + /// Optionally, the architecture the package is build for. + pub arch: Option, /// The build string of the package. pub build: String, @@ -26,16 +25,18 @@ pub struct IndexJson { /// The build number of the package. This is also included in the build string. pub build_number: u64, - /// Optionally, the architecture the package is build for. - pub arch: Option, + /// The package constraints of the package + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub constrains: Vec, - /// If this package is independent of architecture this field specifies in what way. See - /// [`NoArchType`] for more information. - #[serde(skip_serializing_if = "NoArchType::is_none")] - pub noarch: NoArchType, + /// The dependencies of the package + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub depends: Vec, - /// Optionally, the OS the package is build for. - pub platform: Option, + /// Features are a deprecated way to specify different feature sets for the conda solver. This is not + /// supported anymore and should not be used. Instead, `mutex` packages should be used to specify + /// mutually exclusive features. + pub features: Option, /// Optionally, the license pub license: Option, @@ -43,13 +44,23 @@ pub struct IndexJson { /// Optionally, the license family pub license_family: Option, - /// The dependencies of the package - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub depends: Vec, + /// The lowercase name of the package + pub name: String, - /// The package constraints of the package - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub constrains: Vec, + /// If this package is independent of architecture this field specifies in what way. See + /// [`NoArchType`] for more information. + #[serde(skip_serializing_if = "NoArchType::is_none")] + pub noarch: NoArchType, + + /// Optionally, the OS the package is build for. + pub platform: Option, + + /// The subdirectory that contains this package + pub subdir: Option, + + /// The timestamp when this package was created + #[serde_as(as = "Option")] + pub timestamp: Option>, /// Track features are nowadays only used to downweight packages (ie. give them less priority). To /// that effect, the number of track features is counted (number of commas) and the package is downweighted @@ -58,17 +69,9 @@ pub struct IndexJson { #[serde_as(as = "OneOrMany<_>")] pub track_features: Vec, - /// Features are a deprecated way to specify different feature sets for the conda solver. This is not - /// supported anymore and should not be used. Instead, `mutex` packages should be used to specify - /// mutually exclusive features. - pub features: Option, - - /// The timestamp when this package was created - #[serde_as(as = "Option")] - pub timestamp: Option>, - - /// The subdirectory that contains this package - pub subdir: Option, + /// The version of the package + #[serde_as(as = "DisplayFromStr")] + pub version: Version, } impl PackageFile for IndexJson { diff --git a/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__about__test__reconstruct_about_json.snap b/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__about__test__reconstruct_about_json.snap index 58a10beca..43553dc61 100644 --- a/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__about__test__reconstruct_about_json.snap +++ b/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__about__test__reconstruct_about_json.snap @@ -1,13 +1,13 @@ --- source: crates/rattler_conda_types/src/package/about.rs -expression: "About::from_package_directory(package_dir.path()).unwrap()" +expression: "AboutJson::from_package_directory(package_dir.path()).unwrap()" --- +channels: + - "https://conda.anaconda.org/conda-forge" description: "Conda is an open source package management system and environment management system for installing multiple versions of software packages and their dependencies and switching easily between them. It works on Linux, OS X and Windows, and was created for Python programs but can package and distribute any software.\n" -summary: "OS-agnostic, system-level binary package and environment manager." -license: BSD-3-Clause dev_url: "https://github.com/conda/conda" doc_url: "https://docs.conda.io/projects/conda/en/stable/" home: "https://conda.io/" -channels: - - "https://conda.anaconda.org/conda-forge" +license: BSD-3-Clause +summary: "OS-agnostic, system-level binary package and environment manager." diff --git a/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__about__test__reconstruct_about_json_mamba.snap b/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__about__test__reconstruct_about_json_mamba.snap index 916fe6381..45d06249d 100644 --- a/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__about__test__reconstruct_about_json_mamba.snap +++ b/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__about__test__reconstruct_about_json_mamba.snap @@ -1,13 +1,13 @@ --- source: crates/rattler_conda_types/src/package/about.rs -expression: "About::from_package_directory(&package_dir).unwrap()" +expression: "AboutJson::from_package_directory(&package_dir).unwrap()" --- +channels: + - "https://conda.anaconda.org/conda-forge" description: "\n[![Build Status](https://github.com/mamba-org/mamba/workflows/CI/badge.svg)](https://github.com/mamba-org/mamba/actions)\n[![Join the Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mamba-org/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n[![docs](https://readthedocs.org/projects/mamba/badge/?version=latest&style=flat)](https://mamba.readthedocs.io/en/latest)\n\n`mamba` is a reimplementation of the conda package manager in C++.\n\n- parallel downloading of repository data and package files using multi-threading\n- libsolv for much faster dependency solving, a state of the art library used in the RPM package manager of Red Hat, Fedora and OpenSUSE\n- core parts of `mamba` are implemented in C++ for maximum efficiency\n\nAt the same time, `mamba` utilizes the same command line parser, package installation and deinstallation code and transaction verification routines as `conda` to stay as compatible as possible.\n\nMamba is part of a bigger ecosystem to make scientific packaging more sustainable. You can read our [announcement blog post](https://medium.com/@QuantStack/open-software-packaging-for-science-61cecee7fc23).\nThe ecosystem also consists of `quetz`, an open source `conda` package server and `boa`, a fast `conda` package builder.\n\n\nPlease refer to the [`mamba` and `micromamba` installation guide](https://mamba.readthedocs.io/en/latest/installation.html) in the documentation.\n\n\n`mamba` and `micromamba` come with features on top of stock `conda`.\n\n\nTo efficiently query repositories and query package dependencies you can use `mamba repoquery` or `micromamba repoquery`.\nSee the [repoquery documentation](https://mamba.readthedocs.io/en/latest/user_guide/mamba.html#repoquery) for details.\n\n\n`micromamba` can be used to install lock files generated by [conda-lock](https://conda-incubator.github.io/conda-lock/) without having to install `conda-lock`. Simply invoke e.g. `micromamba create -n my-env -f conda-lock.yml` with an environment lockfile named `*-lock.yml` or `*-lock.yaml`.\n" -summary: "A fast drop-in alternative to conda, using libsolv for dependency resolution" -license: BSD-3-Clause -license_family: BSD dev_url: "https://github.com/mamba-org/mamba" home: "https://github.com/mamba-org/mamba" -channels: - - "https://conda.anaconda.org/conda-forge" +license: BSD-3-Clause +license_family: BSD +summary: "A fast drop-in alternative to conda, using libsolv for dependency resolution" diff --git a/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__index__test__reconstruct_index_json.snap b/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__index__test__reconstruct_index_json.snap index 6a8945af3..411d5584b 100644 --- a/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__index__test__reconstruct_index_json.snap +++ b/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__index__test__reconstruct_index_json.snap @@ -2,14 +2,14 @@ source: crates/rattler_conda_types/src/package/index.rs expression: "IndexJson::from_package_directory(package_dir.path()).unwrap()" --- -name: zlib -version: 1.2.8 +arch: x86_64 build: vc10_0 build_number: 0 -arch: x86_64 -platform: win +features: vc10 license: "zlib (http://zlib.net/zlib_license.html)" license_family: Other -features: vc10 +name: zlib +platform: win subdir: win-64 +version: 1.2.8 diff --git a/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__index__test__reconstruct_index_json_with_symlinks.snap b/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__index__test__reconstruct_index_json_with_symlinks.snap index 6b8c29af0..c1d414bcc 100644 --- a/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__index__test__reconstruct_index_json_with_symlinks.snap +++ b/crates/rattler_conda_types/src/package/snapshots/rattler_conda_types__package__index__test__reconstruct_index_json_with_symlinks.snap @@ -2,13 +2,13 @@ source: crates/rattler_conda_types/src/package/index.rs expression: "IndexJson::from_package_directory(&package_dir).unwrap()" --- -name: zlib -version: 1.2.8 +arch: x86_64 build: "3" build_number: 3 -arch: x86_64 -platform: linux license: "zlib (http://zlib.net/zlib_license.html)" license_family: Other +name: zlib +platform: linux subdir: linux-64 +version: 1.2.8 diff --git a/crates/rattler_macros/src/lib.rs b/crates/rattler_macros/src/lib.rs index 28ec3b7b8..c1de153cc 100644 --- a/crates/rattler_macros/src/lib.rs +++ b/crates/rattler_macros/src/lib.rs @@ -2,6 +2,10 @@ use proc_macro::TokenStream; use quote::quote_spanned; use syn::{parse_macro_input, Data, DeriveInput, Fields, FieldsNamed, Ident}; +/// Macro for enforcing alphabetical order on Structs and Enums. +/// +/// This macro will not automatically sort it for you; rather, it will fail to compile if the +/// fields are not defined alphabetically. #[proc_macro_attribute] pub fn sorted(_attr: TokenStream, item: TokenStream) -> TokenStream { let out = item.clone();