Skip to content

Commit

Permalink
feat: use gix for parsing git information in mitre/git plugin
Browse files Browse the repository at this point in the history
Signed-off-by: Patrick Casey <[email protected]>
  • Loading branch information
patrickjcasey committed Dec 13, 2024
1 parent 94333e7 commit c5c049e
Show file tree
Hide file tree
Showing 11 changed files with 1,252 additions and 1,607 deletions.
804 changes: 802 additions & 2 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 1 addition & 3 deletions hipcheck-common/src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,7 @@ mod test {
let res = match chunk_with_size(query, 10) {
Ok(r) => r,
Err(e) => {
println!("{e}");
assert!(false);
return;
panic!("{e}");
}
};
assert_eq!(res.len(), 4);
Expand Down
23 changes: 10 additions & 13 deletions hipcheck/src/policy_exprs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ mod tests {
let program =
"(eq 3 (count (filter (gt 8.0) (foreach (sub 1.0) [1.0 2.0 10.0 20.0 30.0]))))";
let context = Value::Null;
let expr = parse(&program).unwrap();
let expr = parse(program).unwrap();
println!("EXPR: {:?}", &expr);
let expr = FunctionResolver::std().run(expr).unwrap();
let expr = TypeFixer::std().run(expr).unwrap();
Expand Down Expand Up @@ -352,13 +352,12 @@ mod tests {
#[test]
fn type_lambda() {
let program = "(gt #t)";
let expr = parse(&program).unwrap();
let expr = parse(program).unwrap();
let expr = FunctionResolver::std().run(expr).unwrap();
let expr = TypeFixer::std().run(expr).unwrap();
let res_ty = TypeChecker::default().run(&expr);
let Ok(Type::Lambda(l_ty)) = res_ty else {
assert!(false);
return;
panic!();
};
let ret_ty = l_ty.get_return_type();
assert_eq!(ret_ty, Ok(ReturnableType::Primitive(PrimitiveType::Bool)));
Expand All @@ -368,7 +367,7 @@ mod tests {
fn type_filter_bad_lambda_array() {
// Should fail because can't compare ints and bools
let program = "(filter (gt #t) [1 2])";
let expr = parse(&program).unwrap();
let expr = parse(program).unwrap();
let expr = FunctionResolver::std().run(expr).unwrap();
let expr = TypeFixer::std().run(expr).unwrap();
let res_ty = TypeChecker::default().run(&expr);
Expand All @@ -386,7 +385,7 @@ mod tests {
fn type_array_mixed_types() {
// Should fail because array elts must have one primitive type
let program = "(count [#t 2])";
let mut expr = parse(&program).unwrap();
let mut expr = parse(program).unwrap();
expr = FunctionResolver::std().run(expr).unwrap();
let res_ty = TypeChecker::default().run(&expr);
assert_eq!(
Expand All @@ -403,26 +402,24 @@ mod tests {
fn type_propagate_unknown() {
// Type for array should be unknown because we can't know ident type
let program = "(max [])";
let mut expr = parse(&program).unwrap();
let mut expr = parse(program).unwrap();
expr = FunctionResolver::std().run(expr).unwrap();
let res_ty = TypeChecker::default().run(&expr);
let Ok(Type::Function(f_ty)) = res_ty else {
assert!(false);
return;
panic!()
};
assert_eq!(f_ty.get_return_type(), Ok(ReturnableType::Unknown));
}

#[test]
fn type_not() {
let program = "(not $)";
let mut expr = parse(&program).unwrap();
let mut expr = parse(program).unwrap();
expr = FunctionResolver::std().run(expr).unwrap();
let res_ty = TypeChecker::default().run(&expr);
println!("RESTY: {res_ty:?}");
let Ok(Type::Function(f_ty)) = res_ty else {
assert!(false);
return;
panic!()
};
let ret_ty = f_ty.get_return_type();
assert_eq!(ret_ty, Ok(ReturnableType::Primitive(PrimitiveType::Bool)));
Expand All @@ -433,7 +430,7 @@ mod tests {
let programs = vec!["(not $)", "(gt 0)", "(filter (gt 0) $/alpha)"];

for program in programs {
let mut expr = parse(&program).unwrap();
let mut expr = parse(program).unwrap();
expr = FunctionResolver::std().run(expr).unwrap();
expr = TypeFixer::std().run(expr).unwrap();
let string = expr.to_string();
Expand Down
5 changes: 4 additions & 1 deletion plugins/git/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ clap = { version = "4.5.23", features = ["derive"] }
hipcheck-sdk = { version = "0.2.0", path = "../../sdk/rust", features = [
"macros",
] }
gix = { version = "0.68.0", default-features = false, features = [
"basic",
"max-performance",
] }
jiff = { version = "0.1.14", features = ["serde"] }
log = "0.4.22"
nom = "7.1.3"
once_cell = "1.10.0"
schemars = { version = "0.8.21", features = ["url"] }
semver = "1.0.9"
Expand Down
99 changes: 77 additions & 22 deletions plugins/git/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use serde::{Deserialize, Serialize};
use std::{
fmt::{self, Display, Formatter},
hash::Hash,
sync::Arc,
};

/// A locally stored git repo, with optional additional details
Expand All @@ -21,15 +20,44 @@ pub struct DetailedGitRepo {
}

/// Commits as they come directly out of `git log`.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct RawCommit {
pub hash: String,

pub author: Contributor,
pub written_on: Result<String, String>,
pub written_on: Result<jiff::Timestamp, String>,

pub committer: Contributor,
pub committed_on: Result<String, String>,
pub committed_on: Result<jiff::Timestamp, String>,
}

impl TryFrom<gix::Commit<'_>> for RawCommit {
type Error = anyhow::Error;

fn try_from(value: gix::Commit<'_>) -> Result<Self, Self::Error> {
let commit_author = value.author()?;
let author = Contributor {
name: commit_author.name.to_string(),
email: commit_author.email.to_string(),
};
let written_on =
jiff::Timestamp::from_second(commit_author.time.seconds).map_err(|x| x.to_string());
let commit_committer = value.committer()?;
let committer = Contributor {
name: commit_committer.name.to_string(),
email: commit_committer.email.to_string(),
};
let committed_on =
jiff::Timestamp::from_second(commit_committer.time.seconds).map_err(|x| x.to_string());

Ok(Self {
hash: value.id().to_string(),
author,
written_on,
committer,
committed_on,
})
}
}

/// Commits as understood in Hipcheck's data model.
Expand All @@ -39,12 +67,20 @@ pub struct RawCommit {
#[derive(Debug, Serialize, Clone, PartialEq, Eq, Hash, JsonSchema)]
pub struct Commit {
pub hash: String,

pub written_on: Result<String, String>,

pub committed_on: Result<String, String>,
}

impl From<RawCommit> for Commit {
fn from(value: RawCommit) -> Self {
Self {
hash: value.hash,
written_on: value.written_on.map(|x| x.to_string()),
committed_on: value.committed_on.map(|x| x.to_string()),
}
}
}

impl Display for Commit {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.hash)
Expand Down Expand Up @@ -98,39 +134,58 @@ pub struct CommitDiff {
pub diff: Diff,
}

impl CommitDiff {
pub fn new(commit: Commit, diff: Diff) -> Self {
Self { commit, diff }
}
}

impl Display for CommitDiff {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(
f,
"{} +{} -{}",
self.commit,
self.diff
.additions
.map(|n| n.to_string())
.as_deref()
.unwrap_or("<unknown>"),
self.diff
.deletions
.map(|n| n.to_string())
.as_deref()
.unwrap_or("<unknown>")
self.commit, self.diff.additions, self.diff.deletions
)
}
}

/// A set of changes in a commit.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
pub struct Diff {
pub additions: Option<i64>,
pub deletions: Option<i64>,
pub additions: i64,
pub deletions: i64,
pub file_diffs: Vec<FileDiff>,
}

/// A set of changes to a specific file in a commit.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
pub struct FileDiff {
pub file_name: Arc<String>,
pub additions: Option<i64>,
pub deletions: Option<i64>,
pub file_name: String,
pub additions: i64,
pub deletions: i64,
pub patch: String,
}

impl FileDiff {
pub fn new(file_name: String) -> Self {
Self {
file_name,
additions: 0,
deletions: 0,
patch: String::new(),
}
}

pub fn increment_additions(&mut self, additions: i64) {
self.additions += additions
}

pub fn increment_deletions(&mut self, deletions: i64) {
self.deletions += deletions
}

pub fn set_patch(&mut self, patch_data: String) {
self.patch = patch_data;
}
}
Loading

0 comments on commit c5c049e

Please sign in to comment.