Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(lib): clean up some code #709

Merged
merged 9 commits into from
Aug 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions git-cliff-core/src/changelog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ impl<'a> Changelog<'a> {
}

/// Generates the changelog and writes it to the given output.
pub fn generate<W: Write>(&self, out: &mut W) -> Result<()> {
pub fn generate<W: Write + ?Sized>(&self, out: &mut W) -> Result<()> {
debug!("Generating changelog...");
let postprocessors = self
.config
Expand Down Expand Up @@ -567,7 +567,7 @@ impl<'a> Changelog<'a> {
}

/// Generates a changelog and prepends it to the given changelog.
pub fn prepend<W: Write>(
pub fn prepend<W: Write + ?Sized>(
&self,
mut changelog: String,
out: &mut W,
Expand All @@ -582,7 +582,7 @@ impl<'a> Changelog<'a> {
}

/// Prints the changelog context to the given output.
pub fn write_context<W: Write>(&self, out: &mut W) -> Result<()> {
pub fn write_context<W: Write + ?Sized>(&self, out: &mut W) -> Result<()> {
let output = Releases {
releases: &self.releases,
}
Expand Down
58 changes: 29 additions & 29 deletions git-cliff-core/src/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ impl Repository {
/// Sorts the commits by their time.
pub fn commits(
&self,
range: Option<String>,
include_path: Option<Vec<Pattern>>,
exclude_path: Option<Vec<Pattern>>,
range: Option<&str>,
include_path: Option<&[Pattern]>,
exclude_path: Option<&[Pattern]>,
) -> Result<Vec<Commit>> {
let mut revwalk = self.inner.revwalk()?;
revwalk.set_sorting(Sort::TOPOLOGICAL)?;
if let Some(range) = range {
revwalk.push_range(&range)?;
revwalk.push_range(range)?;
} else {
revwalk.push_head()?;
}
Expand All @@ -76,31 +76,31 @@ impl Repository {
.collect();
if include_path.is_some() || exclude_path.is_some() {
commits.retain(|commit| {
if let Ok(prev_commit) = commit.parent(0) {
if let Ok(diff) = self.inner.diff_tree_to_tree(
commit.tree().ok().as_ref(),
prev_commit.tree().ok().as_ref(),
None,
) {
return diff
.deltas()
.filter_map(|delta| delta.new_file().path())
.any(|new_file_path| {
if let Some(include_path) = &include_path {
include_path
.iter()
.any(|glob| glob.matches_path(new_file_path))
} else if let Some(exclude_path) = &exclude_path {
!exclude_path
.iter()
.any(|glob| glob.matches_path(new_file_path))
} else {
false
}
});
}
}
false
let Ok(prev_commit) = commit.parent(0) else {
return false;
};
let Ok(diff) = self.inner.diff_tree_to_tree(
commit.tree().ok().as_ref(),
prev_commit.tree().ok().as_ref(),
None,
) else {
return false;
};
diff.deltas()
.filter_map(|delta| delta.new_file().path())
.any(|new_file_path| {
if let Some(include_path) = include_path {
return include_path
.iter()
.any(|glob| glob.matches_path(new_file_path));
}
if let Some(exclude_path) = exclude_path {
return !exclude_path
.iter()
.any(|glob| glob.matches_path(new_file_path));
}
unreachable!()
})
});
}
Ok(commits)
Expand Down
171 changes: 75 additions & 96 deletions git-cliff/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,8 @@ use std::fs::{
self,
File,
};
use std::io::{
self,
Write,
};
use std::path::PathBuf;
use std::io;
use std::path::Path;
use std::time::{
SystemTime,
UNIX_EPOCH,
Expand Down Expand Up @@ -89,31 +86,28 @@ fn process_repository<'a>(
let mut tags = repository.tags(&config.git.tag_pattern, args.topo_order)?;
let skip_regex = config.git.skip_tags.as_ref();
let ignore_regex = config.git.ignore_tags.as_ref();
tags = tags
.into_iter()
.filter(|(_, tag)| {
let name = &tag.name;

// Keep skip tags to drop commits in the later stage.
let skip = skip_regex.map(|r| r.is_match(name)).unwrap_or_default();

let ignore = ignore_regex
.map(|r| {
if r.as_str().trim().is_empty() {
return false;
}
tags.retain(|_, tag| {
let name = &tag.name;

let ignore_tag = r.is_match(name);
if ignore_tag {
trace!("Ignoring release: {}", name)
}
ignore_tag
})
.unwrap_or_default();
// Keep skip tags to drop commits in the later stage.
let skip = skip_regex.is_some_and(|r| r.is_match(name));
if skip {
return true;
}

skip || !ignore
})
.collect();
let ignore = ignore_regex.is_some_and(|r| {
if r.as_str().trim().is_empty() {
return false;
}

let ignore_tag = r.is_match(name);
if ignore_tag {
trace!("Ignoring release: {}", name)
}
ignore_tag
});
!ignore
});

if !config.remote.github.is_set() {
match repository.upstream_remote() {
Expand Down Expand Up @@ -214,14 +208,12 @@ fn process_repository<'a>(
}
}
let mut commits = repository.commits(
commit_range,
args.include_path.clone(),
args.exclude_path.clone(),
commit_range.as_deref(),
args.include_path.as_deref(),
args.exclude_path.as_deref(),
)?;
if let Some(commit_limit_value) = config.git.limit_commits {
commits = commits
.drain(..commits.len().min(commit_limit_value))
.collect();
commits.truncate(commit_limit_value);
}

// Update tags.
Expand All @@ -240,27 +232,19 @@ fn process_repository<'a>(

// Process releases.
let mut releases = vec![Release::default()];
let mut release_index = 0;
let mut previous_release = Release::default();
let mut first_processed_tag = None;
for git_commit in commits.iter().rev() {
let release = releases.last_mut().unwrap();
let commit = Commit::from(git_commit);
let commit_id = commit.id.to_string();
releases[release_index].repository =
Some(repository.path.to_string_lossy().to_string());
if args.sort == Sort::Newest {
releases[release_index].commits.insert(0, commit);
} else {
releases[release_index].commits.push(commit);
}
release.commits.push(commit);
release.repository = Some(repository.path.to_string_lossy().into_owned());
if let Some(tag) = tags.get(&commit_id) {
let tag_name = &tag.name;

releases[release_index].version = Some(tag_name.clone());
releases[release_index].message = tag.message.clone();
releases[release_index].commit_id = Some(commit_id);
releases[release_index].timestamp = if args.tag == Some(tag_name.clone())
{
release.version = Some(tag.name.to_string());
release.message = tag.message.clone();
release.commit_id = Some(commit_id);
release.timestamp = if args.tag.as_deref() == Some(tag.name.as_str()) {
SystemTime::now()
.duration_since(UNIX_EPOCH)?
.as_secs()
Expand All @@ -272,27 +256,32 @@ fn process_repository<'a>(
first_processed_tag = Some(tag);
}
previous_release.previous = None;
releases[release_index].previous = Some(Box::new(previous_release));
previous_release = releases[release_index].clone();
release.previous = Some(Box::new(previous_release));
previous_release = release.clone();
releases.push(Release::default());
release_index += 1;
}
}

if release_index > 0 {
debug_assert!(!releases.is_empty());

if releases.len() > 1 {
previous_release.previous = None;
releases[release_index].previous = Some(Box::new(previous_release));
releases.last_mut().unwrap().previous = Some(Box::new(previous_release));
}

if args.sort == Sort::Newest {
for release in &mut releases {
release.commits.reverse();
}
}

// Add custom commit messages to the latest release.
if let Some(custom_commits) = &args.with_commit {
if let Some(latest_release) = releases.iter_mut().last() {
custom_commits.iter().for_each(|message| {
latest_release
.commits
.push(Commit::from(message.to_string()))
});
}
releases
.last_mut()
.unwrap()
.commits
.extend(custom_commits.iter().cloned().map(Commit::from));
}

// Set custom message for the latest release.
Expand All @@ -303,12 +292,11 @@ fn process_repository<'a>(
}

// Set the previous release if the first release does not have one set.
if !releases.is_empty() &&
releases
.first()
.and_then(|r| r.previous.as_ref())
.and_then(|p| p.version.as_ref())
.is_none()
if releases[0]
.previous
.as_ref()
.and_then(|p| p.version.as_ref())
.is_none()
{
// Get the previous tag of the first processed tag in the release loop.
let first_tag = first_processed_tag
Expand Down Expand Up @@ -553,6 +541,15 @@ pub fn run(mut args: Opt) -> Result<()> {
let mut changelog = Changelog::new(releases, &config)?;

// Print the result.
let mut out: Box<dyn io::Write> = if let Some(path) = &args.output {
if path == Path::new("-") {
Box::new(io::stdout())
} else {
Box::new(io::BufWriter::new(File::create(path)?))
}
} else {
Box::new(io::stdout())
};
if args.bump.is_some() || args.bumped_version {
let next_version = if let Some(next_version) = changelog.bump_version()? {
next_version
Expand All @@ -565,40 +562,22 @@ pub fn run(mut args: Opt) -> Result<()> {
return Ok(());
};
if args.bumped_version {
if let Some(path) = args.output {
let mut output = File::create(path)?;
output.write_all(next_version.as_bytes())?;
} else {
println!("{next_version}");
}
writeln!(out, "{next_version}")?;
return Ok(());
}
}
if args.context {
return if let Some(path) = args.output {
let mut output = File::create(path)?;
changelog.write_context(&mut output)
} else {
changelog.write_context(&mut io::stdout())
};
changelog.write_context(&mut out)?;
return Ok(());
}
if let Some(ref path) = args.prepend {
changelog.prepend(fs::read_to_string(path)?, &mut File::create(path)?)?;
if let Some(path) = &args.prepend {
let changelog_before = fs::read_to_string(path)?;
let mut out = io::BufWriter::new(File::create(path)?);
changelog.prepend(changelog_before, &mut out)?;
}
if let Some(path) = args.output {
let mut output: Box<dyn Write> = if path == PathBuf::from("-") {
Box::new(io::stdout())
} else {
Box::new(File::create(path)?)
};
if args.context {
changelog.write_context(&mut output)
} else {
changelog.generate(&mut output)
}
} else if args.prepend.is_none() {
changelog.generate(&mut io::stdout())
} else {
Ok(())
orhun marked this conversation as resolved.
Show resolved Hide resolved
if args.output.is_some() || args.prepend.is_none() {
changelog.generate(&mut out)?;
}

Ok(())
}
Loading