Skip to content

Commit

Permalink
feature(config): improve support for backwards compatability
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyclonit committed Apr 14, 2024
1 parent 02bf5bb commit bd225f3
Show file tree
Hide file tree
Showing 15 changed files with 495 additions and 314 deletions.
128 changes: 74 additions & 54 deletions .github/actions/run-fixtures-test/action.yml
Original file line number Diff line number Diff line change
@@ -1,54 +1,74 @@
name: Run a fixtures test
description: Run a fixtures test

inputs:
fixtures-dir:
description: Path to the fixtures directory
required: true
command:
description: The git-cliff command to run
required: false
default: ""
date-format:
description: The date format to use
required: false
default: "%Y-%m-%d"

runs:
using: composite
steps:
- name: Install toolchain
uses: dtolnay/rust-toolchain@nightly

- name: Install git-cliff
run: cargo install --path git-cliff/
shell: bash

- name: Set git config
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
shell: bash

- name: Create commits and tags
working-directory: ${{ inputs.fixtures-dir }}
run: |
git init
./commit.sh
shell: bash

- name: Generate a changelog
working-directory: ${{ inputs.fixtures-dir }}
run: git cliff --config cliff.toml ${{ inputs.command }} > output.md
shell: bash

- name: Compare the output with the expected output
working-directory: ${{ inputs.fixtures-dir }}
env:
IN_DATE_FORMAT: ${{ inputs.date-format }}
run: |
cat output.md
current_date=$(date +"$IN_DATE_FORMAT")
sed -i "s/<<DATE>>/$current_date/g" expected.md
diff --strip-trailing-cr output.md expected.md
shell: bash
name: Run a fixtures test
description: Run a fixtures test

inputs:
fixtures-dir:
description: Path to the fixtures directory
required: true
command:
description: The git-cliff command to run
required: false
default: ""
date-format:
description: The date format to use
required: false
default: "%Y-%m-%d"

runs:
using: composite
steps:
- name: Install toolchain
uses: dtolnay/rust-toolchain@nightly

- name: Install git-cliff
run: cargo install --path git-cliff/
shell: bash

- name: Set git config
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
shell: bash

- name: Create commits and tags
working-directory: ${{ inputs.fixtures-dir }}
run: |
git init
./commit.sh
shell: bash

- name: Generate a changelog
working-directory: ${{ inputs.fixtures-dir }}
run: git cliff --config cliff.toml ${{ inputs.command }} > output.md
shell: bash

- name: Compare the output with the expected output
working-directory: ${{ inputs.fixtures-dir }}
env:
IN_DATE_FORMAT: ${{ inputs.date-format }}
run: |
cat output.md
current_date=$(date +"$IN_DATE_FORMAT")
sed -i "s/<<DATE>>/$current_date/g" expected.md
diff --strip-trailing-cr output.md expected.md
shell: bash

# test backwards compatibility using v1 confiuration

- name: Generate a chanlog using v1 configuration
if: ${{ hashFiles(format('{0}/cliff.v1.toml', inputs.fixtures-dir)) }}
working-directory: ${{ inputs.fixtures-dir }}
run: git-cliff --config cliff.v1.toml --config-version 1 ${{ inputs.command }} > output.md
shell: bash

- name: Compare the v1 configuration output with the expected output
if: ${{ hashFiles(format('{0}/cliff.v1.toml', inputs.fixtures-dir)) }}
working-directory: ${{ inputs.fixtures-dir }}
env:
IN_DATE_FORMAT: ${{ inputs.date-format }}
run: |
cat output.md
current_date=$(date +"$IN_DATE_FORMAT")
sed -i "s/<<DATE>>/$current_date/g" expected.md
diff --strip-trailing-cr output.md expected.md
shell: bash
27 changes: 27 additions & 0 deletions .github/fixtures/test-bump-version/cliff.v1.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[changelog]
# changelog header
header = """
# Changelog\n
All notable changes to this project will be documented in this file.\n
"""
# template for the changelog body
# https://keats.github.io/tera/docs/#introduction
body = """
{% if version %}\
## [{{ version | trim_start_matches(pat="v") }}]
{% else %}\
## [unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits %}
- {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\
{% endfor %}
{% endfor %}\n
"""
# template for the changelog footer
footer = """
<!-- generated by git-cliff -->
"""
# remove the leading and trailing whitespace from the templates
trim = true
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 20 additions & 5 deletions git-cliff-core/src/changelog.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use crate::commit::Commit;
use crate::config::models_v2::Config;
use crate::config::models_v2::{
ChangelogConfig,
CommitConfig,
Config,
};
use crate::error::Result;
#[cfg(feature = "github")]
use crate::github::{
Expand Down Expand Up @@ -60,9 +64,10 @@ impl<'a> Changelog<'a> {
/// Processes a single commit and returns/logs the result.
fn process_commit(
commit: Commit<'a>,
git_config: &GitConfig,
changelog_config: &ChangelogConfig,
commit_config: &CommitConfig,
) -> Option<Commit<'a>> {
match commit.process(git_config) {
match commit.process(changelog_config, commit_config) {
Ok(commit) => Some(commit),
Err(e) => {
trace!(
Expand All @@ -85,7 +90,13 @@ impl<'a> Changelog<'a> {
.commits
.iter()
.cloned()
.filter_map(|commit| Self::process_commit(commit, &self.config.git))
.filter_map(|commit| {
Self::process_commit(
commit,
&self.config.changelog,
&self.config.commit,
)
})
.flat_map(|commit| {
if self.config.commit.split_by_newline.unwrap_or(false) {
commit
Expand All @@ -95,7 +106,11 @@ impl<'a> Changelog<'a> {
let mut c = commit.clone();
c.message = line.to_string();
if !c.message.is_empty() {
Self::process_commit(c, &self.config.git)
Self::process_commit(
c,
&self.config.changelog,
&self.config.commit
)
} else {
None
}
Expand Down
6 changes: 3 additions & 3 deletions git-cliff-core/src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ impl Commit<'_> {
if let Some(preprocessors) = &commit_config.message_preprocessors {
commit = commit.preprocess(preprocessors)?;
}
if config.parse_conventional_commits.unwrap_or(true) {
if config.exclude_unconventional_commits.unwrap_or(true) &&
!config.split_commits.unwrap_or(false)
if commit_config.parse_conventional_commits.unwrap_or(true) {
if commit_config.exclude_unconventional_commits.unwrap_or(true) &&
!commit_config.split_by_newline.unwrap_or(false)
{
commit = commit.into_conventional()?;
} else if let Ok(conv_commit) = commit.clone().into_conventional() {
Expand Down
103 changes: 103 additions & 0 deletions git-cliff-core/src/config/embed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use super::DEFAULT_CONFIG_FILENAME;
use crate::error::{
Error,
Result,
};
use regex::{
Regex,
RegexBuilder,
};
use rust_embed::RustEmbed;
use std::fs;
use std::{
path::PathBuf,
str,
};

/// Manifest file information and regex for matching contents.
#[derive(Debug)]
struct ManifestInfo {
/// Path of the manifest.
path: PathBuf,
/// Regular expression for matching metadata in the manifest.
regex: Regex,
}

lazy_static::lazy_static! {
/// Array containing manifest information for Rust and Python projects.
static ref MANIFEST_INFO: Vec<ManifestInfo> = vec![
ManifestInfo {
path: PathBuf::from("Cargo.toml"),
regex: RegexBuilder::new(
r"^\[(?:workspace|package)\.metadata\.git\-cliff\.",
)
.multi_line(true)
.build()
.expect("failed to build regex"),
},
ManifestInfo {
path: PathBuf::from("pyproject.toml"),
regex: RegexBuilder::new(r"^\[(?:tool)\.git\-cliff\.")
.multi_line(true)
.build()
.expect("failed to build regex"),
},
];

}

/// Reads the config file contents from project manifest (e.g. Cargo.toml,
/// pyproject.toml)
pub fn read_from_manifest() -> Result<Option<String>> {
for info in (*MANIFEST_INFO).iter() {
if info.path.exists() {
let contents = fs::read_to_string(&info.path)?;
if info.regex.is_match(&contents) {
return Ok(Some(info.regex.replace_all(&contents, "[").to_string()));
}
}
}
Ok(None)
}

/// Default configuration file embedder/extractor.
///
/// Embeds `config/`[`DEFAULT_CONFIG`] into the binary.
///
/// [`DEFAULT_CONFIG`]: crate::DEFAULT_CONFIG
#[derive(Debug, RustEmbed)]
#[folder = "../config/"]
pub struct EmbeddedConfig;

impl EmbeddedConfig {
/// Extracts the embedded content.
pub fn get_config_str() -> Result<String> {
match Self::get(DEFAULT_CONFIG_FILENAME) {
Some(v) => Ok(str::from_utf8(&v.data)?.to_string()),
None => Err(Error::EmbeddedError(String::from(
"Embedded config not found",
))),
}
}
}

/// Built-in configuration file embedder/extractor.
///
/// Embeds the files under `/examples/` into the binary.
#[derive(RustEmbed)]
#[folder = "../examples/"]
pub struct BuiltinConfig;

impl BuiltinConfig {
/// Extracts the embedded content.
pub fn get_config_str(mut name: String) -> Result<(String, String)> {
if !name.ends_with(".toml") {
name = format!("{name}.toml");
}
let contents = match Self::get(&name) {
Some(v) => Ok(str::from_utf8(&v.data)?.to_string()),
None => Err(Error::EmbeddedError(format!("config {} not found", name,))),
}?;
Ok((contents, name))
}
}
9 changes: 9 additions & 0 deletions git-cliff-core/src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
/// Embedded file handler.
pub mod embed;
/// Provide a command to migrate from old to new configuration.
pub mod migrate;
/// Base confih models for git-cliff.
pub mod models_base;
/// Deprecated Config models for git-cliff.
pub mod models_v1;
/// Current Config models for git-cliff.
Expand All @@ -9,3 +13,8 @@ pub mod parsing;
/// Tests for git-cliff Config.
#[cfg(test)]
pub mod test;

/// Default configuration file.
pub const DEFAULT_CONFIG_FILENAME: &str = "cliff.toml";
/// Default configuration version.
pub const DEFAULT_CONFIG_VERSION: i64 = 2;
11 changes: 11 additions & 0 deletions git-cliff-core/src/config/models_base.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use serde::{
Deserialize,
Serialize,
};

/// Meta section of the configuration file.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetaConfig {
/// The version of the config schema.
pub version: Option<i64>,
}
7 changes: 5 additions & 2 deletions git-cliff-core/src/config/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use super::models_v2::{
Config,
Remote,
};
use crate::config::parsing;
use crate::config::{
parsing,
DEFAULT_CONFIG_FILENAME,
};
use crate::error::Result;
use std::env;
use std::path::PathBuf;
Expand All @@ -14,7 +17,7 @@ fn parse_config() -> Result<()> {
.expect("parent directory not found")
.to_path_buf()
.join("config")
.join(crate::DEFAULT_CONFIG_FILENAME);
.join(DEFAULT_CONFIG_FILENAME);

const FOOTER_VALUE: &str = "test";
const RELEASE_TAGS_PATTERN_VALUE: &str = ".*[0-9].*";
Expand Down
Loading

0 comments on commit bd225f3

Please sign in to comment.