use std::{fs, path::Path};
pub(super) fn short_hash(hash: &str) -> &str {
hash.get(..16).unwrap_or(hash)
}
pub(super) fn shell_quote(value: &str) -> String {
if value
.chars()
.all(|character| character.is_ascii_alphanumeric() || matches!(character, '_' | '-' | '.'))
{
return value.to_owned();
}
format!("'{}'", value.replace('\'', "'\\''"))
}
pub(super) fn version_line_for_error(version: &str) -> String {
if version.is_empty() {
String::new()
} else {
format!("Version: {version}\n")
}
}
pub(super) fn first_lines(text: &str, count: usize) -> String {
let mut lines = String::new();
for line in text.lines().take(count) {
use std::fmt::Write as _;
let _result = writeln!(&mut lines, "{line}");
}
lines
}
pub(super) fn first_lines_file(path: &Path, count: usize) -> String {
fs::read_to_string(path)
.map(|text| first_lines(&text, count))
.unwrap_or_default()
}
pub(super) fn prefix_lines(text: &str, prefix: &str) -> String {
let mut lines = String::new();
for line in text.lines() {
use std::fmt::Write as _;
let _result = writeln!(&mut lines, "{prefix}{line}");
}
lines
}
pub(super) fn last_non_empty_line(text: &str) -> String {
text.lines()
.map(str::trim)
.rfind(|line| !line.is_empty())
.unwrap_or_default()
.to_owned()
}
#[cfg(test)]
mod tests {
use super::shell_quote;
#[test]
fn shell_quote_keeps_rerun_command_single_argument() {
assert_eq!(shell_quote("abc-123"), "abc-123");
assert_eq!(
shell_quote("refactor(elenchus): Reuse approved review results"),
"'refactor(elenchus): Reuse approved review results'"
);
assert_eq!(shell_quote("can't"), "'can'\\''t'");
}
}