Skip to content

Commit 2335287

Browse files
CopilotByron
andcommitted
Modify 'review publish' to accept CliId as positional argument
Co-authored-by: Byron <[email protected]>
1 parent 1cd81a6 commit 2335287

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

crates/but/src/forge/review.rs

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ pub enum Subcommands {
2626
/// Publish review requests for active branches in your workspace.
2727
/// By default, publishes reviews for all active branches.
2828
Publish {
29-
/// Publish reviews only for the specified branch.
30-
#[clap(long, short = 'b')]
29+
/// Branch name or CliId to publish a review for. If not provided, publishes reviews for all active branches.
3130
branch: Option<String>,
3231
/// Force push even if it's not fast-forward (defaults to true).
3332
#[clap(long, short = 'f', default_value_t = true)]
@@ -57,10 +56,15 @@ pub async fn publish_reviews(
5756
let applied_stacks =
5857
but_api::workspace::stacks(project.id, Some(but_workspace::StacksFilter::InWorkspace))?;
5958
match branch {
60-
Some(branch_name) => {
59+
Some(branch_input) => {
60+
// Resolve the branch input as a CliId to support both branch names and CliIds
61+
let app_settings = AppSettings::load_from_default_path_creating()?;
62+
let ctx = &mut CommandContext::open(project, app_settings)?;
63+
let branch_name = resolve_branch_name(ctx, branch_input)?;
64+
6165
handle_specific_branch_publish(
6266
project,
63-
branch_name,
67+
&branch_name,
6468
&review_map,
6569
&applied_stacks,
6670
skip_force_push_protection,
@@ -530,3 +534,57 @@ pub fn get_review_numbers(
530534
"".to_string().normal()
531535
}
532536
}
537+
538+
/// Resolve a branch input string to an actual branch name.
539+
///
540+
/// This function handles both exact branch names and CliId matches (including partial matches).
541+
/// The CliId resolution allows users to specify branches using shortened identifiers similar
542+
/// to how the `rub` command works.
543+
///
544+
/// # Arguments
545+
/// * `ctx` - The command context used for resolving CliIds
546+
/// * `branch_input` - The branch name or CliId to resolve
547+
///
548+
/// # Returns
549+
/// * `Ok(String)` - The resolved branch name
550+
///
551+
/// # Errors
552+
/// * Returns an error if no matches are found
553+
/// * Returns an error if the input is ambiguous (matches multiple entities)
554+
/// * Returns an error if the input resolves to a non-branch entity (e.g., a commit or file)
555+
fn resolve_branch_name(ctx: &mut CommandContext, branch_input: &str) -> anyhow::Result<String> {
556+
// CliId::from_str handles both exact branch names and CliId matches (including partial matches)
557+
let mut cli_ids = crate::id::CliId::from_str(ctx, branch_input)?;
558+
559+
if cli_ids.is_empty() {
560+
anyhow::bail!(
561+
"Branch '{}' not found. If you just performed a Git operation (squash, rebase, etc.), try running 'but status' to refresh the current state.",
562+
branch_input
563+
);
564+
}
565+
566+
if cli_ids.len() > 1 {
567+
let matches: Vec<String> = cli_ids
568+
.iter()
569+
.map(|id| match id {
570+
crate::id::CliId::Branch { name } => format!("{id} (branch '{name}')"),
571+
_ => format!("{} ({})", id, id.kind()),
572+
})
573+
.collect();
574+
anyhow::bail!(
575+
"Branch identifier '{}' is ambiguous. Matches: {}. Try using more characters, a longer identifier, or the full branch name to disambiguate.",
576+
branch_input,
577+
matches.join(", ")
578+
);
579+
}
580+
581+
// Extract branch name from the resolved CliId
582+
match cli_ids.pop().unwrap() {
583+
crate::id::CliId::Branch { name } => Ok(name),
584+
other => anyhow::bail!(
585+
"Expected a branch, but '{}' resolved to {}",
586+
branch_input,
587+
other.kind()
588+
),
589+
}
590+
}

0 commit comments

Comments
 (0)