Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bin): Add diff only mode on CLI #59

Merged
merged 3 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
}
Loading