Skip to content

Commit 043374e

Browse files
committed
refactor
- try to set a better baseline for error handling.
1 parent ce5fa98 commit 043374e

File tree

2 files changed

+34
-42
lines changed

2 files changed

+34
-42
lines changed

crates/but/src/branch/mod.rs

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,19 @@ use but_settings::AppSettings;
33
use but_workspace::{StackId, ui::StackEntry};
44
use gitbutler_command_context::CommandContext;
55
use gitbutler_project::Project;
6-
use serde::Serialize;
76
use std::io::{self, Write};
87

98
mod list;
109

11-
#[derive(Debug, Serialize)]
12-
#[serde(untagged)]
13-
enum BranchNewResponse {
14-
Success(BranchNewOutput),
15-
Error(BranchNewError),
16-
}
17-
18-
#[derive(Debug, Serialize)]
19-
struct BranchNewOutput {
20-
branch: String,
21-
#[serde(skip_serializing_if = "Option::is_none")]
22-
anchor: Option<String>,
23-
}
10+
mod json {
11+
use serde::Serialize;
2412

25-
#[derive(Debug, Serialize)]
26-
struct BranchNewError {
27-
error: String,
13+
#[derive(Debug, Serialize)]
14+
pub struct BranchNewOutput {
15+
pub branch: String,
16+
#[serde(skip_serializing_if = "Option::is_none")]
17+
pub anchor: Option<String>,
18+
}
2819
}
2920

3021
#[derive(Debug, clap::Parser)]
@@ -82,23 +73,9 @@ pub async fn handle(cmd: Option<Subcommands>, project: &Project, json: bool) ->
8273
let ctx =
8374
CommandContext::open(project, AppSettings::load_from_default_path_creating()?)?;
8475
// Get branch name or use canned name
85-
let branch_name = if let Some(name) = branch_name {
86-
let repo = ctx.gix_repo()?;
87-
if repo.try_find_reference(name.as_str())?.is_some() {
88-
if json {
89-
let response = BranchNewResponse::Error(BranchNewError {
90-
error: format!("Branch '{}' already exists", name),
91-
});
92-
println!("{}", serde_json::to_string_pretty(&response)?);
93-
} else {
94-
println!("Branch '{name}' already exists");
95-
}
96-
return Ok(());
97-
}
98-
name.clone()
99-
} else {
100-
but_api::workspace::canned_branch_name(project.id)?
101-
};
76+
let branch_name = branch_name
77+
.map(Ok::<_, but_api::error::Error>)
78+
.unwrap_or_else(|| but_api::workspace::canned_branch_name(project.id))?;
10279

10380
// Store anchor string for JSON output
10481
let anchor_for_json = anchor.clone();
@@ -155,10 +132,10 @@ pub async fn handle(cmd: Option<Subcommands>, project: &Project, json: bool) ->
155132
)?;
156133

157134
if json {
158-
let response = BranchNewResponse::Success(BranchNewOutput {
135+
let response = json::BranchNewOutput {
159136
branch: branch_name,
160137
anchor: anchor_for_json,
161-
});
138+
};
162139
println!("{}", serde_json::to_string_pretty(&response)?);
163140
} else if atty::is(Stream::Stdout) {
164141
println!("Created branch {branch_name}");

crates/but/tests/but/branch.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::utils::{Sandbox, setup_metadata};
22
use snapbox::str;
33

44
#[test]
5-
fn branch_new_outputs_branch_name() -> anyhow::Result<()> {
5+
fn new_outputs_branch_name() -> anyhow::Result<()> {
66
let env = Sandbox::init_scenario_with_target("one-stack")?;
77
insta::assert_snapshot!(env.git_log()?, @r"
88
* edd3eb7 (HEAD -> gitbutler/workspace) GitButler Workspace Commit
@@ -33,7 +33,7 @@ my-anchored-feature
3333
}
3434

3535
#[test]
36-
fn branch_new_json_output() -> anyhow::Result<()> {
36+
fn new_with_json_output() -> anyhow::Result<()> {
3737
let env = Sandbox::init_scenario_with_target("one-stack")?;
3838
insta::assert_snapshot!(env.git_log()?, @r"
3939
* edd3eb7 (HEAD -> gitbutler/workspace) GitButler Workspace Commit
@@ -56,7 +56,7 @@ fn branch_new_json_output() -> anyhow::Result<()> {
5656
"#]]);
5757

5858
// Test JSON output with anchor
59-
env.but("--json branch new --anchor 9477ae7 my-anchored-feature")
59+
env.but("branch new --json --anchor 9477ae7 my-anchored-feature")
6060
.assert()
6161
.success()
6262
.stderr_eq(str![])
@@ -68,16 +68,31 @@ fn branch_new_json_output() -> anyhow::Result<()> {
6868
6969
"#]]);
7070

71-
// Test JSON output when branch already exists
72-
env.but("--json branch new my-feature")
71+
// Test JSON output when branch already exists - it's idempotent.
72+
env.but("branch --json new my-feature")
7373
.assert()
7474
.success()
7575
.stderr_eq(str![])
7676
.stdout_eq(str![[r#"
7777
{
78-
"error": "Branch 'my-feature' already exists"
78+
"branch": "my-feature"
7979
}
8080
8181
"#]]);
82+
env.but("branch new --json --anchor 9477ae7 my-anchored-feature")
83+
.assert()
84+
.success()
85+
.stderr_eq(str![])
86+
.stdout_eq(str![[r#"
87+
{
88+
"branch": "my-anchored-feature",
89+
"anchor": "9477ae7"
90+
}
91+
92+
"#]]);
93+
94+
// TODO: on error
95+
// On error, we indicate this both by exit code and by json output to stdout
96+
// so tools would be able to detect it that way.
8297
Ok(())
8398
}

0 commit comments

Comments
 (0)