use std::{
collections::BTreeMap,
path::{Path, PathBuf},
};
use cargo_metadata::semver::Version;
use clap::builder::PathBufValueParser;
use release_plz_core::set_version::{SetVersionRequest, VersionChange};
use crate::config::Config;
use super::{config_command::ConfigCommand, manifest_command::ManifestCommand};
#[derive(clap::Parser, Debug)]
pub struct SetVersion {
pub versions: Vec<String>,
#[arg(long, value_parser = PathBufValueParser::new())]
manifest_path: Option<PathBuf>,
#[arg(
long,
value_name = "PATH",
value_parser = PathBufValueParser::new()
)]
config: Option<PathBuf>,
}
impl ConfigCommand for SetVersion {
fn config_path(&self) -> Option<&Path> {
self.config.as_deref()
}
}
impl SetVersion {
fn parse_versions(self) -> anyhow::Result<BTreeMap<String, VersionChange>> {
self
.versions
.iter()
.map(|v| {
let error = Err(anyhow::anyhow!("version {v} is invalid. Format need to be `<package_name>@<version>`. E.g. `release-plz set-version serde@1.2.3`"));
let d: Vec<_> = v.split('@').collect();
#[allow(clippy::get_first)]
let Some(package) = d.get(0) else {return error;};
let Some(version) = d.get(1) else {return error;};
let version = Version::parse(version).unwrap();
Ok((package.to_string(), VersionChange::new( version )))
})
.collect()
}
pub fn set_version_request(self, config: &Config) -> anyhow::Result<SetVersionRequest> {
let cargo_metadata = self.cargo_metadata()?;
let version_changes = self.parse_versions()?;
let mut request = SetVersionRequest::new(version_changes, cargo_metadata)?;
config.fill_set_version_config(&mut request)?;
Ok(request)
}
}
impl ManifestCommand for SetVersion {
fn optional_manifest(&self) -> Option<&Path> {
self.manifest_path.as_deref()
}
}