diff --git a/crates/binstalk/src/ops/resolve.rs b/crates/binstalk/src/ops/resolve.rs index b8e02374..e0c5883e 100644 --- a/crates/binstalk/src/ops/resolve.rs +++ b/crates/binstalk/src/ops/resolve.rs @@ -8,6 +8,7 @@ use std::{ }; use binstalk_fetchers::FETCHER_GH_CRATE_META; +use binstalk_types::crate_info::{CrateSource, SourceType}; use compact_str::{CompactString, ToCompactString}; use itertools::Itertools; use leon::Template; @@ -15,6 +16,7 @@ use maybe_owned::MaybeOwned; use semver::{Version, VersionReq}; use tokio::task::spawn_blocking; use tracing::{debug, error, info, instrument, warn}; +use url::Url; use crate::{ bins, @@ -195,6 +197,7 @@ async fn resolve_inner( new_version: package_info.version, name: package_info.name, version_req: version_req_str, + source: package_info.source, bin_files, }))); } else { @@ -365,6 +368,7 @@ struct PackageInfo { binaries: Vec, name: CompactString, version_str: CompactString, + source: CrateSource, version: Version, repo: Option, overrides: BTreeMap, @@ -387,43 +391,70 @@ impl PackageInfo { use CargoTomlFetchOverride::*; // Fetch crate via crates.io, git, or use a local manifest path - let manifest = match opts.cargo_toml_fetch_override.as_ref() { - Some(Path(manifest_path)) => { - let manifest_path = manifest_path.clone(); - let name = name.clone(); + let (manifest, source) = match opts.cargo_toml_fetch_override.as_ref() { + Some(Path(manifest_path)) => ( + spawn_blocking({ + let manifest_path = manifest_path.clone(); + let name = name.clone(); - spawn_blocking(move || load_manifest_path(manifest_path, &name)).await?? - } + move || load_manifest_path(manifest_path, &name) + }) + .await??, + CrateSource { + source_type: SourceType::Path, + url: MaybeOwned::Owned(Url::parse(&format!( + "file://{}", + manifest_path.display() + ))?), + }, + ), #[cfg(feature = "git")] Some(Git(git_url)) => { use crate::helpers::git::{GitCancellationToken, Repository as GitRepository}; - let git_url = git_url.clone(); - let name = name.clone(); let cancellation_token = GitCancellationToken::default(); // Cancel git operation if the future is cancelled (dropped). let cancel_on_drop = cancellation_token.clone().cancel_on_drop(); - let ret = spawn_blocking(move || { - let dir = tempfile::TempDir::new()?; - GitRepository::shallow_clone(git_url, dir.as_ref(), Some(cancellation_token))?; + let (ret, commit_hash) = spawn_blocking({ + let git_url = git_url.clone(); + let name = name.clone(); + move || { + let dir = tempfile::TempDir::new()?; + let repo = GitRepository::shallow_clone( + git_url, + dir.as_ref(), + Some(cancellation_token), + )?; - load_manifest_from_workspace(dir.as_ref(), &name).map_err(BinstallError::from) + Ok::<_, BinstallError>(( + load_manifest_from_workspace(dir.as_ref(), &name) + .map_err(BinstallError::from)?, + repo.get_head_commit_hash()?, + )) + } }) .await??; // Git operation done, disarm it cancel_on_drop.disarm(); - ret + ( + ret, + CrateSource { + source_type: SourceType::Git, + url: MaybeOwned::Owned(Url::parse(&format!("{git_url}#{commit_hash}"))?), + }, + ) } - None => { + None => ( Box::pin( opts.registry .fetch_crate_matched(client, &name, version_req), ) - .await? - } + .await?, + CrateSource::cratesio_registry(), + ), }; let Some(mut package) = manifest.package else { @@ -479,6 +510,7 @@ impl PackageInfo { meta, binaries, name, + source, version_str: new_version_str, version: new_version, repo: package.repository().map(ToString::to_string), diff --git a/crates/binstalk/src/ops/resolve/resolution.rs b/crates/binstalk/src/ops/resolve/resolution.rs index 9c149dea..75d4f398 100644 --- a/crates/binstalk/src/ops/resolve/resolution.rs +++ b/crates/binstalk/src/ops/resolve/resolution.rs @@ -22,6 +22,7 @@ pub struct ResolutionFetch { pub name: CompactString, pub version_req: CompactString, pub bin_files: Vec, + pub source: CrateSource, } pub struct ResolutionSource { @@ -84,7 +85,7 @@ impl ResolutionFetch { name: self.name, version_req: self.version_req, current_version: self.new_version, - source: CrateSource::cratesio_registry(), + source: self.source, target: self.fetcher.target().to_compact_string(), bins: self .bin_files diff --git a/e2e-tests/git.sh b/e2e-tests/git.sh index 8058d49c..51a0d913 100644 --- a/e2e-tests/git.sh +++ b/e2e-tests/git.sh @@ -45,17 +45,25 @@ cp -r manifests/workspace/* "$GIT" cd "$GIT" git add . git commit -m 'Update to workspace' + git rev-parse HEAD ) +COMMIT_HASH="$(cd "$GIT" && git rev-parse HEAD)" -# Install binaries using `--git` +# Install cargo-binstall using `--git` "./$1" binstall --force --git "file://$GIT" --no-confirm cargo-binstall test_cargo_binstall_install -# Install binaries using `--git` +cat "$CARGO_HOME/.crates.toml" +grep -F "cargo-binstall 0.12.0 (git+file://$GIT#$COMMIT_HASH)" <"$CARGO_HOME/.crates.toml" + +# Install cargo-binstall using `--git` "./$1" binstall --force --git "file://$GIT" --no-confirm cargo-watch cargo_watch_version="$(cargo watch -V)" echo "$cargo_watch_version" [ "$cargo_watch_version" = "cargo-watch 8.4.0" ] + +cat "$CARGO_HOME/.crates.toml" +grep -F "cargo-watch 8.4.0 (git+file://$GIT#$COMMIT_HASH)" <"$CARGO_HOME/.crates.toml" diff --git a/e2e-tests/manifest-path.sh b/e2e-tests/manifest-path.sh index 88cefad6..35f2a1b7 100755 --- a/e2e-tests/manifest-path.sh +++ b/e2e-tests/manifest-path.sh @@ -19,3 +19,6 @@ cargo_binstall_version="$(cargo binstall -V)" echo "$cargo_binstall_version" [ "$cargo_binstall_version" = "cargo-binstall 0.12.0" ] + +cat "$CARGO_HOME/.crates.toml" +grep -F "cargo-binstall 0.12.0 (path+file://manifests/github-test-Cargo.toml)" <"$CARGO_HOME/.crates.toml"