1mod alias;
2mod cli;
3mod handoff;
4mod handup;
5mod install;
6
7use std::process;
8
9use anyhow::Result;
10use clap::Parser;
11use cli::{Cli, Commands};
12use hj_core::ReconcileMode;
13
14pub fn main_entry() {
15 if let Err(error) = run() {
16 eprintln!("error: {error:#}");
17 process::exit(1);
18 }
19}
20
21pub fn run() -> Result<()> {
22 let cli = Cli::parse_from(alias::rewrite_args_for_alias(std::env::args_os()));
23 match cli.command {
24 Commands::Detect(args) => handoff::detect(args),
25 Commands::Handoff(args) => handoff::close(args),
26 Commands::Handon(args) => handoff::handon(args),
27 Commands::Handover(args) => handoff::handover(args),
28 Commands::HandoffDb(args) => handoff::handoff_db(args),
29 Commands::Handup(args) => handup::handup(args),
30 Commands::Install(args) => install::install(args),
31 Commands::Update(args) | Commands::UpdateAll(args) => install::update(args),
32 Commands::Refresh(args) => handoff::refresh(args),
33 Commands::Reconcile(args) => handoff::reconcile(args, ReconcileMode::Sync),
34 Commands::Audit(args) => handoff::reconcile(args, ReconcileMode::Audit),
35 Commands::Close(args) => handoff::close(args),
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use std::ffi::{OsStr, OsString};
42
43 use clap::Parser;
44
45 use crate::{
46 alias::rewrite_args_for_alias,
47 cli::{Cli, Commands, InstallArgs, TargetArgs, UpdateArgs},
48 };
49
50 #[test]
51 fn handoff_detect_alias_rewrites_to_subcommand() {
52 let rewritten = rewrite_args_for_alias([
53 OsString::from("handoff-detect"),
54 OsString::from("--project"),
55 ]);
56 assert_eq!(
57 rewritten,
58 vec![
59 OsString::from("hj"),
60 OsString::from("detect"),
61 OsString::from("--project")
62 ]
63 );
64 }
65
66 #[test]
67 fn handoff_alias_rewrites_to_subcommand() {
68 let rewritten = rewrite_args_for_alias([OsString::from("handoff")]);
69 assert_eq!(
70 rewritten,
71 vec![OsString::from("hj"), OsString::from("handoff")]
72 );
73 }
74
75 #[test]
76 fn handon_alias_rewrites_to_subcommand() {
77 let rewritten = rewrite_args_for_alias([OsString::from("handon")]);
78 assert_eq!(
79 rewritten,
80 vec![OsString::from("hj"), OsString::from("handon")]
81 );
82 }
83
84 #[test]
85 fn handover_alias_rewrites_to_subcommand() {
86 let rewritten = rewrite_args_for_alias([OsString::from("handover")]);
87 assert_eq!(
88 rewritten,
89 vec![OsString::from("hj"), OsString::from("handover")]
90 );
91 }
92
93 #[test]
94 fn install_command_uses_default_root() {
95 let cli = Cli::parse_from([OsStr::new("hj"), OsStr::new("install")]);
96 match cli.command {
97 Commands::Install(InstallArgs { root }) => assert_eq!(root, "~/.local"),
98 other => panic!("expected install command, got {other:?}"),
99 }
100 }
101
102 #[test]
103 fn update_command_uses_default_root() {
104 let cli = Cli::parse_from([OsStr::new("hj"), OsStr::new("update")]);
105 match cli.command {
106 Commands::Update(UpdateArgs { root }) => assert_eq!(root, "~/.local"),
107 other => panic!("expected update command, got {other:?}"),
108 }
109 }
110
111 #[test]
112 fn update_all_command_parses_separately() {
113 let cli = Cli::parse_from([OsStr::new("hj"), OsStr::new("update-all")]);
114 match cli.command {
115 Commands::UpdateAll(UpdateArgs { root }) => assert_eq!(root, "~/.local"),
116 other => panic!("expected update-all command, got {other:?}"),
117 }
118 }
119
120 #[test]
121 fn handon_command_parses_target_args() {
122 let cli = Cli::parse_from([
123 OsStr::new("hj"),
124 OsStr::new("handon"),
125 OsStr::new("--project"),
126 OsStr::new("hj"),
127 ]);
128 match cli.command {
129 Commands::Handon(TargetArgs { project, .. }) => {
130 assert_eq!(project.as_deref(), Some("hj"))
131 }
132 other => panic!("expected handon command, got {other:?}"),
133 }
134 }
135}