forked from mirrors/jj
revset: add support for file(kind:pattern) syntax
There are no more callers of parse_function_argument_to_string(), so it's removed. This function was a thin wrapper of literal parser, and can be easily reintroduced if needed.
This commit is contained in:
parent
850887cf09
commit
8b32a8a916
4 changed files with 42 additions and 23 deletions
|
@ -70,6 +70,6 @@ tags()+++::
|
|||
merges()
|
||||
~merges()
|
||||
# These are unbearably slow, so only filter within small set
|
||||
file(Makefile) & v1.0.0..v1.2.0
|
||||
file(root:"Makefile") & v1.0.0..v1.2.0
|
||||
empty() & v1.0.0..v1.2.0
|
||||
conflict() & v1.0.0..v1.2.0
|
||||
|
|
|
@ -152,15 +152,28 @@ fn test_bad_function_call() {
|
|||
= Function "file": Expected at least 1 argument
|
||||
"###);
|
||||
|
||||
let stderr = test_env.jj_cmd_failure(&repo_path, &["log", "-r", "file(a, not:a-string)"]);
|
||||
let stderr = test_env.jj_cmd_failure(&repo_path, &["log", "-r", "file(a, not@a-string)"]);
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Error: Failed to parse revset: Function "file": Expected function argument of type string
|
||||
Error: Failed to parse revset: Function "file": Expected function argument of file pattern
|
||||
Caused by: --> 1:9
|
||||
|
|
||||
1 | file(a, not:a-string)
|
||||
1 | file(a, not@a-string)
|
||||
| ^----------^
|
||||
|
|
||||
= Function "file": Expected function argument of type string
|
||||
= Function "file": Expected function argument of file pattern
|
||||
"###);
|
||||
|
||||
let stderr = test_env.jj_cmd_failure(&repo_path, &["log", "-r", r#"file(foo:"bar")"#]);
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Error: Failed to parse revset: Function "file": Invalid file pattern
|
||||
Caused by:
|
||||
1: --> 1:6
|
||||
|
|
||||
1 | file(foo:"bar")
|
||||
| ^-------^
|
||||
|
|
||||
= Function "file": Invalid file pattern
|
||||
2: Invalid file pattern kind "foo:"
|
||||
"###);
|
||||
|
||||
let stderr = test_env.jj_cmd_failure(&repo_path, &["log", "-r", r#"file(a, "../out")"#]);
|
||||
|
|
|
@ -156,9 +156,8 @@ given [string pattern](#string-patterns).
|
|||
* `empty()`: Commits modifying no files. This also includes `merges()` without
|
||||
user modifications and `root()`.
|
||||
|
||||
* `file(relativepath)` or `file("relativepath"[, "relativepath"]...)`: Commits
|
||||
modifying one of the paths specified. Currently, string patterns are *not*
|
||||
supported in the path arguments.
|
||||
* `file(pattern[, pattern]...)`: Commits modifying paths matching one of the
|
||||
given [file patterns](filesets.md#file-patterns).
|
||||
|
||||
Paths are relative to the directory `jj` was invoked from. A directory name
|
||||
will match all files in that directory and its subdirectories.
|
||||
|
|
|
@ -33,13 +33,12 @@ use thiserror::Error;
|
|||
|
||||
use crate::backend::{BackendError, BackendResult, ChangeId, CommitId};
|
||||
use crate::commit::Commit;
|
||||
use crate::fileset::FilesetExpression;
|
||||
use crate::fileset::{FilePattern, FilesetExpression, FilesetParseContext};
|
||||
use crate::git;
|
||||
use crate::hex_util::to_forward_hex;
|
||||
use crate::object_id::{HexPrefix, PrefixResolution};
|
||||
use crate::op_store::WorkspaceId;
|
||||
use crate::repo::Repo;
|
||||
use crate::repo_path::RepoPathBuf;
|
||||
use crate::revset_graph::RevsetGraphEdge;
|
||||
use crate::store::Store;
|
||||
use crate::str_util::StringPattern;
|
||||
|
@ -1339,18 +1338,14 @@ static BUILTIN_FUNCTION_MAP: Lazy<HashMap<&'static str, RevsetFunction>> = Lazy:
|
|||
map.insert("file", |name, arguments_pair, state| {
|
||||
let arguments_span = arguments_pair.as_span();
|
||||
if let Some(ctx) = state.workspace_ctx {
|
||||
let ctx = FilesetParseContext {
|
||||
cwd: ctx.cwd,
|
||||
workspace_root: ctx.workspace_root,
|
||||
};
|
||||
let file_expressions: Vec<_> = arguments_pair
|
||||
.into_inner()
|
||||
.map(|arg| -> Result<_, RevsetParseError> {
|
||||
let span = arg.as_span();
|
||||
let needle = parse_function_argument_to_string(name, arg, state)?;
|
||||
let path = RepoPathBuf::parse_fs_path(ctx.cwd, ctx.workspace_root, needle)
|
||||
.map_err(|e| {
|
||||
RevsetParseError::invalid_arguments(name, "Invalid file pattern", span)
|
||||
.with_source(e)
|
||||
})?;
|
||||
Ok(FilesetExpression::prefix_path(path))
|
||||
})
|
||||
.map(|arg| parse_function_argument_to_file_pattern(name, arg, state, &ctx))
|
||||
.map_ok(FilesetExpression::pattern)
|
||||
.try_collect()?;
|
||||
if file_expressions.is_empty() {
|
||||
Err(RevsetParseError::invalid_arguments(
|
||||
|
@ -1497,12 +1492,17 @@ fn expect_named_arguments_vec<'i>(
|
|||
Ok((required, optional))
|
||||
}
|
||||
|
||||
fn parse_function_argument_to_string(
|
||||
fn parse_function_argument_to_file_pattern(
|
||||
name: &str,
|
||||
pair: Pair<Rule>,
|
||||
state: ParseState,
|
||||
) -> Result<String, RevsetParseError> {
|
||||
parse_function_argument_as_literal("string", name, pair, state)
|
||||
ctx: &FilesetParseContext,
|
||||
) -> Result<FilePattern, RevsetParseError> {
|
||||
let parse_pattern = |value: &str, kind: Option<&str>| match kind {
|
||||
Some(kind) => FilePattern::from_str_kind(ctx, value, kind),
|
||||
None => FilePattern::cwd_prefix_path(ctx, value),
|
||||
};
|
||||
parse_function_argument_as_pattern("file pattern", name, pair, state, parse_pattern)
|
||||
}
|
||||
|
||||
fn parse_function_argument_to_string_pattern(
|
||||
|
@ -2587,6 +2587,7 @@ mod tests {
|
|||
use assert_matches::assert_matches;
|
||||
|
||||
use super::*;
|
||||
use crate::repo_path::RepoPathBuf;
|
||||
|
||||
fn parse(revset_str: &str) -> Result<Rc<RevsetExpression>, RevsetParseErrorKind> {
|
||||
parse_with_aliases(revset_str, [] as [(&str, &str); 0])
|
||||
|
@ -3343,6 +3344,12 @@ mod tests {
|
|||
FilesetExpression::prefix_path(RepoPathBuf::from_internal_string("foo"))
|
||||
)))
|
||||
);
|
||||
assert_eq!(
|
||||
parse_with_workspace(r#"file(file:"foo")"#, &WorkspaceId::default()),
|
||||
Ok(RevsetExpression::filter(RevsetFilterPredicate::File(
|
||||
FilesetExpression::file_path(RepoPathBuf::from_internal_string("foo"))
|
||||
)))
|
||||
);
|
||||
assert_eq!(
|
||||
parse_with_workspace("file(foo, bar, baz)", &WorkspaceId::default()),
|
||||
Ok(RevsetExpression::filter(RevsetFilterPredicate::File(
|
||||
|
|
Loading…
Reference in a new issue