feat(config): Add ChangeId enum for suppressing warnings
Introduces the `ChangeId` enum to allow suppressing `change_id` warnings. Now, `ChangeId` supports both numeric values and the string literal `"ignore"`. Numeric values behave as expected, while `"ignore"` is used to suppress warning messages.
This commit is contained in:
parent
7d49ae9731
commit
eaa0613e8d
4 changed files with 75 additions and 53 deletions
|
|
@ -11,8 +11,8 @@ use std::str::FromStr;
|
|||
use std::{env, process};
|
||||
|
||||
use bootstrap::{
|
||||
Build, CONFIG_CHANGE_HISTORY, Config, Flags, Subcommand, debug, find_recent_config_change_ids,
|
||||
human_readable_changes, t,
|
||||
Build, CONFIG_CHANGE_HISTORY, ChangeId, Config, Flags, Subcommand, debug,
|
||||
find_recent_config_change_ids, human_readable_changes, t,
|
||||
};
|
||||
#[cfg(feature = "tracing")]
|
||||
use tracing::instrument;
|
||||
|
|
@ -155,51 +155,53 @@ fn check_version(config: &Config) -> Option<String> {
|
|||
let latest_change_id = CONFIG_CHANGE_HISTORY.last().unwrap().change_id;
|
||||
let warned_id_path = config.out.join("bootstrap").join(".last-warned-change-id");
|
||||
|
||||
if let Some(mut id) = config.change_id {
|
||||
if id == latest_change_id {
|
||||
return None;
|
||||
let mut id = match config.change_id {
|
||||
Some(ChangeId::Id(id)) if id == latest_change_id => return None,
|
||||
Some(ChangeId::Ignore) => return None,
|
||||
Some(ChangeId::Id(id)) => id,
|
||||
None => {
|
||||
msg.push_str("WARNING: The `change-id` is missing in the `bootstrap.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n");
|
||||
msg.push_str("NOTE: to silence this warning, ");
|
||||
msg.push_str(&format!(
|
||||
"add `change-id = {latest_change_id}` at the top of `bootstrap.toml`"
|
||||
));
|
||||
return Some(msg);
|
||||
}
|
||||
|
||||
// Always try to use `change-id` from .last-warned-change-id first. If it doesn't exist,
|
||||
// then use the one from the bootstrap.toml. This way we never show the same warnings
|
||||
// more than once.
|
||||
if let Ok(t) = fs::read_to_string(&warned_id_path) {
|
||||
let last_warned_id = usize::from_str(&t)
|
||||
.unwrap_or_else(|_| panic!("{} is corrupted.", warned_id_path.display()));
|
||||
|
||||
// We only use the last_warned_id if it exists in `CONFIG_CHANGE_HISTORY`.
|
||||
// Otherwise, we may retrieve all the changes if it's not the highest value.
|
||||
// For better understanding, refer to `change_tracker::find_recent_config_change_ids`.
|
||||
if CONFIG_CHANGE_HISTORY.iter().any(|config| config.change_id == last_warned_id) {
|
||||
id = last_warned_id;
|
||||
}
|
||||
};
|
||||
|
||||
let changes = find_recent_config_change_ids(id);
|
||||
|
||||
if changes.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
msg.push_str("There have been changes to x.py since you last updated:\n");
|
||||
msg.push_str(&human_readable_changes(&changes));
|
||||
|
||||
msg.push_str("NOTE: to silence this warning, ");
|
||||
msg.push_str(&format!(
|
||||
"update `bootstrap.toml` to use `change-id = {latest_change_id}` instead"
|
||||
));
|
||||
|
||||
if io::stdout().is_terminal() {
|
||||
t!(fs::write(warned_id_path, latest_change_id.to_string()));
|
||||
}
|
||||
} else {
|
||||
msg.push_str("WARNING: The `change-id` is missing in the `bootstrap.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n");
|
||||
msg.push_str("NOTE: to silence this warning, ");
|
||||
msg.push_str(&format!(
|
||||
"add `change-id = {latest_change_id}` at the top of `bootstrap.toml`"
|
||||
));
|
||||
};
|
||||
|
||||
// Always try to use `change-id` from .last-warned-change-id first. If it doesn't exist,
|
||||
// then use the one from the bootstrap.toml. This way we never show the same warnings
|
||||
// more than once.
|
||||
if let Ok(t) = fs::read_to_string(&warned_id_path) {
|
||||
let last_warned_id = usize::from_str(&t)
|
||||
.unwrap_or_else(|_| panic!("{} is corrupted.", warned_id_path.display()));
|
||||
|
||||
// We only use the last_warned_id if it exists in `CONFIG_CHANGE_HISTORY`.
|
||||
// Otherwise, we may retrieve all the changes if it's not the highest value.
|
||||
// For better understanding, refer to `change_tracker::find_recent_config_change_ids`.
|
||||
if CONFIG_CHANGE_HISTORY.iter().any(|config| config.change_id == last_warned_id) {
|
||||
id = last_warned_id;
|
||||
}
|
||||
};
|
||||
|
||||
let changes = find_recent_config_change_ids(id);
|
||||
|
||||
if changes.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
msg.push_str("There have been changes to x.py since you last updated:\n");
|
||||
msg.push_str(&human_readable_changes(&changes));
|
||||
|
||||
msg.push_str("NOTE: to silence this warning, ");
|
||||
msg.push_str(&format!(
|
||||
"update `bootstrap.toml` to use `change-id = {latest_change_id}` instead"
|
||||
));
|
||||
|
||||
if io::stdout().is_terminal() {
|
||||
t!(fs::write(warned_id_path, latest_change_id.to_string()));
|
||||
}
|
||||
|
||||
Some(msg)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ pub enum GccCiMode {
|
|||
/// `bootstrap.example.toml`.
|
||||
#[derive(Default, Clone)]
|
||||
pub struct Config {
|
||||
pub change_id: Option<usize>,
|
||||
pub change_id: Option<ChangeId>,
|
||||
pub bypass_bootstrap_lock: bool,
|
||||
pub ccache: Option<String>,
|
||||
/// Call Build::ninja() instead of this.
|
||||
|
|
@ -700,14 +700,32 @@ pub(crate) struct TomlConfig {
|
|||
profile: Option<String>,
|
||||
}
|
||||
|
||||
/// This enum is used for deserializing change IDs from TOML, allowing both numeric values and the string `"ignore"`.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ChangeId {
|
||||
Ignore,
|
||||
Id(usize),
|
||||
}
|
||||
|
||||
/// Since we use `#[serde(deny_unknown_fields)]` on `TomlConfig`, we need a wrapper type
|
||||
/// for the "change-id" field to parse it even if other fields are invalid. This ensures
|
||||
/// that if deserialization fails due to other fields, we can still provide the changelogs
|
||||
/// to allow developers to potentially find the reason for the failure in the logs..
|
||||
#[derive(Deserialize, Default)]
|
||||
pub(crate) struct ChangeIdWrapper {
|
||||
#[serde(alias = "change-id")]
|
||||
pub(crate) inner: Option<usize>,
|
||||
#[serde(alias = "change-id", default, deserialize_with = "deserialize_change_id")]
|
||||
pub(crate) inner: Option<ChangeId>,
|
||||
}
|
||||
|
||||
fn deserialize_change_id<'de, D: Deserializer<'de>>(
|
||||
deserializer: D,
|
||||
) -> Result<Option<ChangeId>, D::Error> {
|
||||
let value = toml::Value::deserialize(deserializer)?;
|
||||
Ok(match value {
|
||||
toml::Value::String(s) if s == "ignore" => Some(ChangeId::Ignore),
|
||||
toml::Value::Integer(i) => Some(ChangeId::Id(i as usize)),
|
||||
_ => return Err(serde::de::Error::custom("expected \"ignore\" or an integer")),
|
||||
})
|
||||
}
|
||||
|
||||
/// Describes how to handle conflicts in merging two [`TomlConfig`]
|
||||
|
|
@ -1351,10 +1369,11 @@ impl Config {
|
|||
toml::from_str(&contents)
|
||||
.and_then(|table: toml::Value| TomlConfig::deserialize(table))
|
||||
.inspect_err(|_| {
|
||||
if let Ok(Some(changes)) = toml::from_str(&contents)
|
||||
.and_then(|table: toml::Value| ChangeIdWrapper::deserialize(table))
|
||||
.map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids))
|
||||
if let Ok(ChangeIdWrapper { inner: Some(ChangeId::Id(id)) }) =
|
||||
toml::from_str::<toml::Value>(&contents)
|
||||
.and_then(|table: toml::Value| ChangeIdWrapper::deserialize(table))
|
||||
{
|
||||
let changes = crate::find_recent_config_change_ids(id);
|
||||
if !changes.is_empty() {
|
||||
println!(
|
||||
"WARNING: There have been changes to x.py since you last updated:\n{}",
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use serde::Deserialize;
|
|||
|
||||
use super::flags::Flags;
|
||||
use super::{ChangeIdWrapper, Config, RUSTC_IF_UNCHANGED_ALLOWED_PATHS};
|
||||
use crate::ChangeId;
|
||||
use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order};
|
||||
use crate::core::build_steps::llvm;
|
||||
use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS;
|
||||
|
|
@ -171,7 +172,7 @@ runner = "x86_64-runner"
|
|||
)
|
||||
},
|
||||
);
|
||||
assert_eq!(config.change_id, Some(1), "setting top-level value");
|
||||
assert_eq!(config.change_id, Some(ChangeId::Id(1)), "setting top-level value");
|
||||
assert_eq!(
|
||||
config.rust_lto,
|
||||
crate::core::config::RustcLto::Fat,
|
||||
|
|
@ -311,7 +312,7 @@ fn parse_change_id_with_unknown_field() {
|
|||
"#;
|
||||
|
||||
let change_id_wrapper: ChangeIdWrapper = toml::from_str(config).unwrap();
|
||||
assert_eq!(change_id_wrapper.inner, Some(3461));
|
||||
assert_eq!(change_id_wrapper.inner, Some(ChangeId::Id(3461)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ mod core;
|
|||
mod utils;
|
||||
|
||||
pub use core::builder::PathSet;
|
||||
pub use core::config::Config;
|
||||
pub use core::config::flags::{Flags, Subcommand};
|
||||
pub use core::config::{ChangeId, Config};
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
use tracing::{instrument, span};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue