Skip to main content

bb_cli/commands/
branch.rs

1use crate::api::models::BranchRef;
2use crate::commands::pr::Ctx;
3use crate::error::Result;
4use crate::output::{self, Format};
5use serde::Serialize;
6
7#[derive(Debug, Serialize)]
8struct BranchRow {
9    branch: String,
10    user: String,
11    updated: String,
12}
13
14pub async fn list(
15    ctx: &Ctx,
16    user: Option<String>,
17    name: Option<String>,
18    limit: usize,
19) -> Result<()> {
20    let spinner = output::spinner("fetching branches");
21    let branches: Vec<BranchRef> = ctx
22        .client
23        .paginate(&ctx.path("/refs/branches?pagelen=100&sort=-target.date"))
24        .await?;
25    spinner.finish_and_clear();
26
27    let user = user.map(|u| u.to_lowercase());
28    let name = name.map(|n| n.to_lowercase());
29
30    let rows: Vec<BranchRow> = branches
31        .iter()
32        .filter(|b| match &name {
33            Some(needle) => b.name.to_lowercase().contains(needle),
34            None => true,
35        })
36        .filter(|b| match &user {
37            Some(needle) => b.owner().to_lowercase().contains(needle),
38            None => true,
39        })
40        .take(limit)
41        .map(|b| BranchRow {
42            branch: b.name.clone(),
43            user: b.owner(),
44            updated: b
45                .target
46                .as_ref()
47                .and_then(|t| t.date.as_deref())
48                .map(output::relative_time)
49                .unwrap_or_else(|| "-".into()),
50        })
51        .collect();
52
53    match ctx.format {
54        Format::Json => output::print_json(&rows)?,
55        Format::Human => output::print_table(
56            &["BRANCH", "LAST COMMIT BY", "UPDATED"],
57            rows.iter()
58                .map(|r| vec![r.branch.clone(), r.user.clone(), r.updated.clone()])
59                .collect(),
60        ),
61    }
62
63    Ok(())
64}