use std::borrow::Cow;
use git_workarea::GitContext;
use log::error;
use crate::context::CheckGitContext;
#[derive(Debug)]
pub struct SubmoduleContext<'a> {
pub name: Cow<'a, str>,
pub path: Cow<'a, str>,
pub url: Cow<'a, str>,
pub branch: Cow<'a, str>,
pub context: GitContext,
}
impl<'a> SubmoduleContext<'a> {
pub fn new(ctx: &'a CheckGitContext, diff_path: &str) -> Option<Self> {
ctx.submodule_config()
.iter()
.filter_map(|(name, config)| {
config
.get("url")
.and_then(|url| config.get("path").map(|path| (url, path)))
.and_then(|(url, path)| {
if path == diff_path {
let branch = config.get("branch").map(String::as_str);
Some((name, path, url, branch))
} else {
None
}
})
})
.next()
.map(|(name, path, url, branch)| {
let gitdir = ctx.gitdir().join("modules").join(name);
let context = GitContext::new(&gitdir);
let branch = if let Some(branch) = branch {
branch.into()
} else {
match context.default_branch() {
Ok(Some(branch)) => branch.into(),
Ok(None) => "master".into(),
Err(err) => {
error!(
"failed to determine the default branch in {}: {}",
gitdir.display(),
err,
);
"master".into()
},
}
};
SubmoduleContext {
name: name.into(),
path: path.into(),
url: url.into(),
branch,
context,
}
})
}
}
#[cfg(test)]
mod tests {
use std::path::Path;
use git_workarea::{CommitId, Identity};
use crate::context::CheckGitContext;
use crate::test::*;
use crate::utils::SubmoduleContext;
const DEFAULT_NAME_SUBMODULE: &str = "fe90ee22ae3ce4b4dc41f8d0876e59355ff1e21c";
const CUSTOM_NAME_SUBMODULE: &str = "4f645a7cc4c6a210193e1df5931f6336fa10459f";
fn make_submodule_context(path: &Path, commit: &CommitId) -> CheckGitContext {
let ctx = make_context_submodule(path, commit);
let workarea = ctx.prepare(commit).unwrap();
let who = Identity::new("Rust Git Checks Tests", "rust-git-checks@example.com");
CheckGitContext::new(workarea, who)
}
#[test]
fn test_submodule_context_no_exist() {
let tempdir = make_temp_dir();
let ctx = make_submodule_context(tempdir.path(), &CommitId::new(DEFAULT_NAME_SUBMODULE));
assert!(SubmoduleContext::new(&ctx, "no-submodule").is_none());
}
#[test]
fn test_submodule_context_default_name() {
let tempdir = make_temp_dir();
let ctx = make_submodule_context(tempdir.path(), &CommitId::new(DEFAULT_NAME_SUBMODULE));
let sub_ctx = SubmoduleContext::new(&ctx, "submodule").unwrap();
assert_eq!(sub_ctx.name, "submodule");
assert_eq!(sub_ctx.path, "submodule");
assert_eq!(
sub_ctx.url,
"https://gitlab.kitware.com/utils/test-repo.git",
);
assert_eq!(sub_ctx.branch, "master");
assert_eq!(
sub_ctx.context.gitdir(),
tempdir.path().join("origin/.git/modules/submodule"),
);
}
#[test]
fn test_submodule_context_custom_name() {
let tempdir = make_temp_dir();
let ctx = make_submodule_context(tempdir.path(), &CommitId::new(CUSTOM_NAME_SUBMODULE));
let sub_ctx = SubmoduleContext::new(&ctx, "submodule").unwrap();
assert_eq!(sub_ctx.name, "custom-name");
assert_eq!(sub_ctx.path, "submodule");
assert_eq!(
sub_ctx.url,
"https://gitlab.kitware.com/utils/test-repo.git",
);
assert_eq!(sub_ctx.branch, "master");
assert_eq!(
sub_ctx.context.gitdir(),
tempdir.path().join("origin/.git/modules/custom-name"),
);
}
}