Skip to content

Commit

Permalink
Add checksum field to PackageLock and add Builder pattern there (#…
Browse files Browse the repository at this point in the history
…909)

**Stack**:
- #912
- #911
- #910
- #909⚠️ *Part of a stack created by [spr](https://github.com/ejoffe/spr). Do
not merge manually using the UI - doing so may have unexpected results.*

Signed-off-by: Marek Kaput <marek.kaput@swmansion.com>
  • Loading branch information
mkaput authored Nov 20, 2023
1 parent 0106995 commit bafa992
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 59 deletions.
2 changes: 1 addition & 1 deletion scarb/src/core/checksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
use sha2::Digest as _;
use tokio::io::{AsyncRead, AsyncReadExt};

#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(try_from = "String", into = "String")]
pub struct Checksum([u8; 32]);

Expand Down
123 changes: 67 additions & 56 deletions scarb/src/core/lockfile.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::collections::BTreeSet;
use std::str::FromStr;

use anyhow::{anyhow, Context, Result};
use semver::Version;
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use std::collections::BTreeSet;
use std::str::FromStr;
use toml_edit::Document;
use typed_builder::TypedBuilder;

use crate::core::{ManifestDependency, PackageId, PackageName, Resolve, SourceId};
use crate::core::{Checksum, ManifestDependency, PackageId, PackageName, Resolve, SourceId};

const HEADER: &str = "# Code generated by scarb DO NOT EDIT.";

Expand All @@ -29,13 +31,21 @@ pub struct Lockfile {
pub packages: BTreeSet<PackageLock>,
}

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, TypedBuilder)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub struct PackageLock {
pub name: PackageName,
pub version: Version,

#[builder(default)]
#[serde(skip_serializing_if = "skip_path_source_id")]
pub source: Option<SourceId>,

#[builder(default)]
pub checksum: Option<Checksum>,

#[builder(default, setter(into))]
#[serde(default = "BTreeSet::new")]
#[serde(skip_serializing_if = "BTreeSet::is_empty")]
pub dependencies: BTreeSet<PackageName>,
Expand All @@ -62,8 +72,12 @@ impl Lockfile {
let deps = resolve
.package_dependencies(package)
.filter(include_package)
.map(|dep| dep.name.clone());
PackageLock::new(&package, deps)
.map(|dep| dep.name.clone())
.collect::<BTreeSet<_>>();
PackageLock::builder()
.use_package_id(package)
.dependencies(deps)
.build()
});
Self::new(packages)
}
Expand Down Expand Up @@ -126,14 +140,12 @@ impl FromStr for Lockfile {
}
}

impl PackageLock {
pub fn new(package: &PackageId, dependencies: impl Iterator<Item = PackageName>) -> Self {
Self {
name: package.name.clone(),
version: package.version.clone(),
source: Some(package.source_id),
dependencies: dependencies.collect(),
}
type UsePackageIdFields = ((PackageName,), (Version,), (Option<SourceId>,), (), ());
impl PackageLockBuilder {
pub fn use_package_id(self, package_id: PackageId) -> PackageLockBuilder<UsePackageIdFields> {
self.name(package_id.name.clone())
.version(package_id.version.clone())
.source(Some(package_id.source_id))
}
}

Expand All @@ -153,60 +165,59 @@ impl TryFrom<PackageLock> for PackageId {

#[cfg(test)]
mod tests {
use crate::core::lockfile::{Lockfile, PackageLock};
use crate::core::{PackageId, PackageName, SourceId};
use std::str::FromStr;

use indoc::indoc;
use expect_test::expect;
use semver::Version;
use snapbox::assert_eq;
use std::str::FromStr;

use crate::core::lockfile::{Lockfile, PackageLock};
use crate::core::{Checksum, PackageName, SourceId};

#[test]
fn simple() {
let pkg1 = PackageLock::new(
&PackageId::new(
"first".try_into().unwrap(),
Version::parse("1.0.0").unwrap(),
SourceId::default_registry(),
),
vec![PackageName::new("fourth")].into_iter(),
);

let pkg2 = PackageLock {
name: "second".try_into().unwrap(),
version: Version::parse("1.0.0").unwrap(),
source: None,
dependencies: vec![PackageName::new("fourth")].into_iter().collect(),
};

let pkg3 = PackageLock::new(
&PackageId::new(
PackageName::new("third"),
Version::parse("2.1.0").unwrap(),
SourceId::mock_git(),
),
vec![].into_iter(),
);

let pkg4 = PackageLock::new(
&PackageId::new(
PackageName::new("fourth"),
Version::parse("80.0.85").unwrap(),
SourceId::default_registry(),
),
vec![PackageName::new("third")].into_iter(),
);
let checksum = Checksum::parse(
"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
)
.unwrap();

let pkg1 = PackageLock::builder()
.name(PackageName::new("first"))
.version(Version::parse("1.0.0").unwrap())
.source(Some(SourceId::default_registry()))
.checksum(Some(checksum))
.dependencies([PackageName::new("fourth")])
.build();

let pkg2 = PackageLock::builder()
.name(PackageName::new("second"))
.version(Version::parse("1.0.0").unwrap())
.dependencies([PackageName::new("fourth")])
.build();

let pkg3 = PackageLock::builder()
.name(PackageName::new("third"))
.version(Version::parse("2.1.0").unwrap())
.source(Some(SourceId::mock_git()))
.build();

let pkg4 = PackageLock::builder()
.name(PackageName::new("fourth"))
.version(Version::parse("80.0.85").unwrap())
.source(Some(SourceId::default_registry()))
.dependencies([PackageName::new("third")])
.build();

let lock = Lockfile::new(vec![pkg1, pkg2, pkg3, pkg4]);

let serialized = indoc! {r#"
let serialized = expect![[r#"
# Code generated by scarb DO NOT EDIT.
version = 1
[[package]]
name = "first"
version = "1.0.0"
source = "registry+https://there-is-no-default-registry-yet.com/"
checksum = "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
dependencies = [
"fourth",
]
Expand All @@ -230,10 +241,10 @@ mod tests {
name = "third"
version = "2.1.0"
source = "git+https://github.com/starkware-libs/cairo.git?tag=test"
"#};
"#]];

assert_eq(serialized, lock.render().unwrap());
let deserialized = Lockfile::from_str(serialized).unwrap();
serialized.assert_eq(&lock.render().unwrap());
let deserialized = Lockfile::from_str(serialized.data()).unwrap();
assert_eq!(lock, deserialized);
}

Expand Down
9 changes: 7 additions & 2 deletions scarb/src/core/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,13 @@ pub(crate) mod mock {
#[allow(unused_imports)]
use $crate::core::registry::mock;
let package_id = $crate::core::PackageId::from_display_str($p).unwrap();
let dependencies: Vec<$crate::core::PackageName> = mock::pkg_names![$($d),*].iter().cloned().collect();
$crate::core::lockfile::PackageLock::new(&package_id, dependencies.into_iter())
let dependencies: ::std::collections::BTreeSet<$crate::core::PackageName> = (
mock::pkg_names![$($d),*].iter().cloned().collect()
);
$crate::core::lockfile::PackageLock::builder()
.use_package_id(package_id)
.dependencies(dependencies)
.build()
}};
}

Expand Down

0 comments on commit bafa992

Please sign in to comment.