Skip to content

Commit

Permalink
refactor(git): split repository in multiple modules
Browse files Browse the repository at this point in the history
  • Loading branch information
oknozor committed Nov 30, 2021
1 parent 4616065 commit 5ce5187
Show file tree
Hide file tree
Showing 14 changed files with 496 additions and 474 deletions.
11 changes: 5 additions & 6 deletions src/conventional/changelog/release.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use conventional_commit_parser::commit::Footer;
use serde::Serialize;

use crate::conventional::commit::Commit;

use crate::{settings, OidOf};
use crate::git::oid::OidOf;
use crate::settings;

#[derive(Serialize)]
pub struct Release<'a> {
Expand Down Expand Up @@ -49,16 +49,15 @@ impl<'a> From<&'a Footer> for ChangelogFooter<'a> {
mod test {
use chrono::Utc;
use conventional_commit_parser::commit::{CommitType, ConventionalCommit, Footer};

use git2::Oid;
use indoc::indoc;
use speculoos::prelude::*;

use crate::conventional::changelog::release::{ChangelogCommit, Release};
use crate::conventional::changelog::renderer::Renderer;
use crate::conventional::commit::Commit;
use crate::git::oid::OidOf;
use crate::git::tag::Tag;
use crate::OidOf;
use git2::Oid;
use indoc::indoc;

#[test]
fn should_render_default_template() {
Expand Down
6 changes: 3 additions & 3 deletions src/conventional/changelog/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use serde::ser::SerializeStruct;
use serde::{Serialize, Serializer};

use crate::conventional::changelog::release::{ChangelogCommit, ChangelogFooter};

use crate::git::oid::OidOf;
use crate::git::tag::Tag;
use crate::{OidOf, COMMITS_METADATA};
use crate::COMMITS_METADATA;

impl Serialize for Tag {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
Expand Down Expand Up @@ -70,12 +70,12 @@ impl Serialize for OidOf {
mod test {
use chrono::Utc;
use conventional_commit_parser::commit::{CommitType, ConventionalCommit, Footer};
use git2::Oid;
use speculoos::prelude::*;

use crate::conventional::changelog::release::ChangelogCommit;
use crate::conventional::commit::Commit;
use crate::git::tag::Tag;
use git2::Oid;

#[test]
fn should_serialize_tag() {
Expand Down
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt::{self, Debug, Display, Formatter};

use crate::OidOf;
use crate::git::oid::OidOf;

use colored::*;

Expand Down
77 changes: 77 additions & 0 deletions src/git/commit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use crate::error::CocogittoError;
use crate::git::repository::Repository;
use anyhow::{anyhow, Result};
use git2::Oid;

impl Repository {
pub(crate) fn commit(&self, message: &str) -> Result<Oid> {
let sig = self.0.signature()?;
let tree_id = self.0.index()?.write_tree()?;
let tree = self.0.find_tree(tree_id)?;
let is_empty = self.0.is_empty()?;
let has_delta = self.get_diff(false).is_some();

if !is_empty && has_delta {
let head = &self.0.head()?;
let head_target = head.target().expect("Cannot get HEAD target");
let tip = &self.0.find_commit(head_target)?;

self.0
.commit(Some("HEAD"), &sig, &sig, message, &tree, &[tip])
.map_err(|err| anyhow!(err))
} else if is_empty && has_delta {
// First repo commit
self.0
.commit(Some("HEAD"), &sig, &sig, message, &tree, &[])
.map_err(|err| anyhow!(err))
} else {
let err = self
.get_branch_shorthand()
.map(|branch| CocogittoError::NothingToCommitWithBranch { branch })
.unwrap_or_else(|| CocogittoError::NothingToCommit);

Err(anyhow!(err))
}
}
}

#[cfg(test)]
mod test {
use crate::git::repository::Repository;
use crate::test_helpers::run_test_with_context;
use anyhow::Result;
use speculoos::prelude::*;

#[test]
fn create_commit_ok() -> Result<()> {
run_test_with_context(|context| {
let repo = Repository::init(".")?;
std::fs::write(context.test_dir.join("file"), "changes")?;
repo.add_all()?;

assert_that!(repo.commit("feat: a test commit")).is_ok();
Ok(())
})
}

#[test]
fn not_create_empty_commit() -> Result<()> {
run_test_with_context(|_| {
let repo = Repository::init(".")?;

assert_that!(repo.commit("feat: a test commit")).is_err();
Ok(())
})
}

#[test]
fn not_create_empty_commit_with_unstaged_changed() -> Result<()> {
run_test_with_context(|context| {
let repo = Repository::init(".")?;
std::fs::write(context.test_dir.join("file"), "changes")?;

assert_that!(repo.commit("feat: a test commit")).is_err();
Ok(())
})
}
}
80 changes: 80 additions & 0 deletions src/git/diff.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use crate::git::repository::Repository;
use git2::{Diff, DiffOptions};

impl Repository {
pub(crate) fn get_diff(&self, include_untracked: bool) -> Option<Diff> {
let mut options = DiffOptions::new();
options.include_untracked(include_untracked);

let diff = match &self.get_head() {
Some(head) => self
.0
.diff_tree_to_index(head.as_tree(), None, Some(&mut options)),
None => self
.0
.diff_tree_to_workdir_with_index(None, Some(&mut options)),
};

match diff {
Ok(diff) => {
if diff.deltas().len() > 0 {
Some(diff)
} else {
None
}
}
Err(..) => None,
}
}
}

#[cfg(test)]
mod test {
use crate::git::repository::Repository;
use crate::test_helpers::run_test_with_context;
use anyhow::Result;

#[test]
fn get_diff_some() -> Result<()> {
run_test_with_context(|context| {
let repo = Repository::init(".")?;
std::fs::write(context.test_dir.join("file"), "changes")?;
repo.add_all()?;

assert!(repo.get_diff(false).is_some());
Ok(())
})
}

#[test]
fn get_diff_none() -> Result<()> {
run_test_with_context(|context| {
let repo = Repository::init(".")?;
std::fs::write(context.test_dir.join("file"), "changes")?;

assert!(repo.get_diff(false).is_none());
Ok(())
})
}

#[test]
fn get_diff_include_untracked_some() -> Result<()> {
run_test_with_context(|context| {
let repo = Repository::init(".")?;
std::fs::write(context.test_dir.join("file"), "changes")?;

assert!(repo.get_diff(true).is_some());
Ok(())
})
}

#[test]
fn get_diff_include_untracked_none() -> Result<()> {
run_test_with_context(|_| {
let repo = Repository::init(".")?;

assert!(repo.get_diff(true).is_none());
Ok(())
})
}
}
4 changes: 2 additions & 2 deletions src/git/hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::CocoGitto;

use anyhow::{anyhow, Result};

pub static PRE_PUSH_HOOK: &[u8] = include_bytes!("assets/pre-push");
pub static PREPARE_COMMIT_HOOK: &[u8] = include_bytes!("assets/pre-commit");
pub(crate) static PRE_PUSH_HOOK: &[u8] = include_bytes!("assets/pre-push");
pub(crate) static PREPARE_COMMIT_HOOK: &[u8] = include_bytes!("assets/pre-commit");
const PRE_COMMIT_HOOK_PATH: &str = ".git/hooks/pre-commit";
const PRE_PUSH_HOOK_PATH: &str = ".git/hooks/pre-push";

Expand Down
4 changes: 4 additions & 0 deletions src/git/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
pub mod commit;
pub mod diff;
pub mod hook;
pub mod oid;
pub mod repository;
pub mod revspec;
pub mod stash;
pub mod status;
pub mod tag;
24 changes: 24 additions & 0 deletions src/git/oid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use std::fmt::{Display, Formatter};

use git2::Oid;

use crate::git::tag::Tag;

/// A wrapper for git2 oid including tags and HEAD ref
#[derive(Debug, PartialEq, Eq)]
pub enum OidOf {
Tag(Tag),
Head(Oid),
Other(Oid),
}

impl Display for OidOf {
/// Print the oid according to it's type
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
OidOf::Tag(tag) => write!(f, "{}", tag),
OidOf::Head(_) => write!(f, "HEAD"),
OidOf::Other(oid) => write!(f, "{}", &oid.to_string()[0..6]),
}
}
}
Loading

0 comments on commit 5ce5187

Please sign in to comment.