Skip to content

Commit

Permalink
cli: parse path arguments as fileset expressions
Browse files Browse the repository at this point in the history
If this doesn't work out, maybe we can try one of these:
 a. fall back to bare file name if expression doesn't contain any operator-like
    characters (e.g. "f(x" is an error, but "f x" can be parsed as bare string)
 b. introduce command-line flag to opt in (e.g. -e FILESET)
 c. introduce pattern prefix to opt in (e.g. set:FILESET)

Closes #3239, #2915, #2286
  • Loading branch information
yuja committed Apr 10, 2024
1 parent 05b0fb5 commit b7814a6
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* The default template alias `builtin_log_root(change_id: ChangeId, commit_id: CommitId)` was replaced by `format_root_commit(root: Commit)`.

* Path arguments are now parsed as ["fileset" expressions](docs/filesets.md).
File name containing meta characters or whitespace will need to be escaped.
Example: `jj diff '"File name with space"'`.

### New features

* The list of conflicted paths is printed whenever the working copy changes.
Expand Down
11 changes: 2 additions & 9 deletions cli/src/cli_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use indexmap::{IndexMap, IndexSet};
use itertools::Itertools;
use jj_lib::backend::{ChangeId, CommitId, MergedTreeId, TreeValue};
use jj_lib::commit::Commit;
use jj_lib::fileset::{FilePattern, FilesetExpression, FilesetParseContext};
use jj_lib::fileset::{FilesetExpression, FilesetParseContext};
use jj_lib::git_backend::GitBackend;
use jj_lib::gitignore::{GitIgnoreError, GitIgnoreFile};
use jj_lib::hex_util::to_reverse_hex;
Expand Down Expand Up @@ -657,14 +657,7 @@ impl WorkspaceCommandHelper {
if values.is_empty() {
Ok(FilesetExpression::all())
} else {
let ctx = self.fileset_parse_context();
let expressions = values
.iter()
.map(|v| FilePattern::parse(&ctx, v))
.map_ok(FilesetExpression::pattern)
.try_collect()
.map_err(user_error)?;
Ok(FilesetExpression::union_all(expressions))
self.parse_union_filesets(values)
}
}

Expand Down
12 changes: 10 additions & 2 deletions cli/tests/test_global_opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,16 @@ fn test_color_ui_messages() {
// error source
let stderr = test_env.jj_cmd_failure(&repo_path, &["log", ".."]);
insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"
Error: Path ".." is not in the repo "."
Caused by: Invalid component ".." in repo-relative path "../"
Error: Failed to parse fileset: Invalid file pattern
Caused by:
1:  --> 1:1
 |
1 | ..
 | ^^
 |
 = Invalid file pattern
2: Path ".." is not in the repo "."
3: Invalid component ".." in repo-relative path "../"
"###);

// warning
Expand Down
11 changes: 11 additions & 0 deletions cli/tests/test_log_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,17 @@ fn test_log_filtered_by_path() {
A file2
"###);

// empty revision is filtered out by "all()" fileset.
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-Tdescription", "-s", "all()"]);
insta::assert_snapshot!(stdout, @r###"
@ second
│ M file1
│ A file2
◉ first
│ A file1
~
"###);

// "root:<path>" is resolved relative to the workspace root.
let stdout = test_env.jj_cmd_success(
test_env.env_root(),
Expand Down
14 changes: 14 additions & 0 deletions docs/filesets.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,17 @@ You can also specify patterns by using functions.

* `all()`: Matches everything.
* `none()`: Matches nothing.

## Examples

Show diff excluding `Cargo.lock`.

```
jj diff '~Cargo.lock'
```

Split a revision in two, putting `foo` into the second commit.

```
jj split '~foo'
```
11 changes: 0 additions & 11 deletions lib/src/fileset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,6 @@ pub enum FilePattern {
}

impl FilePattern {
/// Parses the given `input` string as a file pattern.
// TODO: If we decide to parse any file argument as a fileset expression,
// this function can be removed.
pub fn parse(ctx: &FilesetParseContext, input: &str) -> Result<Self, FilePatternParseError> {
if let Some((kind, pat)) = input.split_once(':') {
Self::from_str_kind(ctx, pat, kind)
} else {
Self::cwd_prefix_path(ctx, input)
}
}

/// Parses the given `input` string as pattern of the specified `kind`.
pub fn from_str_kind(
ctx: &FilesetParseContext,
Expand Down

0 comments on commit b7814a6

Please sign in to comment.