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: initialize config structs with default values #1090

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
8 changes: 8 additions & 0 deletions config/cliff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ footer = """
"""
# Remove leading and trailing whitespaces from the changelog's body.
trim = true
# Render body even when there are no releases to process.
render_always = true
# An array of regex based postprocessors to modify the changelog.
postprocessors = [
# Replace the placeholder <REPO> with a URL.
Expand Down Expand Up @@ -62,6 +64,8 @@ commit_preprocessors = [
# If the spelling is incorrect, it will be fixed automatically.
#{ pattern = '.*', replace_command = 'typos --write-changes -' },
]
# Prevent commits that are breaking from being excluded by commit parsers.
protect_breaking_commits = false
# An array of regex based parsers for extracting data from the commit message.
# Assigns commits to groups.
# Optionally sets the commit's scope and can decide to exclude commits from further processing.
Expand All @@ -84,6 +88,10 @@ commit_parsers = [
]
# Exclude commits that are not matched by any commit parser.
filter_commits = false
# An array of link parsers for extracting external references, and turning them into URLs, using regex.
link_parsers = []
# Include only the tags that belong to the current branch.
use_branch_tags = false
# Order releases topologically instead of chronologically.
topo_order = false
# Order of commits in each group/release within the changelog.
Expand Down
88 changes: 39 additions & 49 deletions git-cliff-core/src/changelog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl<'a> Changelog<'a> {

/// Builds a changelog from releases and config.
fn build(releases: Vec<Release<'a>>, config: &'a Config) -> Result<Self> {
let trim = config.changelog.trim.unwrap_or(true);
let trim = config.changelog.trim;
Ok(Self {
releases,
header_template: match &config.changelog.header {
Expand Down Expand Up @@ -127,7 +127,7 @@ impl<'a> Changelog<'a> {
.cloned()
.filter_map(|commit| Self::process_commit(&commit, &self.config.git))
.flat_map(|commit| {
if self.config.git.split_commits.unwrap_or(false) {
if self.config.git.split_commits {
commit
.message
.lines()
Expand All @@ -148,7 +148,7 @@ impl<'a> Changelog<'a> {
.collect::<Vec<Commit>>();
});

if self.config.git.require_conventional.unwrap_or(false) {
if self.config.git.require_conventional {
self.check_conventional_commits()?;
}

Expand Down Expand Up @@ -203,7 +203,7 @@ impl<'a> Changelog<'a> {
}
match &release.previous {
Some(prev_release) if prev_release.commits.is_empty() => {
self.config.changelog.render_always.unwrap_or(false)
self.config.changelog.render_always
}
_ => false,
}
Expand Down Expand Up @@ -561,12 +561,7 @@ impl<'a> Changelog<'a> {
/// Generates the changelog and writes it to the given output.
pub fn generate<W: Write + ?Sized>(&self, out: &mut W) -> Result<()> {
debug!("Generating changelog...");
let postprocessors = self
.config
.changelog
.postprocessors
.clone()
.unwrap_or_default();
let postprocessors = self.config.changelog.postprocessors.clone();

if let Some(header_template) = &self.header_template {
let write_result = writeln!(
Expand Down Expand Up @@ -653,13 +648,7 @@ impl<'a> Changelog<'a> {
}

fn get_body_template(config: &Config, trim: bool) -> Result<Template> {
let template_str = config
.changelog
.body
.as_deref()
.unwrap_or_default()
.to_string();
let template = Template::new("body", template_str, trim)?;
let template = Template::new("body", config.changelog.body.clone(), trim)?;
let deprecated_vars = [
"commit.github",
"commit.gitea",
Expand Down Expand Up @@ -694,7 +683,7 @@ mod test {
let config = Config {
changelog: ChangelogConfig {
header: Some(String::from("# Changelog")),
body: Some(String::from(
body: String::from(
r#"{% if version %}
## Release [{{ version }}] - {{ timestamp | date(format="%Y-%m-%d") }} - ({{ repository }})
{% if commit_id %}({{ commit_id }}){% endif %}{% else %}
Expand All @@ -704,34 +693,34 @@ mod test {
#### {{ group }}{% for commit in commits %}
- {{ commit.message }}{% endfor %}
{% endfor %}{% endfor %}"#,
)),
),
footer: Some(String::from(
r#"-- total releases: {{ releases | length }} --"#,
)),
trim: Some(true),
postprocessors: Some(vec![TextProcessor {
trim: true,
postprocessors: vec![TextProcessor {
pattern: Regex::new("boring")
.expect("failed to compile regex"),
replace: Some(String::from("exciting")),
replace_command: None,
}]),
render_always: None,
}],
render_always: false,
output: None,
},
git: GitConfig {
conventional_commits: Some(true),
require_conventional: Some(false),
filter_unconventional: Some(false),
split_commits: Some(false),
commit_preprocessors: Some(vec![TextProcessor {
conventional_commits: true,
require_conventional: false,
filter_unconventional: false,
split_commits: false,
commit_preprocessors: vec![TextProcessor {
pattern: Regex::new("<preprocess>")
.expect("failed to compile regex"),
replace: Some(String::from(
"this commit is preprocessed",
)),
replace_command: None,
}]),
commit_parsers: Some(vec![
}],
commit_parsers: vec![
CommitParser {
sha: Some(String::from("tea")),
message: None,
Expand Down Expand Up @@ -864,17 +853,17 @@ mod test {
field: None,
pattern: None,
},
]),
protect_breaking_commits: None,
filter_commits: Some(false),
],
protect_breaking_commits: false,
filter_commits: false,
tag_pattern: None,
skip_tags: Regex::new("v3.*").ok(),
ignore_tags: None,
count_tags: None,
use_branch_tags: Some(false),
topo_order: Some(false),
sort_commits: Some(String::from("oldest")),
link_parsers: None,
use_branch_tags: false,
topo_order: false,
sort_commits: String::from("oldest"),
link_parsers: [].to_vec(),
limit_commits: None,
},
remote: RemoteConfig {
Expand Down Expand Up @@ -1150,14 +1139,17 @@ mod test {
#[test]
fn changelog_generator_split_commits() -> Result<()> {
let (mut config, mut releases) = get_test_data();
config.git.split_commits = Some(true);
config.git.filter_unconventional = Some(false);
config.git.protect_breaking_commits = Some(true);

if let Some(parsers) = config.git.commit_parsers.as_mut() {
for parser in parsers.iter_mut().filter(|p| p.footer.is_some()) {
parser.skip = Some(true);
}
config.git.split_commits = true;
config.git.filter_unconventional = false;
config.git.protect_breaking_commits = true;

for parser in config
.git
.commit_parsers
.iter_mut()
.filter(|p| p.footer.is_some())
{
parser.skip = Some(true);
}

releases[0].commits.push(Commit::new(
Expand Down Expand Up @@ -1280,8 +1272,7 @@ chore(deps): fix broken deps
fn changelog_adds_additional_context() -> Result<()> {
let (mut config, releases) = get_test_data();
// add `{{ custom_field }}` to the template
config.changelog.body = Some(
r#"{% if version %}
config.changelog.body = r#"{% if version %}
## {{ custom_field }} [{{ version }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% if commit_id %}({{ commit_id }}){% endif %}{% else %}
## Unreleased{% endif %}
Expand All @@ -1290,8 +1281,7 @@ chore(deps): fix broken deps
#### {{ group }}{% for commit in commits %}
- {{ commit.message }}{% endfor %}
{% endfor %}{% endfor %}"#
.to_string(),
);
.to_string();
let mut changelog = Changelog::new(releases, &config)?;
changelog.add_context("custom_field", "Hello")?;
let mut out = Vec::new();
Expand Down
33 changes: 15 additions & 18 deletions git-cliff-core/src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,29 +212,26 @@ impl Commit<'_> {
/// * extracts links and generates URLs
pub fn process(&self, config: &GitConfig) -> Result<Self> {
let mut commit = self.clone();
if let Some(preprocessors) = &config.commit_preprocessors {
commit = commit.preprocess(preprocessors)?;
}
if config.conventional_commits.unwrap_or(true) {
if !config.require_conventional.unwrap_or(false) &&
config.filter_unconventional.unwrap_or(true) &&
!config.split_commits.unwrap_or(false)
commit = commit.preprocess(&config.commit_preprocessors)?;
if config.conventional_commits {
if !config.require_conventional &&
config.filter_unconventional &&
!config.split_commits
{
commit = commit.into_conventional()?;
} else if let Ok(conv_commit) = commit.clone().into_conventional() {
commit = conv_commit;
}
}
if let Some(parsers) = &config.commit_parsers {
commit = commit.parse(
parsers,
config.protect_breaking_commits.unwrap_or(false),
config.filter_commits.unwrap_or(false),
)?;
}
if let Some(parsers) = &config.link_parsers {
commit = commit.parse_links(parsers)?;
}

commit = commit.parse(
&config.commit_parsers,
config.protect_breaking_commits,
config.filter_commits,
)?;

commit = commit.parse_links(&config.link_parsers)?;

Ok(commit)
}

Expand Down Expand Up @@ -555,7 +552,7 @@ mod test {
#[test]
fn conventional_footers() {
let cfg = crate::config::GitConfig {
conventional_commits: Some(true),
conventional_commits: true,
..Default::default()
};
let test_cases = vec![
Expand Down
39 changes: 23 additions & 16 deletions git-cliff-core/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::command;
use crate::embed::EmbeddedConfig;
use crate::error::Result;
use regex::{
Regex,
Expand Down Expand Up @@ -72,15 +73,15 @@ pub struct ChangelogConfig {
/// Changelog header.
pub header: Option<String>,
/// Changelog body, template.
pub body: Option<String>,
pub body: String,
/// Changelog footer.
pub footer: Option<String>,
/// Trim the template.
pub trim: Option<bool>,
pub trim: bool,
/// Always render the body template.
pub render_always: Option<bool>,
pub render_always: bool,
/// Changelog postprocessors.
pub postprocessors: Option<Vec<TextProcessor>>,
pub postprocessors: Vec<TextProcessor>,
/// Output file path.
pub output: Option<PathBuf>,
}
Expand All @@ -89,30 +90,30 @@ pub struct ChangelogConfig {
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct GitConfig {
/// Parse commits according to the conventional commits specification.
pub conventional_commits: Option<bool>,
pub conventional_commits: bool,
/// Require all commits to be conventional.
/// Takes precedence over filter_unconventional.
pub require_conventional: Option<bool>,
pub require_conventional: bool,
/// Exclude commits that do not match the conventional commits specification
/// from the changelog.
pub filter_unconventional: Option<bool>,
pub filter_unconventional: bool,
/// Split commits on newlines, treating each line as an individual commit.
pub split_commits: Option<bool>,
pub split_commits: bool,

/// An array of regex based parsers to modify commit messages prior to
/// further processing.
pub commit_preprocessors: Option<Vec<TextProcessor>>,
pub commit_preprocessors: Vec<TextProcessor>,
/// An array of regex based parsers for extracting data from the commit
/// message.
pub commit_parsers: Option<Vec<CommitParser>>,
pub commit_parsers: Vec<CommitParser>,
/// Prevent commits having the `BREAKING CHANGE:` footer from being excluded
/// by commit parsers.
pub protect_breaking_commits: Option<bool>,
pub protect_breaking_commits: bool,
/// An array of regex based parsers to extract links from the commit message
/// and add them to the commit's context.
pub link_parsers: Option<Vec<LinkParser>>,
pub link_parsers: Vec<LinkParser>,
/// Exclude commits that are not matched by any commit parser.
pub filter_commits: Option<bool>,
pub filter_commits: bool,
/// Regex to select git tags that represent releases.
#[serde(with = "serde_regex", default)]
pub tag_pattern: Option<Regex>,
Expand All @@ -126,11 +127,11 @@ pub struct GitConfig {
#[serde(with = "serde_regex", default)]
pub count_tags: Option<Regex>,
/// Include only the tags that belong to the current branch.
pub use_branch_tags: Option<bool>,
pub use_branch_tags: bool,
/// Order releases topologically instead of chronologically.
pub topo_order: Option<bool>,
pub topo_order: bool,
/// How to order commits in each group/release within the changelog.
pub sort_commits: Option<String>,
pub sort_commits: String,
/// Limit the total number of commits included in the changelog.
pub limit_commits: Option<usize>,
}
Expand Down Expand Up @@ -441,7 +442,13 @@ impl Config {
}
}

let default_config_str = EmbeddedConfig::get_config()?;

Ok(config::Config::builder()
.add_source(config::File::from_str(
&default_config_str,
config::FileFormat::Toml,
))
.add_source(config::File::from(path))
.add_source(
config::Environment::with_prefix("GIT_CLIFF").separator("__"),
Expand Down
Loading
Loading