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

Add a changelog #351

Merged
merged 2 commits into from
Jul 24, 2023
Merged

Add a changelog #351

merged 2 commits into from
Jul 24, 2023

Conversation

ranile
Copy link
Collaborator

@ranile ranile commented Jun 17, 2023

This is done on a best-effort bases. I did not go through all the previous versions manually or check if everything is accurate.

I added this for historical purposes. Moving forward, I would like the changelog to be updated as PRs are merged and releases are made

Script used to generate the changelog
use std::fmt::Write as _;
use std::fs::File;
use std::process::Command;
use std::str;
use anyhow::{Context, Result};
use toml::Table;
use std::io::Write as _;

fn build_changelog_for_crate(crate_directory: &str) -> Result<String> {
    let output = Command::new("git")
        .arg("log")
        .arg("--pretty=format:%h")
        .arg("--")
        .arg(crate_directory)
        .output()
        .context("Failed to execute git log command")?;

    let output_str = str::from_utf8(&output.stdout).context("Invalid UTF-8 output")?;
    let commit_hashes = output_str.split('\n').collect::<Vec<_>>();

    let mut releases = Vec::new();

    for (index, &commit_hash) in commit_hashes.iter().enumerate().skip(1) {
        if index == 0 { continue; }
        let command = Command::new("git")
            .arg("diff")
            .arg("--name-only")
            .arg(commit_hashes[index - 1])
            .arg(commit_hash)
            .arg("--")
            .arg(crate_directory)
            .output()
            .expect("Failed to execute git diff command");

        let command_str = str::from_utf8(&command.stdout).expect("Invalid UTF-8 output");

        if command_str.contains("Cargo.toml") {
            let command = Command::new("git")
                .arg("show")
                .arg(format!("{commit_hash}:{crate_directory}/Cargo.toml"))
                .output()
                .expect("Failed to execute git show command");

            let command_str = str::from_utf8(&command.stdout).expect("Invalid UTF-8 output");
            let cargo_toml = toml::from_str::<Table>(command_str).expect("Failed to parse Cargo.toml");
            let package = cargo_toml.get("package").expect("Missing package section in Cargo.toml");
            let version = package.get("version").expect("Missing version in package section of Cargo.toml");
            releases.push((version.to_string(), commit_hash));
        }
    }

    // Generate the changelog
    let mut last = String::new();
    let mut changelog = String::new();
    for (index, (version, commit_hash)) in releases.iter().enumerate() {
        if last != *version {
            writeln!(&mut changelog, "\n### Version {}\n", version)?;
            last = version.clone();
        }
        let previous_release = releases.get(index + 1);
        if let Some((_, previous_hash)) = previous_release {
            let command = Command::new("git")
                .arg("log")
                .arg("--pretty=format:- %s")
                .arg(dbg!(format!("{}..{}", previous_hash, commit_hash)))
                .arg("--")
                .arg(crate_directory)
                .output()
                .context("Failed to execute git log command")?;

            let command_str = str::from_utf8(&command.stdout)
                .context("Invalid UTF-8 output")?
                .split("\n")
                .filter(|line| line.to_lowercase().contains("release"))
                .collect::<Vec<_>>()
                .join("\n");
            changelog.push_str(&command_str);
        }
        writeln!(&mut changelog)?
    }

    Ok(changelog)
}

fn main() -> anyhow::Result<()> {

    // Get the git log for the crate directory
    let crates = ["console",
        "dialogs",
        "events",
        "file",
        "history",
        "net",
        "render",
        "storage",
        "timers",
        "utils",
        "worker", ];
    let mut file = File::options().write(true).open("CHANGELOG.md")?;

    for crate_name in crates.iter() {
        let changelog = build_changelog_for_crate(&format!("crates/{}", crate_name))?;
        writeln!(&mut file, "## `{crate_name}`")?;
        write!(&mut file, "{}\n", changelog)?;
    }
    Ok(())
}

@ranile ranile merged commit 82a3f82 into master Jul 24, 2023
@ranile ranile deleted the changelog branch July 24, 2023 16:12
@richardpringle
Copy link
Contributor

🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants