From 57772af4167f8868136c103635ea890b5a221681 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sat, 1 Oct 2022 20:21:15 +0100 Subject: [PATCH] Start the release script rewrite --- tools/src/main.rs | 3 ++ tools/src/release.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 tools/src/release.rs diff --git a/tools/src/main.rs b/tools/src/main.rs index 676c7388..c0b13de7 100644 --- a/tools/src/main.rs +++ b/tools/src/main.rs @@ -2,12 +2,14 @@ use clap::Command; mod publish; +mod release; fn cli() -> Command { Command::new("Agb tools") .subcommand_required(true) .arg_required_else_help(true) .subcommand(publish::command()) + .subcommand(release::command()) } fn main() { @@ -15,6 +17,7 @@ fn main() { let result = match matches.subcommand() { Some(("publish", arg_matches)) => publish::publish(arg_matches), + Some(("release", arg_matches)) => todo!(), _ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"), }; diff --git a/tools/src/release.rs b/tools/src/release.rs new file mode 100644 index 00000000..0cd04340 --- /dev/null +++ b/tools/src/release.rs @@ -0,0 +1,82 @@ +pub fn command() -> clap::Command { + clap::Command::new("release") + .about("Prepares and commits the changes required to release agb") + .arg( + clap::Arg::new("version") + .help("New version to release") + .value_parser(version_parser), + ) +} + +#[derive(Debug, Clone, PartialEq, Eq)] +struct Version { + major: u32, + minor: u32, + patch: u32, +} + +impl Version { + #[cfg(test)] + pub fn new(major: u32, minor: u32, patch: u32) -> Self { + Self { + major, + minor, + patch, + } + } +} + +#[derive(Debug, PartialEq, Eq)] +struct ParseVersionError; + +impl std::str::FromStr for Version { + type Err = ParseVersionError; + + fn from_str(s: &str) -> Result { + let version_array: Vec<_> = s + .split('.') + .map(|v| v.parse()) + .collect::, _>>() + .map_err(|_| ParseVersionError)?; + + if version_array.len() > 3 || version_array.is_empty() { + return Err(ParseVersionError); + } + + Ok(Version { + major: version_array[0], + minor: *version_array.get(1).unwrap_or(&0), + patch: *version_array.get(2).unwrap_or(&0), + }) + } +} + +fn version_parser(maybe_version: &str) -> Result { + maybe_version.parse().map_err(|_| "Failed to parse version") +} + +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + + #[test] + fn verify_cli() { + command().debug_assert(); + } + + #[test] + fn can_parse_versions() { + assert_eq!(Version::from_str("0.1.2").unwrap(), Version::new(0, 1, 2)); + assert_eq!(Version::from_str("0.1").unwrap(), Version::new(0, 1, 0)); + assert_eq!( + Version::from_str("33.23.4000").unwrap(), + Version::new(33, 23, 4000) + ); + + assert_eq!(Version::from_str("abc").unwrap_err(), ParseVersionError); + assert_eq!(Version::from_str("").unwrap_err(), ParseVersionError); + assert_eq!(Version::from_str("0.2.4.5").unwrap_err(), ParseVersionError); + assert_eq!(Version::from_str("0.2.4a").unwrap_err(), ParseVersionError); + } +}