xtask/
release_commands.rs1use anyhow::{Context, Result, bail};
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!(
70 "Usage: cargo xtask <check-release-versions|release-plan> [--base REF] [--head REF] [--mode pr|main] [--json]"
71 );
72 }
73 unknown => bail!("unknown release option: {unknown}"),
74 }
75 index += 1;
76 }
77 Ok(Self {
78 base,
79 head,
80 mode,
81 json,
82 })
83 }
84}
85
86fn parse_gate_mode(value: &str) -> Result<release_versions::GateMode> {
87 match value {
88 "pr" => Ok(release_versions::GateMode::Pr),
89 "main" => Ok(release_versions::GateMode::Main),
90 other => bail!("unknown release gate mode {other:?}; expected pr or main"),
91 }
92}
93
94fn parse_bump_level(value: &str) -> Result<release_versions::BumpLevel> {
95 match value {
96 "patch" => Ok(release_versions::BumpLevel::Patch),
97 "minor" => Ok(release_versions::BumpLevel::Minor),
98 "major" => Ok(release_versions::BumpLevel::Major),
99 other => bail!("unknown bump level {other:?}; expected patch, minor, or major"),
100 }
101}
102
103#[cfg(test)]
104#[path = "release_commands_tests.rs"]
105mod tests;