Skip to content

Commit

Permalink
feat: cache multiple repos
Browse files Browse the repository at this point in the history
Signed-off-by: Aisha M <[email protected]>
  • Loading branch information
aamohd committed Jan 15, 2025
1 parent db74b94 commit 2369ebb
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 26 deletions.
22 changes: 22 additions & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion plugins/activity/local-plugin.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entrypoint {
}

dependencies {
plugin "mitre/git" version="0.2.0" manifest="./plugins/git/local-plugin.kdl"
plugin "mitre/git" version="0.3.0" manifest="./plugins/git/local-plugin.kdl"
}
2 changes: 1 addition & 1 deletion plugins/activity/plugin.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entrypoint {
}

dependencies {
plugin "mitre/git" version="0.2.0" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl"
plugin "mitre/git" version="0.3.0" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl"
}
2 changes: 1 addition & 1 deletion plugins/affiliation/local-plugin.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entrypoint {
}

dependencies {
plugin "mitre/git" version="0.2.0" manifest="./plugins/git/local-plugin.kdl"
plugin "mitre/git" version="0.3.0" manifest="./plugins/git/local-plugin.kdl"
}
2 changes: 1 addition & 1 deletion plugins/affiliation/plugin.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entrypoint {
}

dependencies {
plugin "mitre/git" version="0.2.0" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl"
plugin "mitre/git" version="0.3.0" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl"
}
2 changes: 1 addition & 1 deletion plugins/churn/local-plugin.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entrypoint {
}

dependencies {
plugin "mitre/git" version="0.2.0" manifest="./plugins/git/local-plugin.kdl"
plugin "mitre/git" version="0.3.0" manifest="./plugins/git/local-plugin.kdl"
}
2 changes: 1 addition & 1 deletion plugins/churn/plugin.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entrypoint {
}

dependencies {
plugin "mitre/git" version="0.2.0" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl"
plugin "mitre/git" version="0.3.0" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl"
}
2 changes: 1 addition & 1 deletion plugins/entropy/local-plugin.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entrypoint {
}

dependencies {
plugin "mitre/git" version="0.2.0" manifest="./plugins/git/local-plugin.kdl"
plugin "mitre/git" version="0.3.0" manifest="./plugins/git/local-plugin.kdl"
}
2 changes: 1 addition & 1 deletion plugins/entropy/plugin.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entrypoint {
}

dependencies {
plugin "mitre/git" version="0.2.0" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl"
plugin "mitre/git" version="0.3.0" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl"
}
2 changes: 2 additions & 0 deletions plugins/git/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ clap = { version = "4.5.23", features = ["derive"] }
hipcheck-sdk = { version = "0.3.0", path = "../../sdk/rust", features = [
"macros",
] }
lru = "0.12.5"
gix = { version = "0.69.1", default-features = false, features = [
"basic",
"max-control",
Expand All @@ -22,6 +23,7 @@ log = "0.4.22"
once_cell = "1.10.0"
schemars = { version = "0.8.21", features = ["url"] }
semver = "1.0.24"
serde_json = "1.0.134"
serde = { version = "1.0.215", features = ["derive", "rc"] }
tokio = { version = "1.42.0", features = ["rt"] }
which = { version = "7.0.1", default-features = false }
26 changes: 14 additions & 12 deletions plugins/git/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

use crate::data::*;

use crate::Error;
use crate::CACHE;
use anyhow::Context;
use anyhow::Result;
use gix::bstr::ByteSlice;
Expand All @@ -18,13 +20,12 @@ use gix::traverse::commit::simple::CommitTimeOrder;
use gix::ObjectId;
use gix::Repository;
use jiff::Timestamp;
use lru::LruCache;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Mutex;

/// used to cache all of the `RawCommit` from the last repo/HEAD combination analyzed by this
/// plugin
type GitRawCommitCache = Option<(PathBuf, ObjectId, Vec<RawCommit>)>;
pub type GitRawCommitCache = LruCache<(PathBuf, ObjectId), Vec<RawCommit>>;

/// retrieve a handle to the git repo at this path, as well as determine the commit hash of
/// HEAD
Expand Down Expand Up @@ -122,24 +123,25 @@ pub fn get_all_raw_commits<P>(repo_path: P) -> Result<Vec<RawCommit>>
where
P: AsRef<Path>,
{
// used to cache all of the RawCommits from the last repository analyzed
static ALL_RAW_COMMITS: Mutex<GitRawCommitCache> = Mutex::new(None);

let (repo, head_commit) = initialize_repo(repo_path.as_ref())?;
let mut cache = ALL_RAW_COMMITS.lock().unwrap();
let unlocked_cache = CACHE.get().ok_or(Error::UnspecifiedQueryState)?;
let mut cache = unlocked_cache
.lock()
.map_err(|_| Error::UnspecifiedQueryState)?;

// if there is a value in cache, and it is the same repo with the same HEAD commit, then we can use the
// cached value
if let Some(cached_value) = cache.as_ref() {
if cached_value.0 == repo_path.as_ref().to_path_buf() && cached_value.1 == head_commit {
return Ok(cached_value.2.clone());
}
if let Some(cached_value) = cache.get_mut(&(repo_path.as_ref().to_path_buf(), head_commit)) {
return Ok(cached_value.clone());
}

// otherwise the cache needs to be updated with the data from this repo_path/HEAD combination
let updated_value = get_all_raw_commits_inner(&repo, repo_path.as_ref(), head_commit)?;
let raw_commits = updated_value.2.clone();
*cache = Some(get_all_raw_commits_inner(&repo, repo_path, head_commit)?);
cache.put(
(repo_path.as_ref().to_path_buf(), head_commit),
raw_commits.clone(),
);
Ok(raw_commits)
}

Expand Down
36 changes: 32 additions & 4 deletions plugins/git/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,21 @@ use crate::{
},
git::{
get_all_raw_commits, get_commit_diffs, get_commits_from_date, get_contributors, get_diffs,
get_latest_commit,
get_latest_commit, GitRawCommitCache,
},
};
use clap::Parser;
use hipcheck_sdk::{prelude::*, types::LocalGitRepo};
use jiff::Timestamp;
use lru::LruCache;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::{
num::NonZero,
sync::{Mutex, OnceLock},
};

pub static CACHE: OnceLock<Mutex<GitRawCommitCache>> = OnceLock::new();

/// A locally stored git repo, with a list of additional details
/// The details will vary based on the query (e.g. a date, a committer e-mail address, a commit hash)
Expand Down Expand Up @@ -428,16 +435,37 @@ async fn commit_contributors(
Ok(commit_contributors)
}

#[derive(Clone, Debug)]
#[derive(Deserialize)]
struct Config {
#[serde(default = "default_commit_cache_size")]
commit_cache_size: usize,
}

fn default_commit_cache_size() -> usize {
1
}

#[derive(Clone, Debug, Default)]
struct GitPlugin;

impl Plugin for GitPlugin {
const PUBLISHER: &'static str = "mitre";

const NAME: &'static str = "git";

fn set_config(&self, _config: Value) -> std::result::Result<(), ConfigError> {
Ok(())
fn set_config(&self, config: Value) -> std::result::Result<(), ConfigError> {
// Deserialize and validate the config struct
let conf: Config =
serde_json::from_value::<Config>(config).map_err(|e| ConfigError::Unspecified {
message: e.to_string(),
})?;
let cache_size = conf.commit_cache_size;

CACHE
.set(Mutex::new(LruCache::new(NonZero::new(cache_size).unwrap())))
.map_err(|_e| ConfigError::Unspecified {
message: "config was already set".to_owned(),
})
}

fn default_policy_expr(&self) -> hipcheck_sdk::prelude::Result<String> {
Expand Down
2 changes: 1 addition & 1 deletion plugins/identity/local-plugin.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entrypoint {
}

dependencies {
plugin "mitre/git" version="0.2.0" manifest="./plugins/git/local-plugin.kdl"
plugin "mitre/git" version="0.3.0" manifest="./plugins/git/local-plugin.kdl"
}
2 changes: 1 addition & 1 deletion plugins/identity/plugin.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entrypoint {
}

dependencies {
plugin "mitre/git" version="0.2.0" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl"
plugin "mitre/git" version="0.3.0" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl"
}
6 changes: 6 additions & 0 deletions site/content/docs/guide/plugins/mitre-git.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ extra:

Provides access to Git commit history data. Does not define a default query
and can't be used as a top-level plugin in a policy file.

## Configuration

| Parameter | Type | Explanation |
|:--------------------|:--------|:--------------|
| `commit-cache-size` | `Integer` | Optional number of repositories to retain in cache. Defaults to one. |

0 comments on commit 2369ebb

Please sign in to comment.