Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions esp-rom-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ license = "MIT OR Apache-2.0"
links = "esp_rom_sys"

[package.metadata.espressif]
semver-checked = true
forever-unstable = true
check-configs = [{ features = [] }]
clippy-configs = [{ features = [] }]
Expand Down
27 changes: 6 additions & 21 deletions xtask/src/commands/release/execute_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use anyhow::{Context, Result, bail, ensure};
use clap::Args;
use esp_metadata::Chip;
use strum::IntoEnumIterator;
use toml_edit::{Item, Value};

use crate::{
cargo::CargoToml,
Expand Down Expand Up @@ -66,26 +65,12 @@ pub fn execute_plan(workspace: &Path, args: ApplyPlanArgs) -> Result<()> {
);
}

if let Some(metadata) = package.espressif_metadata()
&& let Some(Item::Value(forever_unstable)) = metadata.get("forever_unstable")
{
// Special case: some packages are perma-unstable, meaning they won't ever have
// a stable release. For these packages, we always use a
// patch release.
let forever_unstable = if let Value::Boolean(forever_unstable) = forever_unstable {
*forever_unstable.value()
} else {
log::warn!("Invalid value for 'forever_unstable' in metadata - must be a boolean");
true
};

if forever_unstable && step.bump != VersionBump::Patch {
bail!(
"Cannot bump perma-unstable package {} to a non-patch version",
step.package
);
}
};
if package.package.is_forever_unstable() && step.bump != VersionBump::Patch {
bail!(
"Cannot bump perma-unstable package {} to a non-patch version",
step.package
);
}

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

Expand Down
20 changes: 1 addition & 19 deletions xtask/src/commands/release/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use clap::Args;
use esp_metadata::Chip;
use serde::{Deserialize, Serialize};
use strum::IntoEnumIterator;
use toml_edit::{Item, Value};

use crate::{
Package,
Expand Down Expand Up @@ -135,24 +134,7 @@ pub fn plan(workspace: &Path, args: PlanArgs) -> Result<()> {
let amount = if package.is_semver_checked() {
min_package_update(workspace, package, &all_chips)?
} else {
let forever_unstable = if let Some(metadata) =
package_tomls[&package].espressif_metadata()
&& let Some(Item::Value(forever_unstable)) = metadata.get("forever-unstable")
{
// Special case: some packages are perma-unstable, meaning they won't ever have
// a stable release. For these packages, we always use a
// patch release.
if let Value::Boolean(forever_unstable) = forever_unstable {
*forever_unstable.value()
} else {
log::warn!(
"Invalid value for 'forever-unstable' in metadata - must be a boolean"
);
true
}
} else {
false
};
let forever_unstable = package_tomls[&package].package.is_forever_unstable();

if forever_unstable {
ReleaseType::Patch
Expand Down
16 changes: 16 additions & 0 deletions xtask/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,22 @@ impl Package {
}
Ok(())
}

#[cfg(feature = "semver-checks")]
fn is_forever_unstable(&self) -> bool {
match self
.toml()
.espressif_metadata()
.and_then(|m| m.get("forever-unstable"))
{
Some(Item::Value(Value::Boolean(b))) => *b.value(),
Some(Item::Value(_)) => {
log::warn!("Invalid value for 'forever-unstable' in metadata - must be a boolean");
true
}
_ => false,
}
}
}

#[derive(Debug, Clone, Copy, strum::Display, clap::ValueEnum, Serialize, Deserialize)]
Expand Down
102 changes: 92 additions & 10 deletions xtask/src/semver_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,13 @@ pub fn minimum_update(
let result = semver_check.check_release(&mut cfg)?;
log::info!("Result {:?}", result);

let mut min_required_update = ReleaseType::Patch;
for (_, report) in result.crate_reports() {
if let Some(required_bump) = report.required_bump() {
let required_is_stricter = (min_required_update == ReleaseType::Patch)
|| (required_bump == ReleaseType::Major);
if required_is_stricter {
min_required_update = required_bump;
}
}
}
let required_bumps: Vec<ReleaseType> = result
.crate_reports()
.into_iter()
.filter_map(|(_, report)| report.required_bump())
.collect();

let min_required_update = required_bump(&required_bumps, package.is_forever_unstable());
Ok(min_required_update)
}

Expand Down Expand Up @@ -126,3 +122,89 @@ pub(crate) fn build_doc_json(
.with_context(|| format!("Failed to run `cargo rustdoc` with {cargo_args:?}",))?;
Ok(current_path)
}

fn required_bump(required_bumps: &[ReleaseType], forever_unstable: bool) -> ReleaseType {
let mut min_required_update = ReleaseType::Patch;

for &required_bump in required_bumps {
let required_is_stricter =
(min_required_update == ReleaseType::Patch) || (required_bump == ReleaseType::Major);

if required_is_stricter {
min_required_update = required_bump;
}
}

if forever_unstable && min_required_update != ReleaseType::Patch {
panic!(
"Forever-unstable package can only receive a patch release but received {:?}!",
min_required_update
);
}

min_required_update
}

#[cfg(test)]
mod tests {

use super::*;

#[test]
// Semver-check requiring a major bump for a 0.x crate
fn major_bump_from_0x_to_0x_plus_1() {
let bumps = [ReleaseType::Major];

let result = required_bump(&bumps, false);

assert_eq!(result, ReleaseType::Major);
}

#[test]
// For crates >= 1.0.0, Major is still Major
fn major_bump_from_1x_to_2x() {
let bumps = [ReleaseType::Major];

let result = required_bump(&bumps, false);

assert_eq!(result, ReleaseType::Major);
}

#[test]
#[should_panic(
expected = "Forever-unstable package can only receive a patch release but received Major"
)]
fn forever_unstable_downgrades_major_to_patch() {
let bumps = [ReleaseType::Major];

let result = required_bump(&bumps, true);
}

#[test]
#[should_panic(
expected = "Forever-unstable package can only receive a patch release but received Minor"
)]
fn forever_unstable_downgrades_minor_to_patch() {
let bumps = [ReleaseType::Minor];

let result = required_bump(&bumps, true);
}

#[test]
fn minor_stays_minor() {
let bumps = [ReleaseType::Minor];

let result = required_bump(&bumps, false);

assert_eq!(result, ReleaseType::Minor);
}

#[test]
fn multiple_bumps_select_major() {
let bumps = [ReleaseType::Patch, ReleaseType::Minor, ReleaseType::Major];

let result = required_bump(&bumps, false);

assert_eq!(result, ReleaseType::Major);
}
}
Loading