diff --git a/src/commands/version.rs b/src/commands/version.rs index 1d8ab13..24d8964 100644 --- a/src/commands/version.rs +++ b/src/commands/version.rs @@ -1,10 +1,12 @@ +use crate::trees::get_tree_skip; +use crate::versions::VersionBump; use anyhow::Result; use clap::Parser; use conventional_commit::ConventionalCommit; use git2::{Oid, Repository}; use semver::Version; use semver_bump_trait::SemverBump; -use slog::{debug, info}; +use slog::{debug, info, warn}; use std::cmp::Ordering; use std::collections::HashMap; use std::str::FromStr; @@ -15,14 +17,6 @@ use crate::tags::get_tag_map; #[derive(Debug, Parser)] pub struct VersionCommand {} -#[derive(Debug, Clone, PartialOrd, PartialEq)] -enum VersionBump { - None = 0, - Patch = 1, - Minor = 2, - Major = 3, -} - impl VersionCommand { pub async fn run(&self, log: slog::Logger) -> Result<()> { // Figure out the path we're searching and which one we found. @@ -67,7 +61,7 @@ impl VersionCommand { info!( log, - " checking {:?} entries, round {}", + "checking {:?} entries, round {}", &check_list.len(), count ); @@ -79,10 +73,7 @@ impl VersionCommand { // First check to see if we have a version for this commit. info!( log, - " checking oid {:?}, bump {:?}, depth {}", - oid, - bump, - depth + "checking oid {:?}, bump {:?}, depth {}", oid, bump, depth ); if let Some(tag_version) = &tag_map.get(&oid) { @@ -106,7 +97,7 @@ impl VersionCommand { info!( log, - " found tag {} + {:?} -> {}", + "found tag {} + {:?} -> {}", &tag_version, &bump, &bump_version @@ -124,30 +115,48 @@ impl VersionCommand { let message = commit.message().unwrap_or(""); let conv = ConventionalCommit::from_str(message)?; let commit_bump = self.get_version_bump(&conv); - let new_bump = match &bump > &commit_bump { - true => bump.clone(), - false => commit_bump.clone(), - }; let commit = &repo.find_commit(oid)?; let parent_count = commit.parent_count(); - debug!(log, " commit {:?}", commit.id()); - debug!(log, " message {:?}", message); - debug!(log, " type {:?}", conv.type_()); - debug!( - log, - " bump {:?} + {:?} -> {:?}", - &bump, - &commit_bump, - new_bump - ); - debug!(log, " parent_count {:?}", parent_count); + debug!(log, "commit {:?}", commit.id()); + debug!(log, "message {:?}", message); + debug!(log, "type {:?}", conv.type_()); + + // See what files were changed by this commit. If there is no + // bump, then we don't have to do this step at all. + let tree_skip = + get_tree_skip(log.clone(), &repo, &commit, &commit_bump)?; + + let new_bump = match tree_skip { + true => { + debug!(log, "no bump"); + bump + } + false => { + let tree_bump = match &bump > &commit_bump { + true => bump.clone(), + false => commit_bump.clone(), + }; + + debug!( + log, + "bump {:?} + {:?} -> {:?}", + &bump, + &commit_bump, + tree_bump + ); + + tree_bump + } + }; // Since we haven't found a tag, insert the entry into the new // list. + debug!(log, "parent_count {:?}", parent_count); + for parent in commit.parent_ids() { - debug!(log, " parent {:?}", parent); + debug!(log, "parent {:?}", parent); check_list.push((parent, new_bump.clone(), depth + 1)); } } diff --git a/src/main.rs b/src/main.rs index ce8813a..64d5ffd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,8 @@ use clap::Parser; mod commands; mod tags; +mod trees; +mod versions; #[tokio::main] async fn main() { diff --git a/src/trees.rs b/src/trees.rs new file mode 100644 index 0000000..1004815 --- /dev/null +++ b/src/trees.rs @@ -0,0 +1,48 @@ +use anyhow::Result; +use git2::{Commit, DiffOptions, Repository}; +use slog::{debug, warn, Logger}; + +use crate::versions::VersionBump; + +pub fn get_tree_skip( + log: Logger, + repo: &Repository, + commit: &Commit, + commit_bump: &VersionBump, +) -> Result { + // If we aren't bumping, then there is no reason to check. + if commit_bump == &VersionBump::None { + debug!(log, "no version bump, skipping tree"); + return Ok(true); + } + + // Get the tree. + let commit_tree = commit.tree()?; + + debug!(log, "checking tree {:?}", &commit_tree.id()); + + // Go through the parents so we can get a difference. + for parent in commit.parent_ids() { + // Get the parent information. + let parent_commit = &repo.find_commit(parent)?; + let parent_tree = parent_commit.tree()?; + + // Get the difference with the parents. + let mut opts = DiffOptions::new(); + let diff = repo.diff_tree_to_tree( + Some(&commit_tree), + Some(&parent_tree), + Some(&mut opts), + )?; + let deltas = diff.deltas(); + + for delta in deltas { + let old_file_path = delta.old_file().path().unwrap(); + let new_file_path = delta.new_file().path().unwrap(); + debug!(log, "old file {:?}", old_file_path); + debug!(log, "new file {:?}", new_file_path); + } + } + + Ok(false) +} diff --git a/src/versions.rs b/src/versions.rs new file mode 100644 index 0000000..51290bc --- /dev/null +++ b/src/versions.rs @@ -0,0 +1,7 @@ +#[derive(Debug, Clone, PartialOrd, PartialEq)] +pub enum VersionBump { + None = 0, + Patch = 1, + Minor = 2, + Major = 3, +}