1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! `changelog` command

use std::env;

use clap::Parser;
use gitcc_core::{
    build_changelog, commit_history, ChangelogBuildOptions, Config, StatusShow,
    TEMPLATE_CHANGELOG_STD,
};

use crate::{info, warn};

/// Changelog command arguments
#[derive(Debug, Parser)]
pub struct ChangelogArgs {
    /// Includes all commits
    #[arg(long)]
    pub all: bool,
    /// Sets the latest version as 'Unreleased'
    #[arg(long)]
    pub unreleased: bool,
}

/// Generates the change log
pub fn run(args: ChangelogArgs) -> anyhow::Result<()> {
    let cwd = env::current_dir()?;
    let cfg = Config::load_from_fs(&cwd)?;
    let cfg = if let Some(c) = cfg {
        c
    } else {
        info!("using default config");
        Config::default()
    };

    // Checks that the repo is clean
    let status = gitcc_core::git_status(&cwd, StatusShow::IndexAndWorkdir)?;
    if !status.is_empty() {
        warn!("repo is dirty");
    }

    // Generate the changelog
    let history = commit_history(&cwd, &cfg)?;
    let changelog_opts = ChangelogBuildOptions {
        origin_name: None,
        all: args.all,
        next_version: if args.unreleased {
            None
        } else {
            Some(history.next_version_str())
        },
    };
    let changelog = build_changelog(&cwd, &cfg, &history, Some(changelog_opts))?;
    let changelog_str = changelog.render(TEMPLATE_CHANGELOG_STD)?;
    println!("{changelog_str}");

    Ok(())
}