Skip to content

Commit 48b9ce8

Browse files
committed
Add tests and add is_forever_unstable method to the Package
1 parent 8da311a commit 48b9ce8

File tree

4 files changed

+101
-56
lines changed

4 files changed

+101
-56
lines changed

xtask/src/commands/release/execute_plan.rs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use anyhow::{Context, Result, bail, ensure};
44
use clap::Args;
55
use esp_metadata::Chip;
66
use strum::IntoEnumIterator;
7-
use toml_edit::{Item, Value};
87

98
use crate::{
109
cargo::CargoToml,
@@ -66,26 +65,12 @@ pub fn execute_plan(workspace: &Path, args: ApplyPlanArgs) -> Result<()> {
6665
);
6766
}
6867

69-
if let Some(metadata) = package.espressif_metadata()
70-
&& let Some(Item::Value(forever_unstable)) = metadata.get("forever_unstable")
71-
{
72-
// Special case: some packages are perma-unstable, meaning they won't ever have
73-
// a stable release. For these packages, we always use a
74-
// patch release.
75-
let forever_unstable = if let Value::Boolean(forever_unstable) = forever_unstable {
76-
*forever_unstable.value()
77-
} else {
78-
log::warn!("Invalid value for 'forever_unstable' in metadata - must be a boolean");
79-
true
80-
};
81-
82-
if forever_unstable && step.bump != VersionBump::Patch {
83-
bail!(
84-
"Cannot bump perma-unstable package {} to a non-patch version",
85-
step.package
86-
);
87-
}
88-
};
68+
if package.package.is_forever_unstable() && step.bump != VersionBump::Patch {
69+
bail!(
70+
"Cannot bump perma-unstable package {} to a non-patch version",
71+
step.package
72+
);
73+
}
8974

9075
let new_version = update_package(&mut package, &step.bump, !args.no_dry_run)?;
9176

xtask/src/commands/release/plan.rs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use clap::Args;
66
use esp_metadata::Chip;
77
use serde::{Deserialize, Serialize};
88
use strum::IntoEnumIterator;
9-
use toml_edit::{Item, Value};
109

1110
use crate::{
1211
Package,
@@ -135,24 +134,7 @@ pub fn plan(workspace: &Path, args: PlanArgs) -> Result<()> {
135134
let amount = if package.is_semver_checked() {
136135
min_package_update(workspace, package, &all_chips)?
137136
} else {
138-
let forever_unstable = if let Some(metadata) =
139-
package_tomls[&package].espressif_metadata()
140-
&& let Some(Item::Value(forever_unstable)) = metadata.get("forever-unstable")
141-
{
142-
// Special case: some packages are perma-unstable, meaning they won't ever have
143-
// a stable release. For these packages, we always use a
144-
// patch release.
145-
if let Value::Boolean(forever_unstable) = forever_unstable {
146-
*forever_unstable.value()
147-
} else {
148-
log::warn!(
149-
"Invalid value for 'forever-unstable' in metadata - must be a boolean"
150-
);
151-
true
152-
}
153-
} else {
154-
false
155-
};
137+
let forever_unstable = package_tomls[&package].package.is_forever_unstable();
156138

157139
if forever_unstable {
158140
ReleaseType::Patch

xtask/src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,22 @@ impl Package {
464464
.as_bool()
465465
.expect("semver-checked must be a boolean")
466466
}
467+
468+
#[cfg(feature = "semver-checks")]
469+
fn is_forever_unstable(&self) -> bool {
470+
match self
471+
.toml()
472+
.espressif_metadata()
473+
.and_then(|m| m.get("forever-unstable"))
474+
{
475+
Some(Item::Value(Value::Boolean(b))) => *b.value(),
476+
Some(Item::Value(_)) => {
477+
log::warn!("Invalid value for 'forever-unstable' in metadata - must be a boolean");
478+
true
479+
}
480+
_ => false,
481+
}
482+
}
467483
}
468484

469485
#[derive(Debug, Clone, Copy, strum::Display, clap::ValueEnum, Serialize, Deserialize)]

xtask/src/semver_check.rs

Lines changed: 78 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use std::{
77
use anyhow::{Context, Error};
88
use cargo_semver_checks::{Check, GlobalConfig, ReleaseType, Rustdoc};
99
use esp_metadata::{Chip, Config};
10-
use toml_edit::{Item, Value};
1110

1211
use crate::{Package, cargo::CargoArgsBuilder, commands::checker::download_baselines};
1312

@@ -59,21 +58,7 @@ pub fn minimum_update(
5958
}
6059
}
6160

62-
let forever_unstable = package
63-
.toml()
64-
.espressif_metadata()
65-
.and_then(|metadata| metadata.get("forever-unstable"))
66-
.map(|item| match item {
67-
Item::Value(Value::Boolean(b)) => *b.value(),
68-
Item::Value(_) => {
69-
log::warn!("Invalid value for 'forever-unstable' in metadata - must be a boolean");
70-
true
71-
}
72-
_ => false,
73-
})
74-
.unwrap_or(false);
75-
76-
if forever_unstable && min_required_update == ReleaseType::Major {
61+
if package.is_forever_unstable() && min_required_update == ReleaseType::Major {
7762
log::warn!(
7863
"Downgrading required bump from Minor to Patch for unstable package: {}",
7964
package
@@ -142,3 +127,80 @@ pub(crate) fn build_doc_json(
142127
.with_context(|| format!("Failed to run `cargo rustdoc` with {cargo_args:?}",))?;
143128
Ok(current_path)
144129
}
130+
131+
#[cfg(test)]
132+
fn compute_required_bump(required_bumps: &[ReleaseType], forever_unstable: bool) -> ReleaseType {
133+
let mut min_required = ReleaseType::Patch;
134+
135+
for &bump in required_bumps {
136+
let required_is_stricter =
137+
(min_required == ReleaseType::Patch) || (bump == ReleaseType::Major);
138+
139+
if required_is_stricter {
140+
min_required = bump;
141+
}
142+
}
143+
144+
if forever_unstable && min_required == ReleaseType::Major {
145+
ReleaseType::Minor
146+
} else {
147+
min_required
148+
}
149+
}
150+
151+
#[cfg(test)]
152+
mod tests {
153+
154+
use super::*;
155+
156+
#[test]
157+
// Semver-check requiring a major bump for a 0.x crate
158+
fn major_bump_from_0x_to_0x_plus_1() {
159+
let bumps = [ReleaseType::Major];
160+
161+
let result = compute_required_bump(&bumps, false);
162+
163+
assert_eq!(result, ReleaseType::Major);
164+
}
165+
166+
#[test]
167+
// For crates >= 1.0.0, Major is still Major
168+
fn major_bump_from_1x_to_2x() {
169+
let bumps = [ReleaseType::Major];
170+
171+
let result = compute_required_bump(&bumps, false);
172+
173+
assert_eq!(result, ReleaseType::Major);
174+
}
175+
176+
#[test]
177+
fn forever_unstable_downgrades_major_to_minor() {
178+
let bumps = [ReleaseType::Major];
179+
180+
let result = compute_required_bump(&bumps, true);
181+
182+
assert_eq!(
183+
result,
184+
ReleaseType::Minor,
185+
"forever-unstable packages must never require a major bump"
186+
);
187+
}
188+
189+
#[test]
190+
fn minor_stays_minor() {
191+
let bumps = [ReleaseType::Minor];
192+
193+
let result = compute_required_bump(&bumps, false);
194+
195+
assert_eq!(result, ReleaseType::Minor);
196+
}
197+
198+
#[test]
199+
fn multiple_bumps_select_major() {
200+
let bumps = [ReleaseType::Patch, ReleaseType::Minor, ReleaseType::Major];
201+
202+
let result = compute_required_bump(&bumps, false);
203+
204+
assert_eq!(result, ReleaseType::Major);
205+
}
206+
}

0 commit comments

Comments
 (0)