diff --git a/Cargo.lock b/Cargo.lock index 7f09ee4..e972336 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -812,9 +812,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.13" +version = "4.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +checksum = "c937d4061031a6d0c8da4b9a4f98a172fc2976dfb1c19213a9cf7d0d3c837e36" dependencies = [ "clap_builder", "clap_derive", @@ -822,9 +822,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.13" +version = "4.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" +checksum = "85379ba512b21a328adf887e85f7742d12e96eb31f3ef077df4ffc26b506ffed" dependencies = [ "anstream", "anstyle", @@ -1374,14 +1374,14 @@ checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", - "windows-sys 0.52.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] @@ -2382,8 +2382,7 @@ dependencies = [ [[package]] name = "gix-worktree-state" version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ed6205b5f51067a485b11843babcf3304c0799e265a06eb0dde7f69cd85cd8" +source = "git+https://github.com/daimond113/gitoxide?rev=753961c2cc23982a7d8c327dbc68c4dd26bce193#753961c2cc23982a7d8c327dbc68c4dd26bce193" dependencies = [ "bstr", "gix-features", @@ -2985,6 +2984,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", + "redox_syscall", ] [[package]] @@ -3518,7 +3518,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -3897,15 +3897,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.3" @@ -5209,9 +5200,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.10.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72139d247e5f97a3eff96229a7ae85ead5328a39efe76f8bf5a06313d505b6ea" +checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" dependencies = [ "base64 0.22.1", "log", @@ -5621,12 +5612,12 @@ dependencies = [ [[package]] name = "xdg-home" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" +checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 8323537..5a9d3f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,10 @@ indicatif = { version = "0.17.8", optional = true } indicatif-log-bridge = { version = "0.2.2", optional = true } inquire = { version = "0.7.5", optional = true } +# TODO: remove this when a release with https://github.com/Byron/gitoxide/commit/aab78f102113330f96c3140c472aaab0912bc553 is available +[patch.crates-io] +gix-worktree-state = { git = "https://github.com/daimond113/gitoxide", rev = "753961c2cc23982a7d8c327dbc68c4dd26bce193" } + [target.'cfg(target_os = "windows")'.dependencies] winreg = { version = "0.52.0", optional = true } diff --git a/src/cli/scripts.rs b/src/cli/scripts.rs index ca9e242..546712a 100644 --- a/src/cli/scripts.rs +++ b/src/cli/scripts.rs @@ -1,31 +1,94 @@ -use std::fs::remove_dir_all; - +use crate::{ + cli::{config::read_config, home_dir}, + util::authenticate_conn, +}; use anyhow::Context; - +use gix::remote::Direction; use pesde::Project; -use crate::cli::{config::read_config, home_dir}; - -pub fn update_scripts_folder(_project: &Project) -> anyhow::Result<()> { +pub fn update_scripts_folder(project: &Project) -> anyhow::Result<()> { let scripts_dir = home_dir()?.join("scripts"); if scripts_dir.exists() { - // checking out the repository seems to be corrupting the repository contents - // TODO: add actual `git pull`-esque functionality - remove_dir_all(&scripts_dir).context("failed to remove scripts directory")?; - } + let repo = gix::open(&scripts_dir).context("failed to open scripts repository")?; - std::fs::create_dir_all(&scripts_dir).context("failed to create scripts directory")?; + let remote = repo + .find_default_remote(Direction::Fetch) + .context("missing default remote of scripts repository")? + .context("failed to find default remote of scripts repository")?; - let cli_config = read_config()?; + let mut connection = remote + .connect(Direction::Fetch) + .context("failed to connect to default remote of scripts repository")?; - gix::prepare_clone(cli_config.scripts_repo, &scripts_dir) - .context("failed to prepare scripts repository clone")? - .fetch_then_checkout(gix::progress::Discard, &false.into()) - .context("failed to fetch and checkout scripts repository")? - .0 - .main_worktree(gix::progress::Discard, &false.into()) - .context("failed to set scripts repository as main worktree")?; + authenticate_conn(&mut connection, project.auth_config()); + + let results = connection + .prepare_fetch(gix::progress::Discard, Default::default()) + .context("failed to prepare scripts repository fetch")? + .receive(gix::progress::Discard, &false.into()) + .context("failed to receive new scripts repository contents")?; + + let remote_ref = results + .ref_map + .remote_refs + .first() + .context("failed to get remote refs of scripts repository")?; + + let unpacked = remote_ref.unpack(); + let oid = unpacked + .1 + .or(unpacked.2) + .context("couldn't find oid in remote ref")?; + + let tree = repo + .find_object(oid) + .context("failed to find scripts repository tree")? + .peel_to_tree() + .context("failed to peel scripts repository object to tree")?; + + let mut index = gix::index::File::from_state( + gix::index::State::from_tree(&tree.id, &repo.objects, Default::default()) + .context("failed to create index state from scripts repository tree")?, + repo.index_path(), + ); + + let opts = gix::worktree::state::checkout::Options { + overwrite_existing: true, + destination_is_initially_empty: false, + ..Default::default() + }; + + gix::worktree::state::checkout( + &mut index, + repo.work_dir().context("scripts repo is bare")?, + repo.objects + .clone() + .into_arc() + .context("failed to clone objects")?, + &gix::progress::Discard, + &gix::progress::Discard, + &false.into(), + opts, + ) + .context("failed to checkout scripts repository")?; + + index + .write(gix::index::write::Options::default()) + .context("failed to write index")?; + } else { + std::fs::create_dir_all(&scripts_dir).context("failed to create scripts directory")?; + + let cli_config = read_config()?; + + gix::prepare_clone(cli_config.scripts_repo, &scripts_dir) + .context("failed to prepare scripts repository clone")? + .fetch_then_checkout(gix::progress::Discard, &false.into()) + .context("failed to fetch and checkout scripts repository")? + .0 + .main_worktree(gix::progress::Discard, &false.into()) + .context("failed to set scripts repository as main worktree")?; + }; Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index d6cf126..5b3aaee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -155,7 +155,7 @@ impl Project { } } -/// Errors that can occur when reading or writing files +/// Errors that can occur when using the pesde library pub mod errors { use thiserror::Error; diff --git a/src/main.rs b/src/main.rs index 86c3374..96fb0d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -153,25 +153,6 @@ fn run() -> anyhow::Result<()> { .build()? }; - match check_for_updates(&reqwest) { - Ok(_) => {} - Err(e) => { - println!( - "{}", - format!("failed to check for updates: {e}\n\n").red().bold() - ); - } - } - match update_scripts_folder(&project) { - Ok(_) => {} - Err(e) => { - println!( - "{}", - format!("failed to update scripts: {e}\n\n").red().bold() - ); - } - } - let target_version = project .deser_manifest() .ok() @@ -200,6 +181,26 @@ fn run() -> anyhow::Result<()> { std::process::exit(status.code().unwrap()); } + match check_for_updates(&reqwest) { + Ok(_) => {} + Err(e) => { + println!( + "{}", + format!("failed to check for updates: {e}\n\n").red().bold() + ); + } + } + + match update_scripts_folder(&project) { + Ok(_) => {} + Err(e) => { + println!( + "{}", + format!("failed to update scripts: {e}\n\n").red().bold() + ); + } + } + Cli::parse().subcommand.run(project, multi, reqwest) }