Skip to content

Commit

Permalink
feat: only copy directories if necessary
Browse files Browse the repository at this point in the history
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
  • Loading branch information
rvolosatovs committed Oct 3, 2024
1 parent 6c955e3 commit eb7c845
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 59 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wit-deps-cli"
version = "0.3.7"
version = "0.4.0"
description = "WIT dependency manager"

authors.workspace = true
Expand Down Expand Up @@ -56,4 +56,4 @@ tracing = { version = "0.1", default-features = false }
tracing-subscriber = { version = "0.3", default-features = false }
url = { version = "2", default-features = false }
wit-bindgen = { version = "0.7", default-features = false }
wit-deps = { path = "./crates/wit-deps", version = "0.3.2" }
wit-deps = { path = "./crates/wit-deps", version = "0.4" }
2 changes: 1 addition & 1 deletion crates/wit-deps/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wit-deps"
version = "0.3.2"
version = "0.4.0"
description = "WIT dependency management"
readme = "../../README.md"

Expand Down
134 changes: 80 additions & 54 deletions crates/wit-deps/src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,94 @@ impl Entry {
reqwest::Client::new()
};

match self {
let entry = if let Some(LockEntry {
source,
digest: ldigest,
deps: ldeps,
}) = lock
{
let deps = if ldeps.is_empty() {
Ok(HashMap::default())
} else {
let base = out
.parent()
.with_context(|| format!("`{}` does not have a parent", out.display()))?;
lock_deps(ldeps.iter().cloned().map(|id| {
let path = base.join(&id);
(id, path)
}))
.await
};
match (LockEntry::digest(out).await, source, deps) {
(Ok(digest), Some(source), Ok(deps)) if digest == *ldigest => {
// NOTE: Manually deleting transitive dependencies of this
// dependency from `dst` is considered user error
// TODO: Check that transitive dependencies are in sync
match (self, source) {
(Self::Url { url, .. }, LockEntrySource::Url(lurl)) if url == *lurl => {
debug!("`{}` is already up-to-date, skip fetch", out.display());
return Ok((
LockEntry::new(
Some(LockEntrySource::Url(url)),
digest,
deps.keys().cloned().collect(),
),
deps,
));
}
(Self::Path(path), LockEntrySource::Path(lpath)) if path == *lpath => {
debug!("`{}` is already up-to-date, skip copy", out.display());
return Ok((
LockEntry::new(
Some(LockEntrySource::Path(path)),
digest,
deps.keys().cloned().collect(),
),
deps,
));
}
(entry, _) => {
debug!("source mismatch");
entry
}
}
}
(Ok(digest), _, _) => {
debug!(
"`{}` is out-of-date (sha256: {})",
out.display(),
hex::encode(digest.sha256)
);
self
}
(Err(e), _, _) if e.kind() == std::io::ErrorKind::NotFound => {
debug!("locked dependency for `{}` missing", out.display());
self
}
(Err(e), _, _) => {
error!(
"failed to compute dependency digest for `{}`: {e}",
out.display()
);
self
}
}
} else {
self
};
match entry {
Self::Path(path) => {
let dst = at.map(|at| at.as_ref().join(&path));
let deps = copy_wits(&dst.as_ref().unwrap_or(&path), out, skip_deps).await?;
let src = at.map(|at| at.as_ref().join(&path));
let src = src.as_ref().unwrap_or(&path);
let deps = copy_wits(src, out, skip_deps).await?;
trace!(?deps, "copied WIT definitions to `{}`", out.display());
let deps = lock_deps(deps).await?;
trace!(
?deps,
"locked transitive dependencies of `{}`",
out.display()
);
let digest = LockEntry::digest(&dst.as_ref().unwrap_or(&path)).await?;
let digest = LockEntry::digest(out).await?;
Ok((
LockEntry::new(
Some(LockEntrySource::Path(path)),
Expand All @@ -237,56 +313,6 @@ impl Entry {
sha256,
sha512,
} => {
if let Some(LockEntry {
source,
digest: ldigest,
deps: ldeps,
}) = lock
{
let deps = if ldeps.is_empty() {
Ok(HashMap::default())
} else {
let base = out.parent().with_context(|| {
format!("`{}` does not have a parent", out.display())
})?;
lock_deps(ldeps.iter().cloned().map(|id| {
let path = base.join(&id);
(id, path)
}))
.await
};
match (LockEntry::digest(out).await, source, deps) {
(Ok(digest), Some(LockEntrySource::Url(lurl)), Ok(deps))
if digest == *ldigest && url == *lurl =>
{
debug!("`{}` is already up-to-date, skip fetch", out.display());
// NOTE: Manually deleting transitive dependencies of this
// dependency from `dst` is considered user error
// TODO: Check that transitive dependencies are in sync
return Ok((
LockEntry::new(
Some(LockEntrySource::Url(url)),
digest,
deps.keys().cloned().collect(),
),
deps,
));
}
(Ok(digest), _, _) => {
debug!(
"`{}` is out-of-date (sha256: {})",
out.display(),
hex::encode(digest.sha256)
);
}
(Err(e), _, _) if e.kind() == std::io::ErrorKind::NotFound => {
debug!("locked dependency for `{url}` missing");
}
(Err(e), _, _) => {
error!("failed to compute dependency digest for `{url}`: {e}");
}
}
}
let cache = if let Some(cache) = cache {
match cache.get(&url).await {
Err(e) => error!("failed to get `{url}` from cache: {e}"),
Expand Down

0 comments on commit eb7c845

Please sign in to comment.