summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-04-29 15:23:53 +0000
committerGitHub <noreply@github.com>2023-04-29 15:23:53 +0000
commit3685081a27cad1e4a403b34450356c3401727f56 (patch)
tree5dd5fe036b0b5153067b185553d5a027941174aa
parente520d935d465ced66d16afabb3bfb60aff33912d (diff)
parent2df5f3be5767f31ec07be3a446164741cd6276ed (diff)
Merge #230
230: Feature/import existing r=matthiasbeyer a=TheNeikos Solves #224 Co-authored-by: Marcel Müller <neikos@neikos.email>
-rw-r--r--.changelogs/template.md3
-rw-r--r--.changelogs/unreleased/2023-04-29T15_18_11_131678077.md5
-rw-r--r--.changelogs/unreleased/2023-04-29T15_19_10_88832722.md7
-rw-r--r--README.md26
-rw-r--r--assets/default_template.handlebars.md3
-rw-r--r--src/command/release_command.rs51
-rw-r--r--src/main.rs21
-rw-r--r--tests/init_command.rs18
-rw-r--r--tests/release_command.rs89
9 files changed, 214 insertions, 9 deletions
diff --git a/.changelogs/template.md b/.changelogs/template.md
index 3cf83f8..fe05a00 100644
--- a/.changelogs/template.md
+++ b/.changelogs/template.md
@@ -16,3 +16,6 @@
{{~ /each ~}}
{{~ /each ~}}
{{/if}}
+{{#if this.suffix}}
+{{this.suffix}}
+{{/if}}
diff --git a/.changelogs/unreleased/2023-04-29T15_18_11_131678077.md b/.changelogs/unreleased/2023-04-29T15_18_11_131678077.md
new file mode 100644
index 0000000..f92438f
--- /dev/null
+++ b/.changelogs/unreleased/2023-04-29T15_18_11_131678077.md
@@ -0,0 +1,5 @@
++++
+subject = "Appending to generated changelogs can now be done through a suffix.md file in the changelogs directory."
+type = "Feature"
++++
+
diff --git a/.changelogs/unreleased/2023-04-29T15_19_10_88832722.md b/.changelogs/unreleased/2023-04-29T15_19_10_88832722.md
new file mode 100644
index 0000000..c4d08fe
--- /dev/null
+++ b/.changelogs/unreleased/2023-04-29T15_19_10_88832722.md
@@ -0,0 +1,7 @@
++++
+subject = "The init subcommand now moves any existing CHANGELOG.md files to the suffix.md file"
+type = "Feature"
++++
+
+With this change, existing repositories will be able to keep their previous
+CHANGELOG and use the generated file from now on.
diff --git a/README.md b/README.md
index 5543a2e..939b7e0 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,23 @@ Changelog management tool for CLI.
`cargo-changelog` is a merge-friendly changelog management utility.
+## Getting Started
+
+⚠️ `cargo-changelog` is still in alpha and will change and evolve. Do not use it
+unless you are ready to, potentially manually, upgrade configuration and/or
+templates on a regular basis.
+
+With that out of the way, to get started with `cargo-changelog` is to install it,
+and running `cargo changelog init`.
+
+If you are running this on a new project, you are good to go and can directly
+start building and adding changelog entries.
+
+If you are planning to use `cargo-changelog` on an already ongoing project,
+your old CHANGELOG.md will have moved to `.changelogs/suffix.md` and will be
+appended to the generated changelog. Be sure to update it so that it can
+seamlessly integrate with the generated one.
+
## Usage
`cargo-changelog` is a tool to generate and manage changelog entries.
@@ -52,6 +69,15 @@ optional metadata fields to your changelog entries. You can also specify a
template file that gets used when rendering your changelogs to your final
`CHANGELOG.md` file.
+### Suffix
+
+If you wish to add something to the CHANGELOG that gets appended to the end of
+the file, you can create a `suffix.md` in your changelog directory (per default
+`.changelogs`).
+
+This is also where the `cargo changelog init` moves your existing CHANGELOG.md
+if you had one while running the command.
+
## Current state
This project is in pre-alpha.
diff --git a/assets/default_template.handlebars.md b/assets/default_template.handlebars.md
index fc99288..2b3002c 100644
--- a/assets/default_template.handlebars.md
+++ b/assets/default_template.handlebars.md
@@ -16,3 +16,6 @@
{{~ /each ~}}
{{~ /each ~}}
{{/if}}
+{{#if this.suffix}}
+{{this.suffix}}
+{{/if}}
diff --git a/src/command/release_command.rs b/src/command/release_command.rs
index 436e25d..f9b5f80 100644
--- a/src/command/release_command.rs
+++ b/src/command/release_command.rs
@@ -31,7 +31,32 @@ impl crate::command::Command for ReleaseCommand {
.join(config.template_path());
let template_source = std::fs::read_to_string(template_path)?;
let template = crate::template::new_handlebars(&template_source)?;
- let template_data = compute_template_data(load_release_files(workdir, config, self.all))?;
+
+ let suffix_path = workdir.join(config.fragment_dir()).join("suffix.md");
+ let suffix = match std::fs::read_to_string(&suffix_path) {
+ Ok(suffix) => Some(suffix),
+ Err(err) => {
+ match err.kind() {
+ std::io::ErrorKind::NotFound => {
+ // We don't want to spam the user for something they don't use
+ log::trace!(
+ "Did not find {}, not appending suffix",
+ suffix_path.display()
+ )
+ }
+ _ => {
+ log::error!(
+ "Could not read suffix file at {}: {err}",
+ suffix_path.display()
+ );
+ }
+ }
+ None
+ }
+ };
+
+ let template_data =
+ generate_template_data(load_release_files(workdir, config, self.all), suffix)?;
let changelog_contents =
template.render(crate::consts::INTERNAL_TEMPLATE_NAME, &template_data)?;
@@ -117,6 +142,13 @@ fn load_release_files(
})
}
+/// The data sent to the handlebars template
+#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, getset::Getters)]
+pub struct TemplateData {
+ versions: Vec<VersionData>,
+ suffix: Option<String>,
+}
+
/// Helper type for storing version associated with Fragments
///
/// only used for handlebars templating
@@ -128,9 +160,10 @@ pub struct VersionData {
entries: Vec<Fragment>,
}
-fn compute_template_data(
+fn generate_template_data(
release_files: impl Iterator<Item = Result<(Option<semver::Version>, Fragment), Error>>,
-) -> Result<HashMap<String, Vec<VersionData>>, Error> {
+ suffix: Option<String>,
+) -> Result<TemplateData, Error> {
let versions = {
use itertools::Itertools;
let mut hm = HashMap::new();
@@ -150,9 +183,10 @@ fn compute_template_data(
.sorted_by(|va, vb| va.version.cmp(&vb.version))
};
- let mut hm: HashMap<String, Vec<VersionData>> = HashMap::new();
- hm.insert("versions".to_string(), versions.collect());
- Ok(hm)
+ Ok(TemplateData {
+ versions: versions.collect(),
+ suffix,
+ })
}
#[cfg(test)]
@@ -164,7 +198,7 @@ mod tests {
#[test]
fn test_template_data_is_sorted() {
- let result = compute_template_data(
+ let result = generate_template_data(
[
Ok((
Some(semver::Version::new(0, 2, 0)),
@@ -190,12 +224,13 @@ mod tests {
)),
]
.into_iter(),
+ None,
);
assert!(result.is_ok());
let result = result.unwrap();
- let versions = result.get("versions").unwrap();
+ let versions = result.versions;
assert_eq!(versions[0].version, "0.1.0");
assert_eq!(versions[1].version, "0.2.0");
}
diff --git a/src/main.rs b/src/main.rs
index d57e5f6..162c610 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -150,5 +150,24 @@ fn init(repo_workdir_path: PathBuf) -> miette::Result<()> {
template_file
.sync_all()
.map_err(Error::from)
- .into_diagnostic()
+ .into_diagnostic()?;
+
+ let existing_changelog = repo_workdir_path.join("CHANGELOG.md");
+
+ if existing_changelog.exists() {
+ let suffix_path = repo_workdir_path
+ .join(crate::config::fragment_dir_default())
+ .join("suffix.md");
+
+ std::fs::rename(existing_changelog, &suffix_path)
+ .map_err(Error::from)
+ .into_diagnostic()?;
+
+ println!(
+ "Found an existing CHANGELOG.md, moved it to {}",
+ suffix_path.display()
+ );
+ }
+
+ Ok(())
}
diff --git a/tests/init_command.rs b/tests/init_command.rs
index 843caaf..9f17fa4 100644
--- a/tests/init_command.rs
+++ b/tests/init_command.rs
@@ -61,3 +61,21 @@ fn init_command_creates_default_template() {
);
}
}
+
+#[test]
+fn init_command_creates_moves_existing_changelog() {
+ let temp_dir = tempfile::Builder::new()
+ .prefix("cargo-changelog")
+ .tempdir()
+ .unwrap();
+ self::common::init_git(temp_dir.path());
+
+ std::fs::write(temp_dir.path().join("CHANGELOG.md"), "foobar").unwrap();
+
+ self::common::init_cargo_changelog(temp_dir.path());
+
+ let suffix_file_path = temp_dir.path().join(".changelogs").join("suffix.md");
+ if !suffix_file_path.exists() {
+ panic!("Suffix file does not exist after `cargo-changelog init`");
+ }
+}
diff --git a/tests/release_command.rs b/tests/release_command.rs
index 24cad11..b8bf018 100644
--- a/tests/release_command.rs
+++ b/tests/release_command.rs
@@ -127,3 +127,92 @@ fn release_command_works_for_alpha_release() {
assert!(changelog.contains("0.1.0-alpha.1"));
assert!(changelog.contains("test text"));
}
+
+#[test]
+fn release_command_works_with_suffix() {
+ let temp_dir = tempfile::Builder::new()
+ .prefix("cargo-changelog")
+ .tempdir()
+ .unwrap();
+ self::common::init_git(temp_dir.path());
+ self::common::init_cargo(temp_dir.path(), "release_command_works_with_suffix");
+ self::common::init_cargo_changelog(temp_dir.path());
+
+ self::common::cargo_changelog_new(temp_dir.path())
+ .args([
+ "--format=toml",
+ "--set",
+ "issue=123",
+ "--set",
+ "subject='Test subject'",
+ "--set",
+ "type=Misc",
+ ])
+ .assert()
+ .success();
+
+ let unreleased_dir = temp_dir.path().join(".changelogs").join("unreleased");
+
+ let new_fragment_file_path = std::fs::read_dir(unreleased_dir)
+ .unwrap()
+ .into_iter()
+ .find(|rde| match rde {
+ Ok(de) => !de.path().ends_with(".gitkeep"),
+ Err(_) => true,
+ })
+ .unwrap()
+ .unwrap();
+
+ let mut new_fragment_file = std::fs::OpenOptions::new()
+ .write(true)
+ .append(true)
+ .create(false)
+ .open(new_fragment_file_path.path())
+ .unwrap();
+
+ writeln!(new_fragment_file).unwrap();
+ writeln!(new_fragment_file, "test text").unwrap();
+ new_fragment_file.sync_all().unwrap();
+ drop(new_fragment_file);
+
+ {
+ let suffix_path = temp_dir.path().join(".changelogs").join("suffix.md");
+
+ let mut suffix_file = std::fs::OpenOptions::new()
+ .write(true)
+ .create(true)
+ .open(suffix_path)
+ .unwrap();
+
+ writeln!(suffix_file, "this is the suffix part").unwrap();
+ suffix_file.sync_all().unwrap();
+ }
+
+ Command::cargo_bin("cargo-changelog")
+ .unwrap()
+ .args(["generate", "custom", "0.1.0-alpha.1"])
+ .current_dir(&temp_dir)
+ .assert()
+ .success();
+
+ Command::cargo_bin("cargo-changelog")
+ .unwrap()
+ .args(["release"])
+ .current_dir(&temp_dir)
+ .assert()
+ .success();
+
+ let changelog_file_path = temp_dir.path().join("CHANGELOG.md");
+ if !changelog_file_path.exists() {
+ panic!("Changelog does not exist");
+ }
+
+ if !changelog_file_path.is_file() {
+ panic!("Changelog is not a file");
+ }
+
+ let changelog = std::fs::read_to_string(changelog_file_path).unwrap();
+ assert!(changelog.contains("0.1.0-alpha.1"));
+ assert!(changelog.contains("test text"));
+ assert!(changelog.contains("this is the suffix part"));
+}