Skip to content

Commit

Permalink
feat: add extra field (#811)
Browse files Browse the repository at this point in the history
Needed for  conda-forge/conda-smithy#2034

---------

Co-authored-by: Bas Zalmstra <zalmstra.bas@gmail.com>
  • Loading branch information
nichmor and baszalmstra committed Aug 13, 2024
1 parent 28c4d81 commit f8abd72
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 14 deletions.
5 changes: 4 additions & 1 deletion crates/rattler_conda_types/src/match_spec/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1276,7 +1276,10 @@ mod tests {
channel.unwrap(),
Channel::from_str(expected_channel.unwrap(), &channel_config()).unwrap()
);
assert_eq!(subdir, expected_subdir.map(|s| s.to_string()));
assert_eq!(
subdir,
expected_subdir.map(std::string::ToString::to_string)
);
}
}
}
69 changes: 69 additions & 0 deletions crates/rattler_conda_types/src/package/about.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use std::collections::BTreeMap;
use std::{io::Error, path::Path};

use crate::{
package::PackageFile,
utils::serde::{LossyUrl, MultiLineString, VecSkipNone},
};

use serde::{Deserialize, Serialize};
use serde_json::Value;
use serde_with::{serde_as, skip_serializing_none, OneOrMany, Same};

use url::Url;
Expand Down Expand Up @@ -41,6 +44,10 @@ pub struct AboutJson {
)]
pub doc_url: Vec<Url>,

/// Extra metadata that was passed during the build
#[serde(skip_serializing_if = "BTreeMap::is_empty", default)]
pub extra: BTreeMap<String, Value>,

/// URL to the homepage of the package
#[serde(skip_serializing_if = "Vec::is_empty", default)]
#[serde_as(
Expand Down Expand Up @@ -77,6 +84,13 @@ impl PackageFile for AboutJson {

#[cfg(test)]
mod test {

use std::collections::BTreeMap;

use insta::assert_snapshot;
use serde_json::json;
use url::Url;

use super::{AboutJson, PackageFile};

#[test]
Expand Down Expand Up @@ -113,4 +127,59 @@ mod test {

insta::assert_yaml_snapshot!(AboutJson::from_package_directory(&package_dir).unwrap());
}

#[test]
fn test_extra_field_is_recorded_when_present() {
// Define a sample AboutJson instance with extra field populated
let mut extra_metadata = BTreeMap::default();
extra_metadata.insert("flow_id".to_string(), json!("2024.08.13".to_string()));
extra_metadata.insert("some_values".to_string(), json!({ "an": "object" }));

let about = AboutJson {
channels: vec!["conda-forge".to_string()],
description: Some("A sample package".to_string()),
dev_url: vec![],
doc_url: vec![],
extra: extra_metadata.clone(),
home: vec![],
license: Some("MIT".to_string()),
license_family: Some("MIT".to_string()),
source_url: Some(Url::parse("https://github.com/some-user/sample").unwrap()),
summary: Some("This is a test package".to_string()),
};

// Serialize the AboutJson instance to JSON
let serialized = serde_json::to_string(&about).expect("Serialization failed");

// Deserialize the JSON back to an AboutJson instance
let deserialized: AboutJson =
serde_json::from_str(&serialized).expect("Deserialization failed");

// Verify that the deserialized instance matches the original
assert_snapshot!(serialized);
assert_eq!(about, deserialized);
}

#[test]
fn test_extra_field_is_skipped() {
// Define a sample AboutJson instance with extra field populated
let about = AboutJson {
channels: vec!["conda-forge".to_string()],
description: Some("A sample package".to_string()),
dev_url: vec![],
doc_url: vec![],
extra: BTreeMap::default(),
home: vec![],
license: Some("MIT".to_string()),
license_family: Some("MIT".to_string()),
source_url: Some(Url::parse("https://github.com/some-user/sample").unwrap()),
summary: Some("This is a test package".to_string()),
};

// Serialize the AboutJson instance to JSON
let serialized = serde_json::to_string(&about).expect("Serialization failed");

// Verify that the deserialized instance matches the original
assert_snapshot!(serialized);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/rattler_conda_types/src/package/about.rs
expression: serialized
---
{"channels":["conda-forge"],"description":"A sample package","extra":{"flow_id":"2024.08.13","some_values":{"an":"object"}},"license":"MIT","license_family":"MIT","source_url":"https://github.com/some-user/sample","summary":"This is a test package"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/rattler_conda_types/src/package/about.rs
expression: serialized
---
{"channels":["conda-forge"],"description":"A sample package","license":"MIT","license_family":"MIT","source_url":"https://github.com/some-user/sample","summary":"This is a test package"}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,22 @@ channels:
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"
dev_url: "https://github.com/conda/conda"
doc_url: "https://docs.conda.io/projects/conda/en/stable/"
extra:
copy_test_source_files: true
final: true
recipe-maintainers:
- isuruf
- jakirkham
- kalefranz
- mingwandroid
- msarahan
- mwcraig
- ocefpaf
- patricksnape
- pelson
- scopatz
- mbargull
- jezdez
home: "https://conda.io/"
license: BSD-3-Clause
summary: "OS-agnostic, system-level binary package and environment manager."

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ 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"
dev_url: "https://github.com/mamba-org/mamba"
extra:
copy_test_source_files: true
final: true
parent_recipe:
name: mamba-split
path: "D:\\a\\1\\s\\recipe"
version: ""
recipe-maintainers:
- adriendelsalle
- SylvainCorlay
- JohanMabille
- wolfv
- ericmjl
home: "https://github.com/mamba-org/mamba"
license: BSD-3-Clause
license_family: BSD
Expand Down
13 changes: 2 additions & 11 deletions crates/rattler_conda_types/src/repo_data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub mod sharded;
mod topological_sort;

use std::{
collections::{BTreeMap, BTreeSet},
collections::BTreeSet,
fmt::{Display, Formatter},
path::Path,
};
Expand All @@ -19,6 +19,7 @@ use serde_with::{serde_as, skip_serializing_none, OneOrMany};
use thiserror::Error;
use url::Url;

use crate::utils::serde::sort_map_alphabetically;
use crate::utils::url::add_trailing_slash;
use crate::{
build_spec::BuildNumber,
Expand Down Expand Up @@ -423,16 +424,6 @@ impl PackageRecord {
}
}

fn sort_map_alphabetically<T: Serialize, S: serde::Serializer>(
value: &FxHashMap<String, T>,
serializer: S,
) -> Result<S::Ok, S::Error> {
value
.iter()
.collect::<BTreeMap<_, _>>()
.serialize(serializer)
}

fn sort_set_alphabetically<S: serde::Serializer>(
value: &FxHashSet<String>,
serializer: S,
Expand Down
14 changes: 13 additions & 1 deletion crates/rattler_conda_types/src/utils/serde.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use chrono::{DateTime, Utc};
use fxhash::FxHashMap;
use itertools::Itertools;
use serde::de::Error as _;
use serde::ser::Error;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_with::de::DeserializeAsWrap;
use serde_with::ser::SerializeAsWrap;
use serde_with::{DeserializeAs, SerializeAs};
use std::collections::HashSet;
use std::collections::{BTreeMap, HashSet};
use std::hash::{BuildHasher, Hash};
use std::marker::PhantomData;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -200,3 +201,14 @@ impl<T: Ord, TAs: SerializeAs<T>> SerializeAs<Vec<T>> for Ordered<TAs> {

/// A helper struct to deserialize types from a string without checking the string.
pub struct DeserializeFromStrUnchecked;

/// A helper function used to sort map alphabetically when serializing.
pub(crate) fn sort_map_alphabetically<T: Serialize, S: serde::Serializer>(
value: &FxHashMap<String, T>,
serializer: S,
) -> Result<S::Ok, S::Error> {
value
.iter()
.collect::<BTreeMap<_, _>>()
.serialize(serializer)
}

0 comments on commit f8abd72

Please sign in to comment.