#![forbid(unsafe_code)]
mod common;
mod error;
mod logging;
mod options;
mod verbose;
use clap::Parser;
use std::ffi::{OsStr, OsString};
use std::process::ExitCode;
fn cargo_subcommand_name() -> &'static str {
const BIN: &str = env!("CARGO_BIN_NAME");
BIN.strip_prefix("cargo-").unwrap_or(BIN)
}
fn normalize_args<I>(args: I) -> Vec<OsString>
where
I: IntoIterator<Item = OsString>,
{
let mut args: Vec<OsString> = args.into_iter().collect();
let subcommand = OsStr::new(cargo_subcommand_name());
if args.get(1).is_some_and(|arg| arg == subcommand) {
args.remove(1);
}
args
}
#[tokio::main]
async fn main() -> ExitCode {
if let Err(error) = color_eyre::install() {
eprintln!("error: could not install the panic handler: {error}");
return ExitCode::FAILURE;
}
let mut options = options::Options::parse_from(normalize_args(std::env::args_os()));
options::fix(&mut options);
common::report_result(common::bumpversion(options).await)
}
#[cfg(test)]
mod tests {
use super::normalize_args;
use std::ffi::OsString;
fn normalize(args: &[&str]) -> Vec<String> {
normalize_args(args.iter().map(OsString::from))
.iter()
.map(|arg| arg.to_string_lossy().into_owned())
.collect()
}
#[test]
fn strips_the_injected_subcommand_name() {
assert_eq!(
normalize(&["cargo-bumpversion", "bumpversion", "patch"]),
["cargo-bumpversion", "patch"]
);
}
#[test]
fn leaves_a_direct_invocation_alone() {
assert_eq!(
normalize(&["cargo-bumpversion", "patch"]),
["cargo-bumpversion", "patch"]
);
}
#[test]
fn preserves_argv0_so_the_first_real_argument_is_not_eaten() {
assert_eq!(
normalize(&["cargo-bumpversion", "bumpversion", "show-bump", "major"]),
["cargo-bumpversion", "show-bump", "major"]
);
assert_eq!(
normalize(&["cargo-bumpversion", "--help"]),
["cargo-bumpversion", "--help"]
);
}
#[test]
fn strips_only_the_first_position_and_only_once() {
assert_eq!(
normalize(&["cargo-bumpversion", "bumpversion", "bumpversion"]),
["cargo-bumpversion", "bumpversion"]
);
assert_eq!(
normalize(&["cargo-bumpversion", "patch", "bumpversion"]),
["cargo-bumpversion", "patch", "bumpversion"]
);
}
#[test]
fn handles_argv_without_arguments() {
assert_eq!(normalize(&["cargo-bumpversion"]), ["cargo-bumpversion"]);
assert!(normalize(&[]).is_empty());
}
}