1use crate::coauthor_repo::CoauthorRepo;
2use crate::commands::{coauthor::Coauthor, mob::Mob, setup::Setup};
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 Coauthor(Coauthor),
50}
51
52pub fn run(coauthor_repo: &impl CoauthorRepo, out: &mut impl Write) -> Result<(), Box<dyn Error>> {
53 let cli = Cli::parse();
54 run_inner(&cli, coauthor_repo, out)
55}
56
57fn run_inner(
58 cli: &Cli,
59 coauthor_repo: &impl CoauthorRepo,
60 out: &mut impl Write,
61) -> Result<(), Box<dyn Error>> {
62 match &cli.command {
63 None => cli.mob.handle(coauthor_repo, out)?,
64 Some(Commands::Setup(setup)) => setup.handle(out)?,
65 Some(Commands::Coauthor(coauthor)) => coauthor.handle(coauthor_repo, out)?,
66 }
67 Ok(())
68}
69
70#[cfg(test)]
71mod tests {
72 use std::error::Error;
73
74 use super::*;
75 use crate::coauthor_repo::MockCoauthorRepo;
76 use mockall::predicate;
77
78 #[test]
79 fn test_clear_mob_session() -> Result<(), Box<dyn Error>> {
80 let mut mock_coauthor_repo = MockCoauthorRepo::new();
81 mock_coauthor_repo
82 .expect_clear_mob()
83 .once()
84 .returning(|| Ok(()));
85
86 let cli = Cli {
87 command: None,
88 mob: Mob {
89 with: None,
90 clear: true,
91 list: false,
92 trailers: false,
93 },
94 };
95
96 let mut out = Vec::new();
97 run_inner(&cli, &mock_coauthor_repo, &mut out)?;
98
99 Ok(())
100 }
101
102 #[test]
103 fn test_delete_coauthor() -> Result<(), Box<dyn Error>> {
104 let key = "lm";
105 let mut mock_coauthor_repo = MockCoauthorRepo::new();
106 mock_coauthor_repo
107 .expect_get()
108 .with(predicate::eq(key))
109 .once()
110 .returning(|_| Ok(Some("Leo Messi <leo.messi@example.com>".to_owned())));
111 mock_coauthor_repo
112 .expect_remove()
113 .with(predicate::eq(key))
114 .once()
115 .returning(|_| Ok(()));
116
117 let cli = Cli {
118 command: Some(Commands::Coauthor(Coauthor {
119 delete: Some(key.to_owned()),
120 add: None,
121 list: false,
122 })),
123 mob: Mob {
124 with: None,
125 clear: false,
126 list: false,
127 trailers: false,
128 },
129 };
130
131 let mut out = Vec::new();
132 run_inner(&cli, &mock_coauthor_repo, &mut out)?;
133
134 Ok(())
135 }
136}