From e942dd3273a8649991f77fc93feb684dd5f1f87a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 5 Jan 2023 12:10:08 -0600 Subject: [PATCH 1/2] feat(ops)!: Sign implementatio based on git This is based off of git's `gpg-signature.c` Not happy with all of the extra dependencies we added. I might want to consider splitting this out, unsure. --- Cargo.lock | 151 ++++++++++++++++++++- Cargo.toml | 4 + src/ops.rs | 390 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 539 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d54427..31c68d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,18 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "assert_fs" version = "1.0.7" @@ -48,12 +60,29 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "bstr" version = "0.2.17" @@ -65,9 +94,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca0852af221f458706eb0725c03e4ed6c46af9ac98e6a689d5e634215d594dd" +checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b" dependencies = [ "memchr", "once_cell", @@ -167,6 +196,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "convert_case" version = "0.4.0" @@ -271,6 +306,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "doc-comment" version = "0.3.3" @@ -304,6 +350,17 @@ dependencies = [ "libc", ] +[[package]] +name = "expanduser" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14e0b79235da57db6b6c2beed9af6e5de867d63a973ae3e91910ddc33ba40bc0" +dependencies = [ + "dirs", + "lazy_static", + "pwd", +] + [[package]] name = "eyre" version = "0.6.8" @@ -338,13 +395,24 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "git-fixture" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8316938721002656fefc2e819dfd44f78d56bd8d1662064026660a44735c5813" dependencies = [ - "bstr 1.0.1", + "bstr 1.1.0", "derive_more", "eyre", "git2", @@ -373,14 +441,18 @@ name = "git2-ext" version = "0.2.0" dependencies = [ "assert_fs", + "bstr 1.1.0", "criterion", + "expanduser", "eyre", "git-fixture", "git2", "itertools", "log", "regex", + "shlex", "snapbox", + "tempfile", "which", ] @@ -753,6 +825,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pwd" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c71c0c79b9701efe4e1e4b563b2016dd4ee789eb99badcb09d61ac4b92e4a2" +dependencies = [ + "libc", + "thiserror", +] + [[package]] name = "quote" version = "1.0.21" @@ -785,6 +867,12 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + [[package]] name = "redox_syscall" version = "0.2.13" @@ -794,6 +882,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom", + "redox_syscall 0.1.57", + "rust-argon2", +] + [[package]] name = "regex" version = "1.7.0" @@ -826,6 +925,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "rust-argon2" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +dependencies = [ + "base64", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + [[package]] name = "rustc_version" version = "0.4.0" @@ -919,6 +1030,12 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + [[package]] name = "similar" version = "2.2.1" @@ -964,7 +1081,7 @@ dependencies = [ "cfg-if", "fastrand", "libc", - "redox_syscall", + "redox_syscall 0.2.13", "remove_dir_all", "winapi", ] @@ -981,6 +1098,26 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.4" @@ -1064,6 +1201,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasm-bindgen" version = "0.2.83" diff --git a/Cargo.toml b/Cargo.toml index e1cd600..c465c2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,10 @@ git2 = { version = "0.15", default-features = false } log = "0.4" itertools = "0.10" which = "4" +bstr = { version = "1.1.0", default-features = false } +tempfile = "3.3.0" +shlex = "1.1.0" +expanduser = "1.2.2" [dev-dependencies] git-fixture = { version = "0.3", features = ["yaml"] } diff --git a/src/ops.rs b/src/ops.rs index 5f76398..f4512cb 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -4,6 +4,7 @@ //! They serve as both examples on how to use `git2` but also should be usable in some limited //! subset of cases. +use bstr::ByteSlice; use itertools::Itertools; /// Lookup the commit ID for `HEAD` @@ -255,7 +256,7 @@ pub fn commit( if let Some(sign) = sign { let content = repo.commit_create_buffer(author, committer, message, tree, parents)?; let content = std::str::from_utf8(&content).unwrap(); - let signed = sign.sign(content); + let signed = sign.sign(content)?; repo.commit_signed(content, &signed, None) } else { repo.commit(None, author, committer, message, tree, parents) @@ -266,5 +267,390 @@ pub fn commit( /// /// See for an example of what to do. pub trait Sign { - fn sign(&self, buffer: &str) -> String; + fn sign(&self, buffer: &str) -> Result; +} + +pub struct UserSign(UserSignInner); + +enum UserSignInner { + Gpg(GpgSign), + Ssh(SshSign), +} + +impl UserSign { + pub fn from_config( + repo: &git2::Repository, + config: &git2::Config, + ) -> Result { + let format = config + .get_string("gpg.format") + .unwrap_or_else(|_| "openpgp".to_owned()); + match format.as_str() { + "openpgp" => { + let program = config + .get_string("gpg.openpgp.program") + .or_else(|_| config.get_string("gpg.program")) + .unwrap_or_else(|_| "gpg".to_owned()); + + let signing_key = config.get_string("user.signingkey").or_else( + |_| -> Result<_, git2::Error> { + let sig = repo.signature()?; + Ok(String::from_utf8_lossy(sig.name_bytes()).into_owned()) + }, + )?; + + Ok(UserSign(UserSignInner::Gpg(GpgSign::new( + program, + signing_key, + )))) + } + "x509" => { + let program = config + .get_string("gpg.x509.program") + .unwrap_or_else(|_| "gpgsm".to_owned()); + + let signing_key = config.get_string("user.signingkey").or_else( + |_| -> Result<_, git2::Error> { + let sig = repo.signature()?; + Ok(String::from_utf8_lossy(sig.name_bytes()).into_owned()) + }, + )?; + + Ok(UserSign(UserSignInner::Gpg(GpgSign::new( + program, + signing_key, + )))) + } + "ssh" => { + let program = config + .get_string("gpg.ssh.program") + .unwrap_or_else(|_| "ssh-keygen".to_owned()); + + let signing_key = config + .get_string("user.signingkey") + .map(Ok) + .unwrap_or_else(|_| -> Result<_, git2::Error> { + get_default_ssh_signing_key(config)?.map(Ok).unwrap_or_else( + || -> Result<_, git2::Error> { + let sig = repo.signature()?; + Ok(String::from_utf8_lossy(sig.name_bytes()).into_owned()) + }, + ) + })?; + + Ok(UserSign(UserSignInner::Ssh(SshSign::new( + program, + signing_key, + )))) + } + _ => Err(git2::Error::new( + git2::ErrorCode::Invalid, + git2::ErrorClass::Config, + format!("invalid valid for gpg.format: {}", format), + )), + } + } +} + +impl Sign for UserSign { + fn sign(&self, buffer: &str) -> Result { + match &self.0 { + UserSignInner::Gpg(s) => s.sign(buffer), + UserSignInner::Ssh(s) => s.sign(buffer), + } + } +} + +pub struct GpgSign { + program: String, + signing_key: String, +} + +impl GpgSign { + pub fn new(program: String, signing_key: String) -> Self { + Self { + program, + signing_key, + } + } +} + +impl Sign for GpgSign { + fn sign(&self, buffer: &str) -> Result { + let output = pipe_command( + std::process::Command::new(&self.program) + .arg("--status-fd=2") + .arg("-bsau") + .arg(&self.signing_key), + Some(buffer), + ) + .map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("{} failed to sign the data: {}", self.program, e), + ) + })?; + if !output.status.success() { + return Err(git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("{} failed to sign the data", self.program), + )); + } + if output.stderr.find(b"\n[GNUPG:] SIG_CREATED ").is_none() { + return Err(git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("{} failed to sign the data", self.program), + )); + } + + let sig = std::str::from_utf8(&output.stdout).map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("{} failed to sign the data: {}", self.program, e), + ) + })?; + + // Strip CR from the line endings, in case we are on Windows. + let normalized = remove_cr_after(sig); + + Ok(normalized) + } +} + +pub struct SshSign { + program: String, + signing_key: String, +} + +impl SshSign { + pub fn new(program: String, signing_key: String) -> Self { + Self { + program, + signing_key, + } + } +} + +impl Sign for SshSign { + fn sign(&self, buffer: &str) -> Result { + let mut literal_key_file = None; + let ssh_signing_key_file = if let Some(literal_key) = literal_key(&self.signing_key) { + let temp = tempfile::NamedTempFile::new().map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("failed writing ssh signing key: {}", e), + ) + })?; + + std::fs::write(temp.path(), literal_key).map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("failed writing ssh signing key: {}", e), + ) + })?; + let path = temp.path().to_owned(); + literal_key_file = Some(temp); + path + } else { + // We assume a file + expanduser::expanduser(&self.signing_key).map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("failed looking up signing file {}: {}", self.signing_key, e), + ) + })? + }; + + let buffer_file = tempfile::NamedTempFile::new().map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("failed writing buffer: {}", e), + ) + })?; + std::fs::write(buffer_file.path(), buffer).map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("failed writing buffer: {}", e), + ) + })?; + + let output = pipe_command( + std::process::Command::new(&self.program) + .arg("-Y") + .arg("sign") + .arg("-n") + .arg("git") + .arg("-f") + .arg(&ssh_signing_key_file) + .arg(buffer_file.path()), + Some(buffer), + ) + .map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("{} failed to sign the data: {}", self.program, e), + ) + })?; + if !output.status.success() { + if output.stderr.find("usage:").is_some() { + return Err(git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("ssh-keygen -Y sign is needed for ssh signing (available in openssh version 8.2p1+)") + )); + } else { + return Err(git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!( + "{} failed to sign the data: {}", + self.program, + String::from_utf8_lossy(&output.stderr) + ), + )); + } + } + + let mut ssh_signature_filename = buffer_file.path().as_os_str().to_owned(); + ssh_signature_filename.push(".sig"); + let ssh_signature_filename = std::path::PathBuf::from(ssh_signature_filename); + let sig = std::fs::read_to_string(&ssh_signature_filename).map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!( + "failed reading ssh signing data buffer from {}: {}", + ssh_signature_filename.display(), + e + ), + ) + })?; + // Strip CR from the line endings, in case we are on Windows. + let normalized = remove_cr_after(&sig); + + buffer_file.close().map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("failed writing buffer: {}", e), + ) + })?; + if let Some(literal_key_file) = literal_key_file { + literal_key_file.close().map_err(|e| { + git2::Error::new( + git2::ErrorCode::GenericError, + git2::ErrorClass::Os, + format!("failed writing ssh signing key: {}", e), + ) + })?; + } + + Ok(normalized) + } +} + +fn pipe_command( + cmd: &mut std::process::Command, + stdin: Option<&str>, +) -> Result { + use std::io::Write; + + let mut child = cmd + .stdin(if stdin.is_some() { + std::process::Stdio::piped() + } else { + std::process::Stdio::null() + }) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .spawn()?; + if let Some(stdin) = stdin { + let mut stdin_sync = child.stdin.take().expect("stdin is piped"); + write!(stdin_sync, "{}", stdin)?; + } + child.wait_with_output() +} + +fn remove_cr_after(sig: &str) -> String { + let mut normalized = String::new(); + for line in sig.lines() { + normalized.push_str(line); + normalized.push('\n'); + } + normalized +} + +fn literal_key(signing_key: &str) -> Option<&str> { + if let Some(literal) = signing_key.strip_prefix("key::") { + Some(literal) + } else if signing_key.starts_with("ssh-") { + Some(signing_key) + } else { + None + } +} + +// Returns the first public key from an ssh-agent to use for signing +fn get_default_ssh_signing_key(config: &git2::Config) -> Result, git2::Error> { + let ssh_default_key_command = config + .get_string("gpg.ssh.defaultKeyCommand") + .map_err(|_| { + git2::Error::new( + git2::ErrorCode::Invalid, + git2::ErrorClass::Config, + "either user.signingkey or gpg.ssh.defaultKeyCommand needs to be configured", + ) + })?; + let ssh_default_key_args = shlex::split(&ssh_default_key_command).ok_or_else(|| { + git2::Error::new( + git2::ErrorCode::Invalid, + git2::ErrorClass::Config, + format!( + "malformed gpg.ssh.defaultKeyCommand: {}", + ssh_default_key_command + ), + ) + })?; + if ssh_default_key_args.is_empty() { + return Err(git2::Error::new( + git2::ErrorCode::Invalid, + git2::ErrorClass::Config, + format!( + "malformed gpg.ssh.defaultKeyCommand: {}", + ssh_default_key_command + ), + )); + } + + let Ok(output) = pipe_command( + std::process::Command::new(&ssh_default_key_args[0]) + .args(&ssh_default_key_args[1..]), + None, + ) else { + return Ok(None); + }; + + let Ok(keys) = std::str::from_utf8(&output.stdout) else { + return Ok(None); + }; + let Some((default_key, _)) = keys.split_once('\n') else { + return Ok(None); + }; + // We only use `is_literal_ssh_key` here to check validity + // The prefix will be stripped when the key is used + if literal_key(default_key).is_none() { + return Ok(None); + } + + Ok(Some(default_key.to_owned())) } From cc43752261b7002f44558c9f02f086e4d3603a59 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 5 Jan 2023 12:12:50 -0600 Subject: [PATCH 2/2] chore: Bump MSRV to 1.65.0 --- .clippy.toml | 2 +- .github/workflows/ci.yml | 6 +- .github/workflows/rust-next.yml | 4 +- Cargo.lock | 136 +------------------------------- Cargo.toml | 3 +- src/ops.rs | 15 ++-- src/utils.rs | 2 +- 7 files changed, 16 insertions(+), 152 deletions(-) diff --git a/.clippy.toml b/.clippy.toml index 1c443be..efa3e89 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -1 +1 @@ -msrv = "1.61.0" # MSRV +msrv = "1.65.0" # MSRV diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c97801..f48d2aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: - name: No-default features run: cargo test --workspace --no-default-features msrv: - name: "Check MSRV: 1.61.0" + name: "Check MSRV: 1.65.0" runs-on: ubuntu-latest steps: - name: Checkout repository @@ -68,7 +68,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.61.0 # MSRV + toolchain: 1.65.0 # MSRV profile: minimal override: true - uses: Swatinem/rust-cache@v2 @@ -122,7 +122,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.61.0 # MSRV + toolchain: 1.65.0 # MSRV profile: minimal override: true components: clippy diff --git a/.github/workflows/rust-next.yml b/.github/workflows/rust-next.yml index 3eb63ad..3e333f9 100644 --- a/.github/workflows/rust-next.yml +++ b/.github/workflows/rust-next.yml @@ -71,9 +71,9 @@ jobs: strategy: matrix: rust: - - 1.61.0 # MSRV + - 1.65.0 # MSRV - stable - continue-on-error: ${{ matrix.rust != '1.61.0' }} # MSRV + continue-on-error: ${{ matrix.rust != '1.65.0' }} # MSRV runs-on: ubuntu-latest steps: - name: Checkout repository diff --git a/Cargo.lock b/Cargo.lock index 31c68d1..36a1a31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,18 +17,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" -[[package]] -name = "arrayref" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "assert_fs" version = "1.0.7" @@ -60,29 +48,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - [[package]] name = "bstr" version = "0.2.17" @@ -196,12 +167,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "convert_case" version = "0.4.0" @@ -306,17 +271,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" -[[package]] -name = "dirs" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "doc-comment" version = "0.3.3" @@ -350,17 +304,6 @@ dependencies = [ "libc", ] -[[package]] -name = "expanduser" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e0b79235da57db6b6c2beed9af6e5de867d63a973ae3e91910ddc33ba40bc0" -dependencies = [ - "dirs", - "lazy_static", - "pwd", -] - [[package]] name = "eyre" version = "0.6.8" @@ -395,17 +338,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "git-fixture" version = "0.3.0" @@ -443,7 +375,6 @@ dependencies = [ "assert_fs", "bstr 1.1.0", "criterion", - "expanduser", "eyre", "git-fixture", "git2", @@ -825,16 +756,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "pwd" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c71c0c79b9701efe4e1e4b563b2016dd4ee789eb99badcb09d61ac4b92e4a2" -dependencies = [ - "libc", - "thiserror", -] - [[package]] name = "quote" version = "1.0.21" @@ -867,12 +788,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "redox_syscall" version = "0.2.13" @@ -882,17 +797,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "redox_users" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" -dependencies = [ - "getrandom", - "redox_syscall 0.1.57", - "rust-argon2", -] - [[package]] name = "regex" version = "1.7.0" @@ -925,18 +829,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rust-argon2" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" -dependencies = [ - "base64", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils", -] - [[package]] name = "rustc_version" version = "0.4.0" @@ -1081,7 +973,7 @@ dependencies = [ "cfg-if", "fastrand", "libc", - "redox_syscall 0.2.13", + "redox_syscall", "remove_dir_all", "winapi", ] @@ -1098,26 +990,6 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" -[[package]] -name = "thiserror" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "thread_local" version = "1.1.4" @@ -1201,12 +1073,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasm-bindgen" version = "0.2.83" diff --git a/Cargo.toml b/Cargo.toml index c465c2f..bca9a11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ readme = "README.md" categories = ["command-line-interface"] keywords = ["git"] edition = "2021" -rust-version = "1.61.0" # MSRV +rust-version = "1.65.0" # MSRV include = [ "build.rs", "src/**/*", @@ -38,7 +38,6 @@ which = "4" bstr = { version = "1.1.0", default-features = false } tempfile = "3.3.0" shlex = "1.1.0" -expanduser = "1.2.2" [dev-dependencies] git-fixture = { version = "0.3", features = ["yaml"] } diff --git a/src/ops.rs b/src/ops.rs index f4512cb..9e5d0cf 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -458,14 +458,13 @@ impl Sign for SshSign { literal_key_file = Some(temp); path } else { + fn expanduser(path: &str) -> std::path::PathBuf { + // HACK: Need a cross-platform solution + std::path::PathBuf::from(path) + } + // We assume a file - expanduser::expanduser(&self.signing_key).map_err(|e| { - git2::Error::new( - git2::ErrorCode::GenericError, - git2::ErrorClass::Os, - format!("failed looking up signing file {}: {}", self.signing_key, e), - ) - })? + expanduser(&self.signing_key) }; let buffer_file = tempfile::NamedTempFile::new().map_err(|e| { @@ -506,7 +505,7 @@ impl Sign for SshSign { return Err(git2::Error::new( git2::ErrorCode::GenericError, git2::ErrorClass::Os, - format!("ssh-keygen -Y sign is needed for ssh signing (available in openssh version 8.2p1+)") + "ssh-keygen -Y sign is needed for ssh signing (available in openssh version 8.2p1+)" )); } else { return Err(git2::Error::new( diff --git a/src/utils.rs b/src/utils.rs index 6e07fe4..5bf9312 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -22,5 +22,5 @@ fn find_git_bash() -> Option { let git_path = which::which("git.exe").ok()?; let git_dir = git_path.parent()?.parent()?; let git_bash = git_dir.join("bin").join("bash.exe"); - git_bash.is_file().then(|| git_bash) + git_bash.is_file().then_some(git_bash) }