1use crate::coauthor_repo::CoauthorRepo;
2use crate::commands::{mob::Mob, setup::Setup, team_member::TeamMember};
3use clap::{Parser, Subcommand};
4use std::error::Error;
5use std::io::Write;
6use std::str;
7
8#[derive(Parser)]
9#[command(
10 author,
11 version,
12 about,
13 long_about,
14 bin_name = "git mob",
15 override_usage = "git mob [COMMAND] [OPTIONS]"
16)]
17#[command(propagate_version = true)]
18struct Cli {
35 #[command(subcommand)]
36 command: Option<Commands>,
37 #[command(flatten)]
38 mob: Mob,
39}
40
41#[derive(Subcommand)]
42enum Commands {
43 Setup(Setup),
45 #[clap(alias = "coauthor")] TeamMember(TeamMember),
51}
52
53pub fn run(coauthor_repo: &impl CoauthorRepo, out: &mut impl Write) -> Result<(), Box<dyn Error>> {
54 let cli = Cli::parse();
55 run_inner(&cli, coauthor_repo, out)
56}
57
58fn run_inner(
59 cli: &Cli,
60 coauthor_repo: &impl CoauthorRepo,
61 out: &mut impl Write,
62) -> Result<(), Box<dyn Error>> {
63 match &cli.command {
64 None => cli.mob.handle(coauthor_repo, out)?,
65 Some(Commands::Setup(setup)) => setup.handle(out)?,
66 Some(Commands::TeamMember(team_member)) => team_member.handle(coauthor_repo, out)?,
67 }
68 Ok(())
69}
70
71#[cfg(test)]
72mod tests {
73 use std::error::Error;
74
75 use super::*;
76 use crate::coauthor_repo::MockCoauthorRepo;
77 use mockall::predicate;
78
79 #[test]
80 fn test_clear_mob_session() -> Result<(), Box<dyn Error>> {
81 let mut mock_coauthor_repo = MockCoauthorRepo::new();
82 mock_coauthor_repo
83 .expect_clear_mob()
84 .once()
85 .returning(|| Ok(()));
86
87 let cli = Cli {
88 command: None,
89 mob: Mob {
90 with: None,
91 clear: true,
92 list: false,
93 trailers: false,
94 },
95 };
96
97 let mut out = Vec::new();
98 run_inner(&cli, &mock_coauthor_repo, &mut out)?;
99
100 Ok(())
101 }
102
103 #[test]
104 fn test_delete_team_member() -> Result<(), Box<dyn Error>> {
105 let key = "lm";
106 let mut mock_coauthor_repo = MockCoauthorRepo::new();
107 mock_coauthor_repo
108 .expect_get()
109 .with(predicate::eq(key))
110 .once()
111 .returning(|_| Ok(Some("Leo Messi <leo.messi@example.com>".to_owned())));
112 mock_coauthor_repo
113 .expect_remove()
114 .with(predicate::eq(key))
115 .once()
116 .returning(|_| Ok(()));
117
118 let cli = Cli {
119 command: Some(Commands::TeamMember(TeamMember {
120 delete: Some(key.to_owned()),
121 add: None,
122 list: false,
123 })),
124 mob: Mob {
125 with: None,
126 clear: false,
127 list: false,
128 trailers: false,
129 },
130 };
131
132 let mut out = Vec::new();
133 run_inner(&cli, &mock_coauthor_repo, &mut out)?;
134
135 Ok(())
136 }
137}