Add quote(s) function for escaping strings (#1022)

Replace all single quotes with `'\''` and prepend and append single
quotes to `s`. This is sufficient to escape special characters for many
shells, including most Bourne shell descendants.
This commit is contained in:
Casey Rodarmor 2021-11-08 11:22:58 -08:00 committed by GitHub
parent 8b49c0cbd1
commit 3ef420ccb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 0 deletions

View File

@ -888,6 +888,7 @@ The executable is at: /bin/just
==== String Manipulation ==== String Manipulation
- `lowercase(s)` - Convert `s` to lowercase. - `lowercase(s)` - Convert `s` to lowercase.
- `quote(s)` - Replace all single quotes with `'\''` and prepend and append single quotes to `s`. This is sufficient to escape special characters for many shells, including most Bourne shell descendants.
- `replace(s, from, to)` - Replace all occurrences of `from` in `s` to `to`. - `replace(s, from, to)` - Replace all occurrences of `from` in `s` to `to`.
- `trim(s)` - Remove leading and trailing whitespace from `s`. - `trim(s)` - Remove leading and trailing whitespace from `s`.
- `trim_end(s)` - Remove trailing whitespace from `s`. - `trim_end(s)` - Remove trailing whitespace from `s`.

View File

@ -27,6 +27,7 @@ lazy_static! {
("os", Nullary(os)), ("os", Nullary(os)),
("os_family", Nullary(os_family)), ("os_family", Nullary(os_family)),
("parent_directory", Unary(parent_directory)), ("parent_directory", Unary(parent_directory)),
("quote", Unary(quote)),
("replace", Ternary(replace)), ("replace", Ternary(replace)),
("trim", Unary(trim)), ("trim", Unary(trim)),
("trim_end", Unary(trim_end)), ("trim_end", Unary(trim_end)),
@ -206,6 +207,10 @@ fn parent_directory(_context: &FunctionContext, path: &str) -> Result<String, St
.ok_or_else(|| format!("Could not extract parent directory from `{}`", path)) .ok_or_else(|| format!("Could not extract parent directory from `{}`", path))
} }
fn quote(_context: &FunctionContext, s: &str) -> Result<String, String> {
Ok(format!("'{}'", s.replace('\'', "'\\''")))
}
fn replace(_context: &FunctionContext, s: &str, from: &str, to: &str) -> Result<String, String> { fn replace(_context: &FunctionContext, s: &str, from: &str, to: &str) -> Result<String, String> {
Ok(s.replace(from, to)) Ok(s.replace(from, to))
} }

View File

@ -26,6 +26,7 @@ mod invocation_directory;
mod misc; mod misc;
mod positional_arguments; mod positional_arguments;
mod quiet; mod quiet;
mod quote;
mod readme; mod readme;
mod regexes; mod regexes;
mod search; mod search;

43
tests/quote.rs Normal file
View File

@ -0,0 +1,43 @@
use crate::common::*;
#[test]
fn single_quotes_are_prepended_and_appended() {
Test::new()
.justfile(
"
x := quote('abc')
",
)
.args(&["--evaluate", "x"])
.stdout("'abc'")
.run();
}
#[test]
fn quotes_are_escaped() {
Test::new()
.justfile(
r#"
x := quote("'")
"#,
)
.args(&["--evaluate", "x"])
.stdout(r"''\'''")
.run();
}
#[test]
fn quoted_strings_can_be_used_as_arguments() {
Test::new()
.justfile(
r#"
file := quote("foo ' bar")
@foo:
touch {{ file }}
ls -1
"#,
)
.stdout("foo ' bar\njustfile\n")
.run();
}