Skip to content

Commit

Permalink
feat: complete rework of revspec and revwalk
Browse files Browse the repository at this point in the history
  • Loading branch information
oknozor committed Mar 7, 2024
1 parent 19a9303 commit 6a3b2db
Show file tree
Hide file tree
Showing 40 changed files with 1,838 additions and 1,421 deletions.
7 changes: 3 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,13 @@ mod test {
#[sealed_test]
fn create_commit_ok() -> Result<()> {
// Arrange
let repo = git_init_no_gpg()?;

run_cmd!(
git init;
echo changes > file;
git add .;
)?;

let repo = Repository::open(".")?;


// Act
let oid = repo.commit("feat: a test commit");

Expand Down
12 changes: 4 additions & 8 deletions src/bin/cog/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ mod mangen;

use std::fs;
use std::path::PathBuf;
use std::str::FromStr;

use cocogitto::conventional::changelog::template::{RemoteContext, Template};
use cocogitto::conventional::commit as conv_commit;
use cocogitto::conventional::version::IncrementCommand;
use cocogitto::git::revspec::RevspecPattern;

use cocogitto::log::filter::{CommitFilter, CommitFilters};
use cocogitto::log::output::Output;
use cocogitto::{CocoGitto, CommitHook, SETTINGS};
Expand Down Expand Up @@ -559,15 +558,12 @@ fn main() -> Result<()> {
Template::default()
};

let pattern = pattern
.as_deref()
.map(RevspecPattern::from_str)
.transpose()?;

// TODO: fallback to tag here
let pattern = pattern.as_deref().unwrap_or("..");
let result = match at {
Some(at) => cocogitto.get_changelog_at_tag(&at, template)?,
None => {
let changelog = cocogitto.get_changelog(pattern.unwrap_or_default(), true)?;
let changelog = cocogitto.get_changelog(pattern, true)?;
changelog.into_markdown(template)?
}
};
Expand Down
39 changes: 15 additions & 24 deletions src/command/bump/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::conventional::changelog::release::Release;
use crate::conventional::commit::Commit;
use crate::git::error::TagError;
use crate::git::oid::OidOf;
use crate::git::revspec::RevspecPattern;

use crate::git::tag::Tag;
use crate::hook::{Hook, HookVersion, Hooks};
use crate::settings::{HookType, MonoRepoPackage, Settings};
Expand Down Expand Up @@ -109,6 +109,14 @@ fn tag_or_fallback_to_zero(tag: Result<Tag, TagError>) -> Result<Tag> {
}

impl CocoGitto {
fn get_bump_revspec(&mut self, current_tag: &Tag) -> String {
if current_tag.is_zero() {
"..".to_string()
} else {
format!("{current_tag}..")
}
}

pub fn unwrap_or_stash_and_exit<T>(&mut self, tag: &Tag, result: Result<T>) -> T {
match result {
Ok(res) => res,
Expand Down Expand Up @@ -172,13 +180,8 @@ impl CocoGitto {
}

/// The target version is not created yet when generating the changelog.
pub fn get_changelog_with_target_version(
&self,
pattern: RevspecPattern,
tag: Tag,
) -> Result<Release> {
let commit_range = self.repository.get_commit_range(&pattern)?;

pub fn get_changelog_with_target_version(&self, pattern: &str, tag: Tag) -> Result<Release> {
let commit_range = self.repository.revwalk(pattern)?;
let mut release = Release::from(commit_range);
release.version = OidOf::Tag(tag);
Ok(release)
Expand All @@ -187,13 +190,13 @@ impl CocoGitto {
/// The target package version is not created yet when generating the changelog.
pub fn get_package_changelog_with_target_version(
&self,
pattern: RevspecPattern,
pattern: &str,
tag: Tag,
package: &str,
) -> Result<Release> {
let commit_range = self
.repository
.get_commit_range_for_package(&pattern, package)?;
.get_commit_range_for_package(pattern, package)?;

let mut release = Release::from(commit_range);
release.version = OidOf::Tag(tag);
Expand All @@ -203,12 +206,12 @@ impl CocoGitto {
/// The target global monorepo version is not created yet when generating the changelog.
pub fn get_monorepo_global_changelog_with_target_version(
&self,
pattern: RevspecPattern,
pattern: &str,
tag: Tag,
) -> Result<Release> {
let commit_range = self
.repository
.get_commit_range_for_monorepo_global(&pattern)?;
.get_commit_range_for_monorepo_global(pattern)?;

let mut release = Release::from(commit_range);
release.version = OidOf::Tag(tag);
Expand Down Expand Up @@ -298,18 +301,6 @@ impl CocoGitto {

Ok(())
}

fn get_revspec_for_tag(&mut self, tag: &Tag) -> Result<RevspecPattern> {
let origin = if tag.is_zero() {
self.repository.get_first_commit()?.to_string()
} else {
tag.oid_unchecked().to_string()
};

let target = self.repository.get_head_commit_oid()?.to_string();
let pattern = (origin.as_str(), target.as_str());
Ok(RevspecPattern::from(pattern))
}
}

impl Release<'_> {
Expand Down
32 changes: 21 additions & 11 deletions src/command/bump/monorepo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::conventional::changelog::ReleaseType;

use crate::conventional::version::{Increment, IncrementCommand};

use crate::git::tag::Tag;
use crate::git::tag::{Tag, TagLookUpOptions};
use crate::hook::HookVersion;
use crate::{settings, CocoGitto, SETTINGS};
use anyhow::Result;
Expand Down Expand Up @@ -188,7 +188,9 @@ impl CocoGitto {
.max();

// Get current global tag
let old = self.repository.get_latest_tag();
let old = self
.repository
.get_latest_tag(TagLookUpOptions::default().include_pre_release());
let old = tag_or_fallback_to_zero(old)?;
let mut tag = old.bump(
IncrementCommand::AutoMonoRepoGlobal(increment_from_package_bumps),
Expand Down Expand Up @@ -232,9 +234,9 @@ impl CocoGitto {
}

if !SETTINGS.disable_changelog {
let pattern = self.get_revspec_for_tag(&old)?;
let pattern = self.get_bump_revspec(&old);
let changelog =
self.get_monorepo_global_changelog_with_target_version(pattern, tag.clone())?;
self.get_monorepo_global_changelog_with_target_version(&pattern, tag.clone())?;

changelog.pretty_print_bump_summary()?;

Expand All @@ -251,7 +253,11 @@ impl CocoGitto {
)?;
}

let current = self.repository.get_latest_tag().map(HookVersion::new).ok();
let current = self
.repository
.get_latest_tag(TagLookUpOptions::default())
.map(HookVersion::new)
.ok();
let next_version = HookVersion::new(tag.clone());

let hook_result = self.run_hooks(
Expand Down Expand Up @@ -341,7 +347,7 @@ impl CocoGitto {
let bumps = self.get_current_packages()?;

// Get current global tag
let old = self.repository.get_latest_tag();
let old = self.repository.get_latest_tag(TagLookUpOptions::default());
let old = tag_or_fallback_to_zero(old)?;
let mut tag = old.bump(increment, &self.repository)?;
ensure_tag_is_greater_than_previous(&old, &tag)?;
Expand All @@ -368,9 +374,9 @@ impl CocoGitto {
}

if !SETTINGS.disable_changelog {
let pattern = self.get_revspec_for_tag(&old)?;
let pattern = self.get_bump_revspec(&old);
let changelog =
self.get_monorepo_global_changelog_with_target_version(pattern, tag.clone())?;
self.get_monorepo_global_changelog_with_target_version(&pattern, tag.clone())?;

changelog.pretty_print_bump_summary()?;

Expand All @@ -387,7 +393,11 @@ impl CocoGitto {
)?;
}

let current = self.repository.get_latest_tag().map(HookVersion::new).ok();
let current = self
.repository
.get_latest_tag(TagLookUpOptions::default())
.map(HookVersion::new)
.ok();
let next_version = HookVersion::new(tag.clone());

let hook_result = self.run_hooks(
Expand Down Expand Up @@ -533,15 +543,15 @@ impl CocoGitto {
}

let tag = Tag::create(next_version.version, Some(package_name.to_string()));
let pattern = self.get_revspec_for_tag(&old)?;
let pattern = self.get_bump_revspec(&old);

let package = SETTINGS
.packages
.get(package_name.as_str())
.expect("package exists");

let changelog = self.get_package_changelog_with_target_version(
pattern,
&pattern,
tag.clone(),
package_name.as_str(),
)?;
Expand Down
9 changes: 6 additions & 3 deletions src/command/bump/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,12 @@ impl CocoGitto {
}

if !SETTINGS.disable_changelog {
let pattern = self.get_revspec_for_tag(&current_tag)?;
let changelog =
self.get_package_changelog_with_target_version(pattern, tag.clone(), package_name)?;
let pattern = self.get_bump_revspec(&current_tag);
let changelog = self.get_package_changelog_with_target_version(
&pattern,
tag.clone(),
package_name,
)?;

changelog.pretty_print_bump_summary()?;

Expand Down
15 changes: 10 additions & 5 deletions src/command/bump/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::command::bump::{

use crate::conventional::changelog::ReleaseType;
use crate::conventional::version::IncrementCommand;
use crate::git::tag::Tag;

use crate::git::tag::{Tag, TagLookUpOptions};
use crate::hook::HookVersion;
use crate::{settings, CocoGitto, SETTINGS};
use anyhow::Result;
Expand All @@ -28,7 +29,7 @@ impl CocoGitto {
) -> Result<()> {
self.pre_bump_checks(skip_untracked)?;

let current_tag = self.repository.get_latest_tag();
let current_tag = self.repository.get_latest_tag(TagLookUpOptions::default());
let current_tag = tag_or_fallback_to_zero(current_tag)?;
let mut tag = current_tag.bump(increment, &self.repository)?;
if current_tag == tag {
Expand All @@ -49,10 +50,10 @@ impl CocoGitto {
return Ok(());
}

let pattern = self.get_revspec_for_tag(&current_tag)?;
let pattern = self.get_bump_revspec(&current_tag);

if !SETTINGS.disable_changelog {
let changelog = self.get_changelog_with_target_version(pattern, tag.clone())?;
let changelog = self.get_changelog_with_target_version(&pattern, tag.clone())?;
changelog.pretty_print_bump_summary()?;

let path = settings::changelog_path();
Expand All @@ -61,7 +62,11 @@ impl CocoGitto {
changelog.write_to_file(path, template, ReleaseType::Standard)?;
}

let current = self.repository.get_latest_tag().map(HookVersion::new).ok();
let current = self
.repository
.get_latest_tag(TagLookUpOptions::default())
.map(HookVersion::new)
.ok();

let next_version = HookVersion::new(tag.clone());

Expand Down
24 changes: 5 additions & 19 deletions src/command/changelog.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,21 @@
use crate::conventional::changelog::release::Release;
use crate::conventional::changelog::template::Template;
use crate::git::revspec::RevspecPattern;

use crate::CocoGitto;
use anyhow::anyhow;
use anyhow::Result;
use std::str::FromStr;

impl CocoGitto {
/// ## Get a changelog between two oids
/// - `from` default value:latest tag or else first commit
/// - `to` default value:`HEAD` or else first commit
pub fn get_changelog(
&self,
pattern: RevspecPattern,
with_child_releases: bool,
) -> Result<Release> {
if with_child_releases {
self.repository
.get_release_range(pattern)
.map_err(Into::into)
} else {
let commit_range = self.repository.get_commit_range(&pattern)?;

Ok(Release::from(commit_range))
}
pub fn get_changelog(&self, pattern: &str, _with_child_releases: bool) -> Result<Release> {
let commit_range = self.repository.revwalk(pattern)?;
Ok(Release::from(commit_range))
}

pub fn get_changelog_at_tag(&self, tag: &str, template: Template) -> Result<String> {
let pattern = format!("..{tag}");
let pattern = RevspecPattern::from_str(pattern.as_str())?;
let changelog = self.get_changelog(pattern, false)?;
let changelog = self.get_changelog(tag, false)?;

changelog
.into_markdown(template)
Expand Down
23 changes: 11 additions & 12 deletions src/command/check.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::conventional::commit::Commit;
use crate::error::CogCheckReport;
use crate::git::revspec::RevspecPattern;

use crate::git::tag::TagLookUpOptions;
use crate::CocoGitto;
use anyhow::anyhow;
use anyhow::Result;
use colored::*;
use log::info;
use std::str::FromStr;

impl CocoGitto {
pub fn check(
Expand All @@ -16,27 +16,26 @@ impl CocoGitto {
range: Option<String>,
) -> Result<()> {
let commit_range = if let Some(range) = range {
self.repository
.get_commit_range(&RevspecPattern::from_str(range.as_str())?)?
self.repository.revwalk(&range)?
} else if check_from_latest_tag {
self.repository
.get_commit_range(&RevspecPattern::default())?
let tag = self
.repository
.get_latest_tag(TagLookUpOptions::default())?;
self.repository.revwalk(&format!("{tag}.."))?
} else {
self.repository.all_commits()?
self.repository.revwalk("..")?
};

let errors: Vec<_> = if ignore_merge_commits {
commit_range
.commits
.iter()
.iter_commits()
.filter(|commit| commit.parent_count() <= 1)
.map(Commit::from_git_commit)
.filter_map(Result::err)
.collect()
} else {
commit_range
.commits
.iter()
.iter_commits()
.map(Commit::from_git_commit)
.filter_map(Result::err)
.collect()
Expand All @@ -48,7 +47,7 @@ impl CocoGitto {
Ok(())
} else {
let report = CogCheckReport {
from: commit_range.from,
from: commit_range.from_oid(),
errors: errors.into_iter().map(|err| *err).collect(),
};
Err(anyhow!("{}", report))
Expand Down
Loading

0 comments on commit 6a3b2db

Please sign in to comment.