Skip to content

Commit

Permalink
Move parse_string_pattern in cli to StringPattern::parse in lib
Browse files Browse the repository at this point in the history
This commit moves the parse_string_pattern helper function into the
str_util module in jj lib and adds tests for it.

I'd like to reuse this code in a function defined by `UserSettings`, which is
part of the jj lib crate and cannot use functions from the cli crate.
  • Loading branch information
emesterhazy committed Mar 29, 2024
1 parent f83d1a8 commit dd1def0
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 22 deletions.
10 changes: 1 addition & 9 deletions cli/src/cli_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ use jj_lib::revset::{
use jj_lib::rewrite::restore_tree;
use jj_lib::settings::{ConfigResultExt as _, UserSettings};
use jj_lib::signing::SignInitError;
use jj_lib::str_util::{StringPattern, StringPatternParseError};
use jj_lib::str_util::StringPattern;
use jj_lib::transaction::Transaction;
use jj_lib::view::View;
use jj_lib::working_copy::{
Expand Down Expand Up @@ -1651,14 +1651,6 @@ pub fn print_trackable_remote_branches(ui: &Ui, view: &View) -> io::Result<()> {
Ok(())
}

pub fn parse_string_pattern(src: &str) -> Result<StringPattern, StringPatternParseError> {
if let Some((kind, pat)) = src.split_once(':') {
StringPattern::from_str_kind(pat, kind)
} else {
Ok(StringPattern::exact(src))
}
}

/// Resolves revsets into revisions for use; useful for rebases or operations
/// that take multiple parents.
pub fn resolve_all_revs(
Expand Down
10 changes: 4 additions & 6 deletions cli/src/commands/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ use jj_lib::revset::{self, RevsetExpression};
use jj_lib::str_util::StringPattern;
use jj_lib::view::View;

use crate::cli_util::{
parse_string_pattern, CommandHelper, RemoteBranchName, RemoteBranchNamePattern, RevisionArg,
};
use crate::cli_util::{CommandHelper, RemoteBranchName, RemoteBranchNamePattern, RevisionArg};
use crate::command_error::{user_error, user_error_with_hint, CommandError};
use crate::formatter::Formatter;
use crate::ui::Ui;
Expand Down Expand Up @@ -78,7 +76,7 @@ pub struct BranchDeleteArgs {
/// By default, the specified name matches exactly. Use `glob:` prefix to
/// select branches by wildcard pattern. For details, see
/// https://github.com/martinvonz/jj/blob/main/docs/revsets.md#string-patterns.
#[arg(required_unless_present_any(&["glob"]), value_parser = parse_string_pattern)]
#[arg(required_unless_present_any(&["glob"]), value_parser = StringPattern::parse)]
pub names: Vec<StringPattern>,

/// Deprecated. Please prefix the pattern with `glob:` instead.
Expand Down Expand Up @@ -117,7 +115,7 @@ pub struct BranchListArgs {
/// By default, the specified name matches exactly. Use `glob:` prefix to
/// select branches by wildcard pattern. For details, see
/// https://github.com/martinvonz/jj/blob/main/docs/revsets.md#string-patterns.
#[arg(value_parser = parse_string_pattern)]
#[arg(value_parser = StringPattern::parse)]
pub names: Vec<StringPattern>,

/// Show branches whose local targets are in the given revisions.
Expand All @@ -140,7 +138,7 @@ pub struct BranchForgetArgs {
/// By default, the specified name matches exactly. Use `glob:` prefix to
/// select branches by wildcard pattern. For details, see
/// https://github.com/martinvonz/jj/blob/main/docs/revsets.md#string-patterns.
#[arg(required_unless_present_any(&["glob"]), value_parser = parse_string_pattern)]
#[arg(required_unless_present_any(&["glob"]), value_parser = StringPattern::parse)]
pub names: Vec<StringPattern>,

/// Deprecated. Please prefix the pattern with `glob:` instead.
Expand Down
9 changes: 4 additions & 5 deletions cli/src/commands/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ use jj_lib::workspace::Workspace;
use maplit::hashset;

use crate::cli_util::{
parse_string_pattern, print_trackable_remote_branches, short_change_hash, short_commit_hash,
start_repo_transaction, CommandHelper, RevisionArg, WorkspaceCommandHelper,
WorkspaceCommandTransaction,
print_trackable_remote_branches, short_change_hash, short_commit_hash, start_repo_transaction,
CommandHelper, RevisionArg, WorkspaceCommandHelper, WorkspaceCommandTransaction,
};
use crate::command_error::{
user_error, user_error_with_hint, user_error_with_message, CommandError,
Expand Down Expand Up @@ -158,7 +157,7 @@ pub struct GitFetchArgs {
///
/// By default, the specified name matches exactly. Use `glob:` prefix to
/// expand `*` as a glob. The other wildcard characters aren't supported.
#[arg(long, short, default_value = "glob:*", value_parser = parse_string_pattern)]
#[arg(long, short, default_value = "glob:*", value_parser = StringPattern::parse)]
branch: Vec<StringPattern>,
/// The remote to fetch from (only named remotes are supported, can be
/// repeated)
Expand Down Expand Up @@ -203,7 +202,7 @@ pub struct GitPushArgs {
/// By default, the specified name matches exactly. Use `glob:` prefix to
/// select branches by wildcard pattern. For details, see
/// https://martinvonz.github.io/jj/latest/revsets#string-patterns.
#[arg(long, short, value_parser = parse_string_pattern)]
#[arg(long, short, value_parser = StringPattern::parse)]
branch: Vec<StringPattern>,
/// Push all branches (including deleted branches)
#[arg(long)]
Expand Down
4 changes: 2 additions & 2 deletions cli/src/commands/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use jj_lib::str_util::StringPattern;

use crate::cli_util::{parse_string_pattern, CommandHelper};
use crate::cli_util::CommandHelper;
use crate::command_error::CommandError;
use crate::ui::Ui;

Expand All @@ -33,7 +33,7 @@ pub struct TagListArgs {
/// By default, the specified name matches exactly. Use `glob:` prefix to
/// select tags by wildcard pattern. For details, see
/// https://github.com/martinvonz/jj/blob/main/docs/revsets.md#string-patterns.
#[arg(value_parser = parse_string_pattern)]
#[arg(value_parser = StringPattern::parse)]
pub names: Vec<StringPattern>,
}

Expand Down
48 changes: 48 additions & 0 deletions lib/src/str_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,19 @@ impl StringPattern {
StringPattern::Substring(String::new())
}

/// Parses the given string as a `StringPattern`. Everything before the
/// first ":" is considered the string's prefix. If the prefix is "exact:",
/// "glob:", or "substring:", a pattern of the specified kind is returned.
/// Returns an error if the string has an unrecognized prefix. Otherwise, a
/// `StringPattern::Exact` is returned.
pub fn parse(src: &str) -> Result<StringPattern, StringPatternParseError> {
if let Some((kind, pat)) = src.split_once(':') {
StringPattern::from_str_kind(pat, kind)
} else {
Ok(StringPattern::exact(src))
}
}

/// Creates pattern that matches exactly.
pub fn exact(src: impl Into<String>) -> Self {
StringPattern::Exact(src.into())
Expand Down Expand Up @@ -163,4 +176,39 @@ mod tests {
Some("*[*]*".into())
);
}

#[test]
fn test_parse() {
// Parse specific pattern kinds.
assert_eq!(
StringPattern::parse("exact:foo").unwrap(),
StringPattern::from_str_kind("foo", "exact").unwrap()
);
assert_eq!(
StringPattern::parse("glob:foo*").unwrap(),
StringPattern::from_str_kind("foo*", "glob").unwrap()
);
assert_eq!(
StringPattern::parse("substring:foo").unwrap(),
StringPattern::from_str_kind("foo", "substring").unwrap()
);

// Parse a pattern that contains a : itself.
assert_eq!(
StringPattern::parse("exact:foo:bar").unwrap(),
StringPattern::from_str_kind("foo:bar", "exact").unwrap()
);

// If no kind is specified, the input is treated as an exact pattern.
assert_eq!(
StringPattern::parse("foo").unwrap(),
StringPattern::from_str_kind("foo", "exact").unwrap()
);

// Parsing an unknown prefix results in an error.
assert!(matches! {
StringPattern::parse("unknown-prefix:foo"),
Err(StringPatternParseError::InvalidKind(_))
});
}
}

0 comments on commit dd1def0

Please sign in to comment.