From e803bed845228c49e5a5b10e1bb8f0af89b79b44 Mon Sep 17 00:00:00 2001 From: Aaron Bull Schaefer Date: Mon, 12 Aug 2024 09:39:35 -0700 Subject: [PATCH] config: expand tilde in ssh key filepaths Add home directory expansion for SSH key filepaths. This allows the `signing.key` configuration value to work more universally across both Linux and macOS without requiring an absolute path. This moved and renamed the previous `expand_git_path` function to a more generic location, and the prior use was updated accordingly. --- CHANGELOG.md | 3 +++ cli/src/cli_util.rs | 4 ++-- cli/src/git_util.rs | 10 ---------- docs/config.md | 2 +- lib/src/file_util.rs | 10 ++++++++++ lib/src/ssh_signing.rs | 4 ++-- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0afa80c58b..31fb7f8094 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). * The following diff formats now include information about copies and moves: `--color-words`, `--summary` +* A tilde (`~`) at the start of the path will now be expanded to the user's home + directory when configuring a `signing.key` for SSH commit signing. + ### Fixed bugs ## [0.20.0] - 2024-08-07 diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index 4771ddc7b8..bf27ff2f2d 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -73,7 +73,7 @@ use jj_lib::workspace::{ default_working_copy_factories, LockedWorkspace, WorkingCopyFactories, Workspace, WorkspaceLoadError, WorkspaceLoader, }; -use jj_lib::{dag_walk, fileset, git, op_heads_store, op_walk, revset}; +use jj_lib::{dag_walk, file_util, fileset, git, op_heads_store, op_walk, revset}; use once_cell::unsync::OnceCell; use tracing::instrument; use tracing_chrome::ChromeLayerBuilder; @@ -806,7 +806,7 @@ impl WorkspaceCommandHelper { if let Some(value) = config.string("core.excludesFile") { let path = str::from_utf8(&value) .ok() - .map(crate::git_util::expand_git_path)?; + .map(file_util::expand_home_path)?; // The configured path is usually absolute, but if it's relative, // the "git" command would read the file at the work-tree directory. Some(self.workspace_root().join(path)) diff --git a/cli/src/git_util.rs b/cli/src/git_util.rs index 6642470cef..00f5383d9a 100644 --- a/cli/src/git_util.rs +++ b/cli/src/git_util.rs @@ -419,13 +419,3 @@ export or their "parent" branches."#, } Ok(()) } - -/// Expands "~/" to "$HOME/" as Git seems to do for e.g. core.excludesFile. -pub fn expand_git_path(path_str: &str) -> PathBuf { - if let Some(remainder) = path_str.strip_prefix("~/") { - if let Ok(home_dir_str) = std::env::var("HOME") { - return PathBuf::from(home_dir_str).join(remainder); - } - } - PathBuf::from(path_str) -} diff --git a/docs/config.md b/docs/config.md index 5d2552004e..c0906b116b 100644 --- a/docs/config.md +++ b/docs/config.md @@ -784,7 +784,7 @@ sign-all = true backend = "ssh" key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGj+J6N6SO+4P8dOZqfR1oiay2yxhhHnagH52avUqw5h" ## You can also use a path instead of embedding the key -# key = "/home/me/.ssh/id_for_signing.pub" +# key = "~/.ssh/id_for_signing.pub" ``` By default the ssh backend will look for a `ssh-keygen` binary on your path. If you want diff --git a/lib/src/file_util.rs b/lib/src/file_util.rs index 55b24e9aab..c55b80df8b 100644 --- a/lib/src/file_util.rs +++ b/lib/src/file_util.rs @@ -69,6 +69,16 @@ pub fn remove_dir_contents(dirname: &Path) -> Result<(), PathError> { Ok(()) } +/// Expands "~/" to "$HOME/". +pub fn expand_home_path(path_str: &str) -> PathBuf { + if let Some(remainder) = path_str.strip_prefix("~/") { + if let Ok(home_dir_str) = std::env::var("HOME") { + return PathBuf::from(home_dir_str).join(remainder); + } + } + PathBuf::from(path_str) +} + /// Turns the given `to` path into relative path starting from the `from` path. /// /// Both `from` and `to` paths are supposed to be absolute and normalized in the diff --git a/lib/src/ssh_signing.rs b/lib/src/ssh_signing.rs index f514b940a6..a80fbaaa0b 100644 --- a/lib/src/ssh_signing.rs +++ b/lib/src/ssh_signing.rs @@ -81,8 +81,8 @@ fn run_command(command: &mut Command, stdin: &[u8]) -> SshResult> { fn ensure_key_as_file(key: &str) -> SshResult> { let is_inlined_ssh_key = key.starts_with("ssh-"); if !is_inlined_ssh_key { - let key_path = Path::new(key); - return Ok(either::Left(key_path.to_path_buf())); + let key_path = crate::file_util::expand_home_path(key); + return Ok(either::Left(key_path)); } let mut pub_key_file = tempfile::Builder::new()