fix(dotfiles): unquote aliases before quoting (#1976)

* fix(dotfiles): unquote aliases before quoting

* tests
This commit is contained in:
Ellie Huxtable 2024-04-23 14:45:07 +01:00 committed by GitHub
parent 8b8844887b
commit bf88b42cec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 55 additions and 3 deletions

View File

@ -2,6 +2,8 @@ use std::borrow::Cow;
use std::env; use std::env;
use std::path::PathBuf; use std::path::PathBuf;
use eyre::{eyre, Result};
use rand::RngCore; use rand::RngCore;
use uuid::Uuid; use uuid::Uuid;
@ -144,6 +146,30 @@ pub trait Escapable: AsRef<str> {
} }
} }
pub fn unquote(s: &str) -> Result<String> {
if s.chars().count() < 2 {
return Err(eyre!("not enough chars"));
}
let quote = s.chars().next().unwrap();
// not quoted, do nothing
if quote != '"' && quote != '\'' && quote != '`' {
return Ok(s.to_string());
}
if s.chars().last().unwrap() != quote {
return Err(eyre!("unexpected eof, quotes do not match"));
}
// removes quote characters
// the sanity checks performed above ensure that the quotes will be ASCII and this will not
// panic
let s = &s[1..s.len() - 1];
Ok(s.to_string())
}
impl<T: AsRef<str>> Escapable for T {} impl<T: AsRef<str>> Escapable for T {}
#[cfg(test)] #[cfg(test)]

View File

@ -6,6 +6,7 @@ use atuin_client::record::sqlite_store::SqliteStore;
// While we will support a range of shell config, I'd rather have a larger number of small records // While we will support a range of shell config, I'd rather have a larger number of small records
// + stores, rather than one mega config store. // + stores, rather than one mega config store.
use atuin_common::record::{DecryptedData, Host, HostId}; use atuin_common::record::{DecryptedData, Host, HostId};
use atuin_common::utils::unquote;
use eyre::{bail, ensure, eyre, Result}; use eyre::{bail, ensure, eyre, Result};
use atuin_client::record::encryption::PASETO_V4; use atuin_client::record::encryption::PASETO_V4;
@ -142,7 +143,11 @@ impl AliasStore {
let mut config = String::new(); let mut config = String::new();
for alias in aliases { for alias in aliases {
config.push_str(&format!("alias {}='{}'\n", alias.name, alias.value)); // If it's quoted, remove the quotes. If it's not quoted, do nothing.
let value = unquote(alias.value.as_str()).unwrap_or(alias.value.clone());
// we're about to quote it ourselves anyway!
config.push_str(&format!("alias {}='{}'\n", alias.name, value));
} }
Ok(config) Ok(config)
@ -336,14 +341,17 @@ mod tests {
let alias = AliasStore::new(store, host_id, key); let alias = AliasStore::new(store, host_id, key);
alias.set("k", "kubectl").await.unwrap(); alias.set("k", "kubectl").await.unwrap();
alias.set("gp", "git push").await.unwrap(); alias.set("gp", "git push").await.unwrap();
alias
.set("kgap", "'kubectl get pods --all-namespaces'")
.await
.unwrap();
let mut aliases = alias.aliases().await.unwrap(); let mut aliases = alias.aliases().await.unwrap();
aliases.sort_by_key(|a| a.name.clone()); aliases.sort_by_key(|a| a.name.clone());
assert_eq!(aliases.len(), 2); assert_eq!(aliases.len(), 3);
assert_eq!( assert_eq!(
aliases[0], aliases[0],
@ -360,5 +368,23 @@ mod tests {
value: String::from("kubectl") value: String::from("kubectl")
} }
); );
assert_eq!(
aliases[2],
Alias {
name: String::from("kgap"),
value: String::from("'kubectl get pods --all-namespaces'")
}
);
let build = alias.posix().await.expect("failed to build aliases");
assert_eq!(
build,
"alias gp='git push'
alias k='kubectl'
alias kgap='kubectl get pods --all-namespaces'
"
)
} }
} }