use crate::error::MarsError;
use crate::sync::{ResolutionMode, SyncOptions, SyncRequest};
use super::output;
#[derive(Debug, clap::Args)]
pub struct SyncArgs {
#[arg(long)]
pub force: bool,
#[arg(long)]
pub diff: bool,
#[arg(long)]
pub frozen: bool,
#[arg(long, conflicts_with = "no_refresh_models")]
pub refresh_models: bool,
#[arg(long, conflicts_with = "refresh_models")]
pub no_refresh_models: bool,
#[arg(long)]
pub no_upgrade_hint: bool,
#[arg(long)]
pub verbose: bool,
#[arg(long)]
pub ignore_requires_mars: bool,
#[arg(long)]
pub ignore_requires_meridian: bool,
}
pub fn run(args: &SyncArgs, ctx: &super::MarsContext, json: bool) -> Result<i32, MarsError> {
let no_upgrade_hint = args.no_upgrade_hint || no_upgrade_hint_from_env();
let request = SyncRequest {
resolution: ResolutionMode::Normal,
mutation: None,
options: SyncOptions {
force: args.force,
dry_run: args.diff,
frozen: args.frozen,
refresh_models: args.refresh_models,
no_refresh_models: args.no_refresh_models,
check_upgrades: !no_upgrade_hint,
ignore_requires_mars: args.ignore_requires_mars,
ignore_requires_meridian: args.ignore_requires_meridian,
},
recovery: Default::default(),
lossiness_mode: if args.verbose {
crate::diagnostic::LossinessMode::Verbose
} else {
crate::diagnostic::LossinessMode::Surface
},
};
let report = crate::sync::execute(ctx, &request)?;
output::print_sync_report(&report, json, no_upgrade_hint);
Ok(0)
}
fn no_upgrade_hint_from_env() -> bool {
match std::env::var("MARS_NO_UPGRADE_HINT") {
Ok(value) => value.trim() == "1",
Err(_) => false,
}
}
#[cfg(test)]
mod tests {
use crate::cli::{Cli, Command};
use clap::Parser;
#[test]
fn parses_no_refresh_models() {
let cli = Cli::try_parse_from(["mars", "sync", "--no-refresh-models"]).unwrap();
let Command::Sync(args) = cli.command else {
panic!("expected sync command");
};
assert!(args.no_refresh_models);
}
#[test]
fn parses_refresh_models() {
let cli = Cli::try_parse_from(["mars", "sync", "--refresh-models"]).unwrap();
let Command::Sync(args) = cli.command else {
panic!("expected sync command");
};
assert!(args.refresh_models);
}
#[test]
fn refresh_and_no_refresh_conflict() {
assert!(
Cli::try_parse_from(["mars", "sync", "--refresh-models", "--no-refresh-models"])
.is_err()
);
}
#[test]
fn parses_no_upgrade_hint() {
let cli = Cli::try_parse_from(["mars", "sync", "--no-upgrade-hint"]).unwrap();
let Command::Sync(args) = cli.command else {
panic!("expected sync command");
};
assert!(args.no_upgrade_hint);
}
#[test]
fn parses_verbose() {
let cli = Cli::try_parse_from(["mars", "sync", "--verbose"]).unwrap();
let Command::Sync(args) = cli.command else {
panic!("expected sync command");
};
assert!(args.verbose);
}
#[test]
fn engine_ignore_flags_parse_on_all_syncing_commands() {
for command in ["sync", "upgrade", "add", "repair"] {
let mut argv = vec!["mars", command];
if command == "add" {
argv.push("owner/repo");
}
argv.extend(["--ignore-requires-mars", "--ignore-requires-meridian"]);
let cli = Cli::try_parse_from(argv).unwrap();
match cli.command {
Command::Sync(args) => {
assert!(args.ignore_requires_mars);
assert!(args.ignore_requires_meridian);
}
Command::Upgrade(args) => {
assert!(args.ignore_requires_mars);
assert!(args.ignore_requires_meridian);
}
Command::Add(args) => {
assert!(args.ignore_requires_mars);
assert!(args.ignore_requires_meridian);
}
Command::Repair(args) => {
assert!(args.ignore_requires_mars);
assert!(args.ignore_requires_meridian);
}
_ => panic!("unexpected command"),
}
}
}
}