Skip to content

Commit ccb4655

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

File tree

4 files changed

+107
-73
lines changed

4 files changed

+107
-73
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: 84 additions & 33 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

@@ -47,40 +46,15 @@ pub fn minimum_update(
4746
let mut cfg = GlobalConfig::new();
4847
cfg.set_log_level(Some(log::Level::Info));
4948
let result = semver_check.check_release(&mut cfg)?;
49+
log::info!("Result {:?}", result);
5050

51-
let mut min_required_update = ReleaseType::Patch;
52-
for (_, report) in result.crate_reports() {
53-
if let Some(required_bump) = report.required_bump() {
54-
let required_is_stricter = (min_required_update == ReleaseType::Patch)
55-
|| (required_bump == ReleaseType::Major);
56-
if required_is_stricter {
57-
min_required_update = required_bump;
58-
}
59-
}
60-
}
61-
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 {
77-
log::warn!(
78-
"Downgrading required bump from Minor to Patch for unstable package: {}",
79-
package
80-
);
81-
min_required_update = ReleaseType::Minor;
82-
}
51+
let required_bumps: Vec<ReleaseType> = result
52+
.crate_reports()
53+
.into_iter()
54+
.filter_map(|(_, report)| report.required_bump())
55+
.collect();
8356

57+
let min_required_update = required_bump(&required_bumps, package.is_forever_unstable());
8458
Ok(min_required_update)
8559
}
8660

@@ -142,3 +116,80 @@ pub(crate) fn build_doc_json(
142116
.with_context(|| format!("Failed to run `cargo rustdoc` with {cargo_args:?}",))?;
143117
Ok(current_path)
144118
}
119+
120+
fn required_bump(required_bumps: &[ReleaseType], forever_unstable: bool) -> ReleaseType {
121+
let mut min_required_update = ReleaseType::Patch;
122+
123+
for &required_bump in required_bumps {
124+
let required_is_stricter =
125+
(min_required_update == ReleaseType::Patch) || (required_bump == ReleaseType::Major);
126+
127+
if required_is_stricter {
128+
min_required_update = required_bump;
129+
}
130+
}
131+
132+
if forever_unstable && min_required_update == ReleaseType::Major {
133+
log::warn!("Downgrading required bump from Minor to Patch for unstable package",);
134+
min_required_update = ReleaseType::Minor;
135+
}
136+
137+
min_required_update
138+
}
139+
140+
#[cfg(test)]
141+
mod tests {
142+
143+
use super::*;
144+
145+
#[test]
146+
// Semver-check requiring a major bump for a 0.x crate
147+
fn major_bump_from_0x_to_0x_plus_1() {
148+
let bumps = [ReleaseType::Major];
149+
150+
let result = required_bump(&bumps, false);
151+
152+
assert_eq!(result, ReleaseType::Major);
153+
}
154+
155+
#[test]
156+
// For crates >= 1.0.0, Major is still Major
157+
fn major_bump_from_1x_to_2x() {
158+
let bumps = [ReleaseType::Major];
159+
160+
let result = required_bump(&bumps, false);
161+
162+
assert_eq!(result, ReleaseType::Major);
163+
}
164+
165+
#[test]
166+
fn forever_unstable_downgrades_major_to_minor() {
167+
let bumps = [ReleaseType::Major];
168+
169+
let result = required_bump(&bumps, true);
170+
171+
assert_eq!(
172+
result,
173+
ReleaseType::Minor,
174+
"forever-unstable packages must never require a major bump"
175+
);
176+
}
177+
178+
#[test]
179+
fn minor_stays_minor() {
180+
let bumps = [ReleaseType::Minor];
181+
182+
let result = required_bump(&bumps, false);
183+
184+
assert_eq!(result, ReleaseType::Minor);
185+
}
186+
187+
#[test]
188+
fn multiple_bumps_select_major() {
189+
let bumps = [ReleaseType::Patch, ReleaseType::Minor, ReleaseType::Major];
190+
191+
let result = required_bump(&bumps, false);
192+
193+
assert_eq!(result, ReleaseType::Major);
194+
}
195+
}

0 commit comments

Comments
 (0)