Skip to content

Commit

Permalink
feat(bin): Add diff only mode on CLI (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpedroh authored Jun 15, 2024
1 parent 39687ce commit 28d81a1
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 10 deletions.
12 changes: 8 additions & 4 deletions bin/src/cli_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ use clap::Parser;
#[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,

/// Path to file in base revision
#[arg(short, long)]
pub(crate) base_path: std::path::PathBuf,
#[arg(short, long, requires_if("false", "diff_only"))]
pub(crate) base_path: Option<std::path::PathBuf>,

/// Path to file in left revision
#[arg(short, long)]
Expand All @@ -16,8 +20,8 @@ pub struct CliArgs {
pub(crate) right_path: std::path::PathBuf,

/// Path where the merged file should be written
#[arg(short, long)]
pub(crate) merge_path: std::path::PathBuf,
#[arg(short, long, requires_if("false", "diff_only"))]
pub(crate) merge_path: Option<std::path::PathBuf>,

/// 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.
Expand Down
3 changes: 3 additions & 0 deletions bin/src/cli_exit_codes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
pub const SUCCESS_WITHOUT_CONFLICTS: i32 = 0;
pub const SUCCESS_WITH_CONFLICTS: i32 = 1;

pub const SUCCESS_FILES_FULLY_MATCH: i32 = 0;
pub const SUCCESS_FILES_DO_NOT_FULLY_MATCH: i32 = 1;

pub const READING_FILE_ERROR: i32 = 129;
pub const INVALID_LANGUAGE_ERROR: i32 = 130;
pub const WRITING_FILE_ERROR: i32 = 131;
Expand Down
30 changes: 29 additions & 1 deletion bin/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{
fmt::{self, Display},
};

use matching::matching_configuration;
use matching::{matching_configuration, MatchingEntry};
use parsing::ParserConfiguration;

#[derive(Debug)]
Expand Down Expand Up @@ -102,3 +102,31 @@ pub fn run_tool_on_merge_scenario(
false => Ok(ExecutionResult::WithoutConflicts(result.to_string())),
}
}

pub fn run_diff_on_files(
language: model::Language,
left: &str,
right: &str,
) -> Result<MatchingEntry, ExecutionError> {
let parser_configuration = ParserConfiguration::from(language);

log::info!("Started parsing left file");
let left_tree_root =
parsing::parse_string(left, &parser_configuration).map_err(ExecutionError::ParsingError)?;
log::info!("Finished parsing left file");
log::info!("Started parsing right file");
let right_tree_root = parsing::parse_string(right, &parser_configuration)
.map_err(ExecutionError::ParsingError)?;
log::info!("Finished parsing right file");

let matching_configuration = matching_configuration::MatchingConfiguration::from(language);
log::info!("Started calculation of matchings between left and right");
let matchings_left_right =
matching::calculate_matchings(&left_tree_root, &right_tree_root, &matching_configuration);
log::info!("Finished calculation of matchings between left and right");

Ok(matchings_left_right
.get_matching_entry(&left_tree_root, &right_tree_root)
.unwrap_or_default()
.to_owned())
}
2 changes: 1 addition & 1 deletion bin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ mod cli_exit_codes;
mod control;

pub use cli_exit_codes::*;
pub use control::run_tool_on_merge_scenario;
pub use control::{run_diff_on_files, run_tool_on_merge_scenario};
57 changes: 53 additions & 4 deletions bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,27 @@ 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();
env_logger::builder()
.filter_level(args.log_level.unwrap_or(log::LevelFilter::Info))
.init();

log::info!("Starting Generic Merge tool execution");
log::debug!("Parsed arguments: {:?}", args);

let base = std::fs::read_to_string(&args.base_path).unwrap_or_else(|error| {
match !args.diff_only {
true => run_merge(args),
false => run_diff(args),
}
}

fn run_merge(args: CliArgs) {
let base_path = args.base_path.unwrap();

let base = std::fs::read_to_string(&base_path).unwrap_or_else(|error| {
log::error!("Error while reading base file: {}", error);
std::process::exit(cli_exit_codes::READING_FILE_ERROR)
});
Expand All @@ -27,7 +39,7 @@ fn main() {

let language = match args.language {
Some(language) => language::get_language_from_name(&language),
None => language::get_language_by_file_path(&args.base_path),
None => language::get_language_by_file_path(&base_path),
}
.unwrap_or_else(|error| {
log::error!("Error while retrieving language configuration: {}", error);
Expand All @@ -40,7 +52,7 @@ fn main() {
std::process::exit(cli_exit_codes::INTERNAL_EXECUTION_ERROR)
});

std::fs::write(args.merge_path, result.to_string()).unwrap_or_else(|error| {
std::fs::write(args.merge_path.unwrap(), result.to_string()).unwrap_or_else(|error| {
log::error!("Error while writing output file: {}", error);
std::process::exit(cli_exit_codes::WRITING_FILE_ERROR)
});
Expand All @@ -56,3 +68,40 @@ fn main() {
}
}
}

fn run_diff(args: CliArgs) {
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)
});
let right = std::fs::read_to_string(&args.right_path).unwrap_or_else(|error| {
log::error!("Error while reading right file: {}", error);
std::process::exit(cli_exit_codes::READING_FILE_ERROR)
});

let language = match args.language {
Some(language) => language::get_language_from_name(&language),
None => language::get_language_by_file_path(&args.left_path),
}
.unwrap_or_else(|error| {
log::error!("Error while retrieving language configuration: {}", error);
std::process::exit(cli_exit_codes::INVALID_LANGUAGE_ERROR)
});

let result = control::run_diff_on_files(language, &left, &right).unwrap_or_else(|error| {
log::error!("Error while running tool: {}", error);
std::process::exit(cli_exit_codes::INTERNAL_EXECUTION_ERROR)
});

log::info!("{:?}", result);
match result.is_perfect_match {
true => {
log::info!("Both files are equivalent");
std::process::exit(cli_exit_codes::SUCCESS_FILES_FULLY_MATCH)
}
false => {
log::info!("Both files are different");
std::process::exit(cli_exit_codes::SUCCESS_FILES_DO_NOT_FULLY_MATCH)
}
}
}
22 changes: 22 additions & 0 deletions bin/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,25 @@ fn if_there_is_no_conflict_it_returns_valid_exit_code() {
.assert()
.code(bin::SUCCESS_WITHOUT_CONFLICTS);
}

#[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")
.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")
.assert()
.code(bin::SUCCESS_FILES_FULLY_MATCH);
}

#[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")
.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")
.assert()
.code(bin::SUCCESS_FILES_DO_NOT_FULLY_MATCH);
}
11 changes: 11 additions & 0 deletions bin/tests/diff_scenarios/java_files_full_match/left.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public class Main {
static {
int x = 2;
}

public static void main() {
int a = 0;
}

public static void teste() {}
}
11 changes: 11 additions & 0 deletions bin/tests/diff_scenarios/java_files_full_match/right.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public class Main {
static {
int x = 2;
}

public static void teste() {}

public static void main() {
int a = 0;
}
}
11 changes: 11 additions & 0 deletions bin/tests/diff_scenarios/java_files_not_fully_matching/left.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public class Main {
static {
int x = 2;
}

public static void main() {
int a = 2;
}

public static void teste() {}
}
11 changes: 11 additions & 0 deletions bin/tests/diff_scenarios/java_files_not_fully_matching/right.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public class Main {
static {
int x = 2;
}

public static void teste() {}

public static void main() {
int a = 0;
}
}

0 comments on commit 28d81a1

Please sign in to comment.