git_stk/commands/
status.rs1use anyhow::Result;
2use clap_complete::engine::ArgValueCompleter;
3
4use crate::commands::Run;
5use crate::completions;
6use crate::providers::{ReviewState, detect_provider, review_provider};
7use crate::{git, stack};
8
9#[derive(Debug, clap::Args)]
11pub struct Status {
12 #[arg(add = ArgValueCompleter::new(completions::branch_candidates))]
13 branch: Option<String>,
14}
15
16impl Run for Status {
17 fn run(self) -> Result<()> {
18 print_status(self.branch.as_deref())
19 }
20}
21
22pub fn print_status(branch: Option<&str>) -> Result<()> {
23 let branch = branch
24 .map(str::to_owned)
25 .map_or_else(git::current_branch, Ok)?;
26 let parent = stack::parent_for_branch(&branch)?;
27 let children = stack::children_for_branch(&branch)?;
28
29 println!("branch: {branch}");
30 match parent.as_deref() {
31 Some(parent) => println!("parent: {parent}"),
32 None => println!("parent: none"),
33 }
34 if children.is_empty() {
35 println!("children: none");
36 } else {
37 println!("children: {}", children.join(", "));
38 }
39
40 let provider = detect_provider()?;
41 println!("provider: {} ({})", provider.kind, provider.source);
42 let review_provider = review_provider(provider.kind);
43
44 let review = review_provider.review_for_branch(&branch)?;
45 match &review {
46 Some(review) => {
47 println!(
48 "review: {} {} {} -> {}",
49 review.id, review.state, review.branch, review.base
50 );
51 println!("url: {}", review.url);
52
53 if let Some(parent) = parent.as_deref()
54 && parent != review.base
55 {
56 println!(
57 "warning: review base is {}, local parent is {parent} - run `git stk submit`",
58 review.base
59 );
60 }
61 }
62 None => println!("review: none"),
63 }
64
65 let mut hints = Vec::new();
68 if let Some(review) = &review
69 && review.state == ReviewState::Merged
70 {
71 hints.push(format!(
72 "review {} is merged - run `git stk sync`",
73 review.id
74 ));
75 }
76 if let Some(parent) = parent.as_deref() {
77 if let Ok(Some(parent_review)) = review_provider.review_for_branch(parent)
78 && parent_review.branch == parent
79 && parent_review.state == ReviewState::Merged
80 {
81 hints.push(format!(
82 "parent review {} is merged - run `git stk sync`",
83 parent_review.id
84 ));
85 }
86
87 if hints.is_empty()
88 && let Some(hint) = stack::behind_parent_hint(&branch, parent)
89 {
90 hints.push(hint);
91 }
92 }
93 for hint in hints {
94 println!("hint: {hint}");
95 }
96
97 Ok(())
98}