diff --git a/bin/src/cli_args.rs b/bin/src/cli_args.rs index 99dea85..ae898b5 100644 --- a/bin/src/cli_args.rs +++ b/bin/src/cli_args.rs @@ -1,14 +1,44 @@ -use clap::Parser; +use clap::{Parser, Subcommand}; #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] pub struct CliArgs { - /// Runs only the diffing algorithm and outputs if the two files matches. - #[arg(short, long, num_args = 0)] - pub(crate) diff_only: bool, + #[command(subcommand)] + pub command: CliSubCommands, + /// The minimum log level to be displayed in output + #[arg(long, global=true, default_value_t = log::LevelFilter::Info)] + pub log_level: log::LevelFilter, +} + +#[derive(Subcommand, Debug)] +pub enum CliSubCommands { + #[command(about = "Runs only the diffing step on both input files")] + Diff(DiffCliArgs), + #[command(about = "Runs structured merge on the scenario provided")] + Merge(MergeCliArgs), +} + +#[derive(Parser, Debug)] +pub struct DiffCliArgs { + /// Path to file in left revision + #[arg(short, long)] + pub(crate) left_path: std::path::PathBuf, + + /// Path to file in right revision + #[arg(short, long)] + pub(crate) right_path: std::path::PathBuf, + + /// The language that the files being diffed are written in. + /// If not provided the language will try to be inferred by the extension. + #[arg(long)] + pub(crate) language: Option, +} + +#[derive(Parser, Debug)] +pub struct MergeCliArgs { /// Path to file in base revision - #[arg(short, long, requires_if("false", "diff_only"))] + #[arg(short, long)] pub(crate) base_path: Option, /// Path to file in left revision @@ -20,16 +50,11 @@ pub struct CliArgs { pub(crate) right_path: std::path::PathBuf, /// Path where the merged file should be written - #[arg(short, long, requires_if("false", "diff_only"))] + #[arg(short, long)] pub(crate) merge_path: Option, - /// The language that the files being merged are written in. - /// If not provided the language will try to be inferred by the extension of the base file. + /// The language that the files being diffed are written in. + /// If not provided the language will try to be inferred by the extension. #[arg(long)] pub(crate) language: Option, - - /// The log level provided for the execution. - /// If not provided defaults to INFO. - #[arg(long)] - pub(crate) log_level: Option, } diff --git a/bin/src/main.rs b/bin/src/main.rs index aba48e6..8bc91a2 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -1,27 +1,25 @@ +use clap::Parser; +use cli_args::{CliArgs, CliSubCommands, DiffCliArgs, MergeCliArgs}; + mod cli_args; mod cli_exit_codes; mod control; mod language; -use clap::Parser; -use cli_args::CliArgs; - fn main() { - let args = cli_args::CliArgs::parse(); - env_logger::builder() - .filter_level(args.log_level.unwrap_or(log::LevelFilter::Info)) - .init(); + let args = CliArgs::parse(); + env_logger::builder().filter_level(args.log_level).init(); log::info!("Starting Generic Merge tool execution"); log::debug!("Parsed arguments: {:?}", args); - match !args.diff_only { - true => run_merge(args), - false => run_diff(args), + match args.command { + CliSubCommands::Diff(args) => run_diff(args), + CliSubCommands::Merge(args) => run_merge(args), } } -fn run_merge(args: CliArgs) { +fn run_merge(args: MergeCliArgs) { let base_path = args.base_path.unwrap(); let base = std::fs::read_to_string(&base_path).unwrap_or_else(|error| { @@ -69,7 +67,7 @@ fn run_merge(args: CliArgs) { } } -fn run_diff(args: CliArgs) { +fn run_diff(args: DiffCliArgs) { let left = std::fs::read_to_string(&args.left_path).unwrap_or_else(|error| { log::error!("Error while reading left file: {}", error); std::process::exit(cli_exit_codes::READING_FILE_ERROR) diff --git a/bin/tests/cli.rs b/bin/tests/cli.rs index edae8f1..dfc1c3a 100644 --- a/bin/tests/cli.rs +++ b/bin/tests/cli.rs @@ -5,7 +5,8 @@ use assert_cmd::prelude::*; #[test] fn if_there_is_a_conflict_it_returns_valid_exit_code() { let mut cmd = Command::cargo_bin("generic-merge").unwrap(); - cmd.arg("--base-path=tests/scenarios/smoke_java/base.java") + cmd.arg("merge") + .arg("--base-path=tests/scenarios/smoke_java/base.java") .arg("--left-path=tests/scenarios/smoke_java/left.java") .arg("--right-path=tests/scenarios/smoke_java/right.java") .arg("--merge-path=tests/scenarios/smoke_java/merge.output.java") @@ -17,7 +18,8 @@ fn if_there_is_a_conflict_it_returns_valid_exit_code() { #[test] fn if_there_is_no_conflict_it_returns_valid_exit_code() { let mut cmd = Command::cargo_bin("generic-merge").unwrap(); - cmd.arg("--base-path=tests/scenarios/no_conflicts/base.java") + cmd.arg("merge") + .arg("--base-path=tests/scenarios/no_conflicts/base.java") .arg("--left-path=tests/scenarios/no_conflicts/left.java") .arg("--right-path=tests/scenarios/no_conflicts/right.java") .arg("--merge-path=tests/scenarios/no_conflicts/merge.output.java") @@ -29,7 +31,7 @@ fn if_there_is_no_conflict_it_returns_valid_exit_code() { #[test] fn if_i_am_running_on_diff_mode_and_files_fully_match_it_returns_zero() { let mut cmd = Command::cargo_bin("generic-merge").unwrap(); - cmd.arg("--diff-only") + cmd.arg("diff") .arg("--left-path=tests/diff_scenarios/java_files_full_match/left.java") .arg("--right-path=tests/diff_scenarios/java_files_full_match/right.java") .arg("--language=java") @@ -40,7 +42,7 @@ fn if_i_am_running_on_diff_mode_and_files_fully_match_it_returns_zero() { #[test] fn if_i_am_running_on_diff_mode_and_files_do_not_fully_match_it_returns_one() { let mut cmd = Command::cargo_bin("generic-merge").unwrap(); - cmd.arg("--diff-only") + cmd.arg("diff") .arg("--left-path=tests/diff_scenarios/java_files_not_fully_matching/left.java") .arg("--right-path=tests/diff_scenarios/java_files_not_fully_matching/right.java") .arg("--language=java")