Skip to content

Commit

Permalink
production ready release
Browse files Browse the repository at this point in the history
  • Loading branch information
demidko committed Apr 4, 2024
1 parent 1cc3fa1 commit 5abacce
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 83 deletions.
70 changes: 17 additions & 53 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "archdiff"
version = "2024.3.12"
version = "2024.4.4"
edition = "2021"

[profile.release]
Expand All @@ -9,5 +9,4 @@ panic = "abort"

[dependencies]
git2 = "0.18.3"
regex = "1.10.4"
similar = "2.5.0"
itertools = "0.12.1"
52 changes: 52 additions & 0 deletions src/diff_printer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use std::str;

pub struct DiffPrinter {
buf: String,
changes: bool,
was_real_print: bool,
}

impl DiffPrinter {
pub fn new() -> Self {
Self {
buf: String::new(),
changes: false,
was_real_print: false,
}
}

pub fn println(&mut self, diff: &str) {
if is_new_file(diff) {
self.flush()
}
if has_changes(diff) {
self.changes = true
}
self.buf += diff;
self.buf += "\n"
}

pub fn flush(&mut self) {
if self.changes {
if self.was_real_print {
println!();
}
println!("{}", self.buf.trim_end());
self.was_real_print = true
}
self.changes = false;
self.buf.clear()
}
}

fn has_changes(diff: &str) -> bool {
if is_new_file(diff) {
// мы не можем знать об изменениях в api по заголовку файла
return false;
}
diff.starts_with("+") || diff.starts_with("-")
}

fn is_new_file(diff: &str) -> bool {
diff.starts_with("---") || diff.starts_with("+++")
}
66 changes: 39 additions & 27 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
use std::env::args;
use std::fmt::Debug;
use std::ops::Not;
use std::str;

use DiffFormat::Patch;
use DiffLineType::{AddEOFNL, Addition, Binary, Context, ContextEOFNL, DeleteEOFNL, Deletion, FileHeader, HunkHeader};
use git2::{Diff, DiffDelta, DiffFindOptions, DiffFormat, DiffHunk, DiffLine, DiffLineType, Object, ObjectType, Repository};
use similar::DiffableStr;
use itertools::Itertools;

use crate::diff_printer::DiffPrinter;

mod diff_printer;

fn main() {
let help = "Usage: archdiff [OLD_BRANCH] [NEW_BRANCH]";
let old_branch = args().nth(1).expect(help);
let new_branch = args().nth(2).expect(help);
let repo = open_current_repo();
diff_branches(&repo, &old_branch, &new_branch)
.print(Patch, print_diff_line)
.unwrap();
let diff = diff_branches(&repo, &old_branch, &new_branch);
let mut printer = DiffPrinter::new();
diff.print(Patch, |d, h, l| print_diff_line(d, h, l, &mut printer)).unwrap();
printer.flush();
}

pub fn open_current_repo() -> Repository {
fn open_current_repo() -> Repository {
match Repository::open(".") {
Ok(repo) => repo,
Err(e) => panic!("Failed to open repo: {}", e.message())
}
}

pub fn diff_branches<'a>(repo: &'a Repository, old_branch: &str, new_branch: &str) -> Diff<'a> {
fn diff_branches<'a>(repo: &'a Repository, old_branch: &str, new_branch: &str) -> Diff<'a> {
let old_obj = make_tree_object(repo, old_branch);
let old_tree = old_obj.as_tree();
let new_obj = make_tree_object(repo, new_branch);
Expand All @@ -40,7 +43,7 @@ pub fn diff_branches<'a>(repo: &'a Repository, old_branch: &str, new_branch: &st
diff
}

pub fn print_diff_line(delta: DiffDelta, _hunk: Option<DiffHunk>, line: DiffLine) -> bool {
fn print_diff_line(delta: DiffDelta, _hunk: Option<DiffHunk>, line: DiffLine, printer: &mut DiffPrinter) -> bool {
let diff_type = line.origin_value();

if is_unsupported_file(&delta) {
Expand All @@ -51,18 +54,17 @@ pub fn print_diff_line(delta: DiffDelta, _hunk: Option<DiffHunk>, line: DiffLine
}

let line = line.content();
let line = str::from_utf8(line).unwrap();
let line = str::from_utf8(line).unwrap().trim_end();

if diff_type == FileHeader {
print!("{}", line);
return true;
}
if diff_type == HunkHeader {
print!("{}", trim_hunk_header(line));
printer.println(&trim_file_header(line));
return true;
}
if is_java_api(line) {
println!("{}{}", prefix(diff_type), trim_java_api(line));
let prefix = prefix(diff_type);
let line = trim_java_api(line);
let line = format!("{}{}", prefix, line);
printer.println(&line)
}
true
}
Expand All @@ -76,15 +78,6 @@ fn prefix(diff: DiffLineType) -> char {
}
}

fn trim_hunk_header(line: &str) -> &str {
if line.starts_with("@@") {
let line = line.trim_start_matches("@@");
let idx = line.find("@@").unwrap() + 2;
return &line[idx..];
}
line
}

fn is_java_api(line: &str) -> bool {
let line = line.trim_start();
if line.starts_with("public") {
Expand All @@ -97,7 +90,25 @@ fn is_java_api(line: &str) -> bool {
}

fn trim_java_api(line: &str) -> &str {
line.trim_end_matches(" {\n")
line.trim_end()
.trim_end_matches("=")
.trim_end_matches("{")
.trim_end()
}

fn trim_file_header(line: &str) -> String {
let lines = line.lines().collect_vec();
let new_file = lines.len() - 1;
let old_file = new_file - 1;
let old_file = lines[old_file];
let new_file = lines[new_file];
if old_file.ends_with("/dev/null") {
return new_file.to_string();
}
if new_file.ends_with("/dev/null") {
return old_file.to_string();
}
format!("{}\n{}", old_file, new_file)
}

fn is_unsupported_file(delta: &DiffDelta) -> bool {
Expand All @@ -116,6 +127,7 @@ fn is_unsupported_diff(diff: DiffLineType) -> bool {
AddEOFNL => true,
DeleteEOFNL => true,
Binary => true,
HunkHeader => true,
_ => false
}
}
Expand All @@ -136,4 +148,4 @@ mod tests {
let header = trim_hunk_header(&header);
assert_eq!(header, " class Test {")
}
}
}

0 comments on commit 5abacce

Please sign in to comment.