changesette 6.3.0

A version and changelog manager using the changesets file format
use std::{fmt::Write as _, path::Path};

use anyhow::Result;

use crate::{bump::Bump, config::Config, output, plan, release_plan, workspace::Workspace};

pub(crate) fn run(
    workspace: Workspace,
    config: &Config,
    verbose: bool,
    output_path: Option<&Path>,
) -> Result<()> {
    let planned = plan::plan_version(workspace, config, &[], None)?;

    if let Some(path) = output_path {
        return release_plan::write_file(
            path,
            &release_plan::build(&planned.changes, &planned.releases, planned.pre.as_ref()),
        );
    }

    let mut text = String::from("Packages to be bumped:");
    for group in [Bump::Major, Bump::Minor, Bump::Patch] {
        let group_releases: Vec<_> = planned
            .releases
            .iter()
            .filter(|release| release.bump == Some(group))
            .collect();
        if group_releases.is_empty() {
            continue;
        }
        let _ = write!(text, "\n- {}", group.as_str());
        for release in group_releases {
            let _ = write!(text, "\n  - {}", release.name);
            if verbose {
                let _ = write!(text, " -> {}", release.new_version);
                for id in &release.changeset_ids {
                    let _ = write!(text, "\n    - .changeset/{id}.md");
                }
            }
        }
    }
    output::print_line(&text)
}