xtask/
release_commands.rs1use anyhow::{bail, Context, Result};
2use std::path::Path;
3
4use crate::release_versions;
5
6pub(crate) fn check(root: &Path, args: &[String]) -> Result<()> {
7 let options = ReleaseCommandOptions::parse(args)?;
8 release_versions::check(
9 root,
10 options.base.as_deref(),
11 &options.head,
12 options.mode,
13 options.json,
14 )
15}
16
17pub(crate) fn plan(root: &Path, args: &[String]) -> Result<()> {
18 let options = ReleaseCommandOptions::parse(args)?;
19 let plans = release_versions::plan(root, options.base.as_deref(), &options.head, options.mode)?;
20 release_versions::print_plans(&plans, options.json)
21}
22
23pub(crate) fn bump(root: &Path, args: &[String]) -> Result<()> {
24 if args.len() != 2 {
25 bail!("Usage: cargo xtask bump-version <component> <patch|minor|major>");
26 }
27 let level = parse_bump_level(&args[1])?;
28 release_versions::bump(root, &args[0], level)
29}
30
31#[derive(Debug, PartialEq, Eq)]
32struct ReleaseCommandOptions {
33 base: Option<String>,
34 head: String,
35 mode: release_versions::GateMode,
36 json: bool,
37}
38
39impl ReleaseCommandOptions {
40 fn parse(args: &[String]) -> Result<Self> {
41 let mut base = None;
42 let mut head = "HEAD".to_owned();
43 let mut mode = release_versions::GateMode::Pr;
44 let mut json = false;
45 let mut index = 0usize;
46 while index < args.len() {
47 match args[index].as_str() {
48 "--base" => {
49 index += 1;
50 base = Some(
51 args.get(index)
52 .context("--base requires a value")?
53 .to_owned(),
54 );
55 }
56 "--head" => {
57 index += 1;
58 head = args
59 .get(index)
60 .context("--head requires a value")?
61 .to_owned();
62 }
63 "--mode" => {
64 index += 1;
65 mode = parse_gate_mode(args.get(index).context("--mode requires a value")?)?;
66 }
67 "--json" => json = true,
68 "--help" | "-h" => {
69 bail!("Usage: cargo xtask <check-release-versions|release-plan> [--base REF] [--head REF] [--mode pr|main] [--json]");
70 }
71 unknown => bail!("unknown release option: {unknown}"),
72 }
73 index += 1;
74 }
75 Ok(Self {
76 base,
77 head,
78 mode,
79 json,
80 })
81 }
82}
83
84fn parse_gate_mode(value: &str) -> Result<release_versions::GateMode> {
85 match value {
86 "pr" => Ok(release_versions::GateMode::Pr),
87 "main" => Ok(release_versions::GateMode::Main),
88 other => bail!("unknown release gate mode {other:?}; expected pr or main"),
89 }
90}
91
92fn parse_bump_level(value: &str) -> Result<release_versions::BumpLevel> {
93 match value {
94 "patch" => Ok(release_versions::BumpLevel::Patch),
95 "minor" => Ok(release_versions::BumpLevel::Minor),
96 "major" => Ok(release_versions::BumpLevel::Major),
97 other => bail!("unknown bump level {other:?}; expected patch, minor, or major"),
98 }
99}
100
101#[cfg(test)]
102#[path = "release_commands_tests.rs"]
103mod tests;