From 9a953e00a11f829bfae882c314ece41426bcfc8c Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Thu, 28 Nov 2024 07:35:17 -0600 Subject: [PATCH] fix(spm): git proxy config (#3264) Fixes #3263 --- src/backend/spm.rs | 33 ++++++++++++++++----------------- src/git.rs | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/backend/spm.rs b/src/backend/spm.rs index aa2360ef6..fe446301f 100644 --- a/src/backend/spm.rs +++ b/src/backend/spm.rs @@ -3,15 +3,14 @@ use crate::backend::Backend; use crate::cli::args::BackendArg; use crate::cmd::CmdLineRunner; use crate::config::Settings; +use crate::git::Git; use crate::install_context::InstallContext; use crate::toolset::ToolVersion; use crate::{file, github}; use eyre::WrapErr; -use git2::Repository; use serde::de::{MapAccess, Visitor}; use serde::Deserializer; use serde_derive::Deserialize; -use std::env::temp_dir; use std::fmt::{self, Debug}; use std::path::PathBuf; use url::Url; @@ -62,7 +61,7 @@ impl Backend for SPMBackend { } else { tv.version.clone() }; - let repo_dir = self.clone_package_repo(&repo, &revision)?; + let repo_dir = self.clone_package_repo(ctx, &tv, &repo, &revision)?; let executables = self.get_executable_names(&repo_dir)?; if executables.is_empty() { @@ -88,24 +87,24 @@ impl SPMBackend { fn clone_package_repo( &self, + ctx: &InstallContext, + tv: &ToolVersion, package_repo: &SwiftPackageRepo, revision: &str, ) -> Result { - let tmp_repo_dir = temp_dir().join("spm").join(package_repo.dir_name(revision)); - file::remove_all(&tmp_repo_dir)?; - file::create_dir_all(tmp_repo_dir.parent().unwrap())?; + let repo = Git::new(tv.cache_path().join(package_repo.dir_name(revision))); + if !repo.exists() { + debug!( + "Cloning swift package repo {} to {}", + package_repo.url.as_str(), + repo.dir.display(), + ); + repo.clone(package_repo.url.as_str(), Some(ctx.pr.as_ref()))?; + } + debug!("Checking out revision: {revision}"); + repo.update(Some(revision.to_string()))?; - debug!( - "Cloning swift package repo: {}, revision: {} to path: {}", - package_repo.url.as_str(), - revision, - tmp_repo_dir.display() - ); - let repo = Repository::clone(package_repo.url.as_str(), &tmp_repo_dir)?; - let (object, reference) = repo.revparse_ext(revision)?; - repo.checkout_tree(&object, None)?; - repo.set_head(reference.unwrap().name().unwrap())?; - Ok(tmp_repo_dir) + Ok(repo.dir) } fn get_executable_names(&self, repo_dir: &PathBuf) -> Result, eyre::Error> { diff --git a/src/git.rs b/src/git.rs index 22e11f2bc..2edd5fae2 100644 --- a/src/git.rs +++ b/src/git.rs @@ -67,6 +67,22 @@ impl Git { pub fn update(&self, gitref: Option) -> Result<(String, String)> { let gitref = gitref.map_or_else(|| self.current_branch(), Ok)?; debug!("updating {} to {}", self.dir.display(), gitref); + if SETTINGS.libgit2 { + if let Ok(repo) = self.repo() { + let mut fetch_options = get_fetch_options()?; + let mut remote = repo.find_remote("origin")?; + remote.fetch(&[&gitref], Some(&mut fetch_options), None)?; + let prev_rev = self.current_sha()?; + let (obj, reference) = repo.revparse_ext(&gitref)?; + repo.checkout_tree(&obj, None)?; + if let Some(reference) = reference.and_then(|r| r.name().map(|s| s.to_string())) { + repo.set_head(&reference)?; + } + let post_rev = self.current_sha()?; + touch_dir(&self.dir)?; + return Ok((prev_rev, post_rev)); + } + } let exec = |cmd: Expression| match cmd.stderr_to_stdout().stdout_capture().unchecked().run() { Ok(res) => { @@ -81,6 +97,7 @@ impl Git { } Err(err) => Err(eyre!("git failed: {cmd:?} {err:#}")), }; + debug!("updating {} to {} with git", self.dir.display(), gitref); exec(git_cmd!( &self.dir, "fetch",