From b6f0a3644640cb0525339893aa8d8502c0e6df05 Mon Sep 17 00:00:00 2001 From: Marek Kaput Date: Mon, 20 Nov 2023 15:56:36 +0100 Subject: [PATCH] Store package checksum in `Summary` (#910) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Stack**: - #912 - #911 - #910 ⬅ ⚠️ *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 --- scarb/src/core/manifest/summary.rs | 11 +++++++++-- scarb/src/core/package/mod.rs | 6 +++++- scarb/src/core/registry/client/cache.rs | 10 ++++++---- scarb/src/sources/registry.rs | 22 ++++++++++++++++------ 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/scarb/src/core/manifest/summary.rs b/scarb/src/core/manifest/summary.rs index 7e84d74ac..591fbeac3 100644 --- a/scarb/src/core/manifest/summary.rs +++ b/scarb/src/core/manifest/summary.rs @@ -8,7 +8,8 @@ use typed_builder::TypedBuilder; #[cfg(doc)] use crate::core::Manifest; use crate::core::{ - DepKind, DependencyVersionReq, ManifestDependency, PackageId, PackageName, SourceId, TargetKind, + Checksum, DepKind, DependencyVersionReq, ManifestDependency, PackageId, PackageName, SourceId, + TargetKind, }; /// Subset of a [`Manifest`] that contains only the most important information about a package. @@ -17,7 +18,7 @@ use crate::core::{ #[derive(Clone, Debug)] pub struct Summary(Arc); -#[derive(TypedBuilder, Debug)] +#[derive(TypedBuilder, Clone, Debug)] #[builder(builder_type(name = SummaryBuilder))] #[builder(builder_method(vis = ""))] #[builder(build_method(into = Summary))] @@ -29,6 +30,8 @@ pub struct SummaryInner { pub target_kinds: HashSet, #[builder(default = false)] pub no_core: bool, + #[builder(default)] + pub checksum: Option, } impl Deref for Summary { @@ -51,6 +54,10 @@ impl Summary { SummaryInner::builder() } + pub fn set_checksum(&mut self, cksum: Checksum) { + Arc::make_mut(&mut self.0).checksum = Some(cksum); + } + pub fn full_dependencies(&self) -> impl Iterator { self.dependencies.iter().chain(self.implicit_dependencies()) } diff --git a/scarb/src/core/package/mod.rs b/scarb/src/core/package/mod.rs index 7b5dc0fd7..e88a8c356 100644 --- a/scarb/src/core/package/mod.rs +++ b/scarb/src/core/package/mod.rs @@ -20,7 +20,7 @@ mod name; #[derive(Clone, Debug)] pub struct Package(Arc); -#[derive(Debug)] +#[derive(Clone, Debug)] #[non_exhaustive] pub struct PackageInner { pub id: PackageId, @@ -111,6 +111,10 @@ impl Package { let structured = toml_value.clone().try_into()?; Ok(structured) } + + pub fn manifest_mut(&mut self) -> &mut Manifest { + &mut Arc::make_mut(&mut self.0).manifest + } } impl WithManifestPath for Package { diff --git a/scarb/src/core/registry/client/cache.rs b/scarb/src/core/registry/client/cache.rs index a76a90009..1837eeaeb 100644 --- a/scarb/src/core/registry/client/cache.rs +++ b/scarb/src/core/registry/client/cache.rs @@ -139,14 +139,16 @@ impl<'c> RegistryClientCache<'c> { pub async fn download_and_verify_with_cache( &self, package: PackageId, - ) -> Result { + ) -> Result<(FileLockGuard, Checksum)> { // Skip downloading if the package already has been. if self.is_package_downloaded(package).await { trace!("found cached archive which is not empty, skipping download"); let tarball_name = package.tarball_name(); - return self + let file = self .dl_fs - .open_rw(&tarball_name, &tarball_name, self.config); + .open_rw(&tarball_name, &tarball_name, self.config)?; + let checksum = self.get_record_maybe_uncached(package).await?.checksum; + return Ok((file, checksum)); } let create_scratch_file: CreateScratchFileCallback = Box::new({ @@ -167,7 +169,7 @@ impl<'c> RegistryClientCache<'c> { let checksum = self.get_record_maybe_uncached(package).await?.checksum; let file = self.verify_checksum(package, &checksum, file).await?; trace!("package archive file has valid checksum: {checksum}"); - Ok(file) + Ok((file, checksum)) } } } diff --git a/scarb/src/sources/registry.rs b/scarb/src/sources/registry.rs index 42af66b2d..25486e0fa 100644 --- a/scarb/src/sources/registry.rs +++ b/scarb/src/sources/registry.rs @@ -15,8 +15,8 @@ use crate::core::registry::index::IndexRecord; use crate::core::registry::package_source_store::PackageSourceStore; use crate::core::source::Source; use crate::core::{ - Config, DependencyVersionReq, ManifestDependency, Package, PackageId, SourceId, Summary, - TargetKind, + Checksum, Config, DependencyVersionReq, ManifestDependency, Package, PackageId, SourceId, + Summary, TargetKind, }; use crate::flock::FileLockGuard; use crate::sources::PathSource; @@ -107,6 +107,7 @@ impl<'c> Source for RegistrySource<'c> { .dependencies(dependencies) .target_kinds(HashSet::from_iter([TargetKind::LIB])) .no_core(record.no_core) + .checksum(Some(record.checksum.clone())) .build() }; @@ -123,13 +124,13 @@ impl<'c> Source for RegistrySource<'c> { #[tracing::instrument(level = "trace", skip(self))] async fn download(&self, id: PackageId) -> Result { - let archive = self + let (archive, checksum) = self .client .download_and_verify_with_cache(id) .await .with_context(|| format!("failed to download package: {id}"))?; - self.load_package(id, archive).await + self.load_package(id, archive, checksum).await } } @@ -138,7 +139,12 @@ impl<'c> RegistrySource<'c> { /// /// This method extracts the tarball into cache directory, and then loads it using /// suitably configured [`PathSource`]. - async fn load_package(&self, id: PackageId, archive: FileLockGuard) -> Result { + async fn load_package( + &self, + id: PackageId, + archive: FileLockGuard, + checksum: Checksum, + ) -> Result { self.config .ui() .verbose(Status::new("Unpacking", &id.to_string())); @@ -147,7 +153,11 @@ impl<'c> RegistrySource<'c> { let path = self.package_sources.extract(id, archive).await?; let path_source = PathSource::recursive_at(&path, self.source_id, self.config); - path_source.download(id).await + let mut package = path_source.download(id).await?; + + package.manifest_mut().summary.set_checksum(checksum); + + Ok(package) } }