1use crate::error::MarsError;
4use crate::sync::{ResolutionMode, SyncOptions, SyncRequest};
5
6use super::output;
7
8#[derive(Debug, clap::Args)]
10pub struct SyncArgs {
11 #[arg(long)]
13 pub force: bool,
14
15 #[arg(long)]
17 pub diff: bool,
18
19 #[arg(long)]
21 pub frozen: bool,
22
23 #[arg(long, conflicts_with = "no_refresh_models")]
25 pub refresh_models: bool,
26
27 #[arg(long, conflicts_with = "refresh_models")]
29 pub no_refresh_models: bool,
30
31 #[arg(long)]
33 pub no_upgrade_hint: bool,
34
35 #[arg(long)]
37 pub verbose: bool,
38}
39
40pub fn run(args: &SyncArgs, ctx: &super::MarsContext, json: bool) -> Result<i32, MarsError> {
42 let no_upgrade_hint = args.no_upgrade_hint || no_upgrade_hint_from_env();
43 let request = SyncRequest {
44 resolution: ResolutionMode::Normal,
45 mutation: None,
46 options: SyncOptions {
47 force: args.force,
48 dry_run: args.diff,
49 frozen: args.frozen,
50 refresh_models: args.refresh_models,
51 no_refresh_models: args.no_refresh_models,
52 check_upgrades: !no_upgrade_hint,
53 },
54 lossiness_mode: if args.verbose {
55 crate::diagnostic::LossinessMode::Verbose
56 } else {
57 crate::diagnostic::LossinessMode::Surface
58 },
59 };
60
61 let report = crate::sync::execute(ctx, &request)?;
62
63 output::print_sync_report(&report, json, no_upgrade_hint);
64
65 if report.has_conflicts() { Ok(1) } else { Ok(0) }
66}
67
68fn no_upgrade_hint_from_env() -> bool {
69 match std::env::var("MARS_NO_UPGRADE_HINT") {
70 Ok(value) => value.trim() == "1",
71 Err(_) => false,
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use crate::cli::{Cli, Command};
78 use clap::Parser;
79
80 #[test]
81 fn parses_no_refresh_models() {
82 let cli = Cli::try_parse_from(["mars", "sync", "--no-refresh-models"]).unwrap();
83 let Command::Sync(args) = cli.command else {
84 panic!("expected sync command");
85 };
86 assert!(args.no_refresh_models);
87 }
88
89 #[test]
90 fn parses_refresh_models() {
91 let cli = Cli::try_parse_from(["mars", "sync", "--refresh-models"]).unwrap();
92 let Command::Sync(args) = cli.command else {
93 panic!("expected sync command");
94 };
95 assert!(args.refresh_models);
96 }
97
98 #[test]
99 fn refresh_and_no_refresh_conflict() {
100 assert!(
101 Cli::try_parse_from(["mars", "sync", "--refresh-models", "--no-refresh-models"])
102 .is_err()
103 );
104 }
105
106 #[test]
107 fn parses_no_upgrade_hint() {
108 let cli = Cli::try_parse_from(["mars", "sync", "--no-upgrade-hint"]).unwrap();
109 let Command::Sync(args) = cli.command else {
110 panic!("expected sync command");
111 };
112 assert!(args.no_upgrade_hint);
113 }
114
115 #[test]
116 fn parses_verbose() {
117 let cli = Cli::try_parse_from(["mars", "sync", "--verbose"]).unwrap();
118 let Command::Sync(args) = cli.command else {
119 panic!("expected sync command");
120 };
121 assert!(args.verbose);
122 }
123}