From d06e0e53eb083895c0a98b918699e7047f7c87d7 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 15 Aug 2022 16:57:46 +0200 Subject: [PATCH 1/7] tidy: forbid since values for features that point to the current release or future ones It's a common phenomenon that feature stabilizations don't make it into a particular release, but the version is still inaccurate. Often this leads to subsequent changes to adjust/correct the version. Instead, require people to put a placeholder that gets replaced during beta branching time with the current rust version. That way, there is no chance that an error can be introduced. Usage of the placeholder is required on the nightly channel, and forbidden on the stable and beta channels. --- src/tools/tidy/src/features.rs | 38 ++++++++++++++++++++++++++ src/tools/tidy/src/features/version.rs | 19 ++++++++++--- src/tools/tidy/src/lib.rs | 3 +- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 2f22c081a54..de292d3305d 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -175,6 +175,36 @@ pub fn check( tidy_error!(bad, "Found {} features without a gate test.", gate_untested.len()); } + let (version, channel) = get_version_and_channel(src_path); + + let all_features_iter = features + .iter() + .map(|feat| (feat, "lang")) + .chain(lib_features.iter().map(|feat| (feat, "lib"))); + for ((feature_name, feature), kind) in all_features_iter { + let since = if let Some(since) = feature.since { since } else { continue }; + if since > version && since != Version::CurrentPlaceholder { + tidy_error!( + bad, + "The stabilization version {since} of {kind} feature `{feature_name}` is newer than the current {version}" + ); + } + if channel == "nightly" && since == version { + tidy_error!( + bad, + "The stabilization version {since} of {kind} feature `{feature_name}` is written out but should be {}", + version::VERSION_PLACEHOLDER + ); + } + if channel != "nightly" && since == Version::CurrentPlaceholder { + tidy_error!( + bad, + "The placeholder use of {kind} feature `{feature_name}` is not allowed on the {} channel", + version::VERSION_PLACEHOLDER + ); + } + } + if *bad { return CollectedFeatures { lib: lib_features, lang: features }; } @@ -195,6 +225,14 @@ pub fn check( CollectedFeatures { lib: lib_features, lang: features } } +fn get_version_and_channel(src_path: &Path) -> (Version, String) { + let version_str = t!(std::fs::read_to_string(src_path.join("version"))); + let version_str = version_str.trim(); + let version = t!(std::str::FromStr::from_str(&version_str).map_err(|e| format!("{e:?}"))); + let channel_str = t!(std::fs::read_to_string(src_path.join("ci").join("channel"))); + (version, channel_str.trim().to_owned()) +} + fn format_features<'a>( features: &'a Features, family: &'a str, diff --git a/src/tools/tidy/src/features/version.rs b/src/tools/tidy/src/features/version.rs index 620be2f9852..0830c226caf 100644 --- a/src/tools/tidy/src/features/version.rs +++ b/src/tools/tidy/src/features/version.rs @@ -5,14 +5,22 @@ use std::str::FromStr; #[cfg(test)] mod tests; +pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION"; + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct Version { - parts: [u32; 3], +pub enum Version { + Explicit { parts: [u32; 3] }, + CurrentPlaceholder, } impl fmt::Display for Version { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad(&format!("{}.{}.{}", self.parts[0], self.parts[1], self.parts[2])) + match self { + Version::Explicit { parts } => { + f.pad(&format!("{}.{}.{}", parts[0], parts[1], parts[2])) + } + Version::CurrentPlaceholder => f.pad(&format!("CURRENT")), + } } } @@ -32,6 +40,9 @@ impl FromStr for Version { type Err = ParseVersionError; fn from_str(s: &str) -> Result { + if s == VERSION_PLACEHOLDER { + return Ok(Version::CurrentPlaceholder); + } let mut iter = s.split('.').map(|part| Ok(part.parse()?)); let mut part = || iter.next().unwrap_or(Err(ParseVersionError::WrongNumberOfParts)); @@ -43,6 +54,6 @@ impl FromStr for Version { return Err(ParseVersionError::WrongNumberOfParts); } - Ok(Self { parts }) + Ok(Version::Explicit { parts }) } } diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 09848462ae2..e9315df4330 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -28,7 +28,8 @@ macro_rules! t { macro_rules! tidy_error { ($bad:expr, $fmt:expr) => ({ *$bad = true; - eprintln!("tidy error: {}", $fmt); + eprint!("tidy error: "); + eprintln!($fmt); }); ($bad:expr, $fmt:expr, $($arg:tt)*) => ({ *$bad = true; From 7a5b1d7939a39c38d3c644a9211b969319496be5 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 15 Aug 2022 17:28:43 +0200 Subject: [PATCH 2/7] Expand the version placeholder to the current version in stability attribute parsing That way, the current version is shown in rustdoc etc. --- compiler/rustc_passes/src/lib_features.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index 868887c66cd..70b6bfd1e58 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -54,6 +54,14 @@ impl<'tcx> LibFeatureCollector<'tcx> { } } } + const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION"; + + if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER { + let version = option_env!("CFG_VERSION").unwrap_or(""); + let version = version.split(' ').next().unwrap(); + since = Some(Symbol::intern(&version)); + } + if let Some(feature) = feature { // This additional check for stability is to make sure we // don't emit additional, irrelevant errors for malformed From e576a9b554f24a26c36c04b41c901636d190605b Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 15 Aug 2022 17:34:09 +0200 Subject: [PATCH 3/7] Adjust ptr_const_cast stabilization version to CURRENT_RUSTC_VERSION --- library/core/src/ptr/const_ptr.rs | 4 ++-- library/core/src/ptr/mut_ptr.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 08fbb79fa65..b8486af0018 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -95,8 +95,8 @@ impl *const T { /// /// This is a bit safer than `as` because it wouldn't silently change the type if the code is /// refactored. - #[stable(feature = "ptr_const_cast", since = "1.65.0")] - #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")] + #[stable(feature = "ptr_const_cast", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ptr_const_cast", since = "CURRENT_RUSTC_VERSION")] pub const fn cast_mut(self) -> *mut T { self as _ } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 84674690531..a1836140559 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -100,8 +100,8 @@ impl *mut T { /// coercion. /// /// [`cast_mut`]: #method.cast_mut - #[stable(feature = "ptr_const_cast", since = "1.65.0")] - #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")] + #[stable(feature = "ptr_const_cast", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ptr_const_cast", since = "CURRENT_RUSTC_VERSION")] pub const fn cast_const(self) -> *const T { self as _ } From 6e4e3e84b544bcec30b0e4dab64b8f33ea0ce06e Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 15 Aug 2022 17:35:34 +0200 Subject: [PATCH 4/7] Adjust backtrace stabilization version to CURRENT_RUSTC_VERSION --- library/std/src/backtrace.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs index 5cf6ec81789..354200d4c95 100644 --- a/library/std/src/backtrace.rs +++ b/library/std/src/backtrace.rs @@ -58,7 +58,7 @@ //! `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` at runtime might not actually change //! how backtraces are captured. -#![stable(feature = "backtrace", since = "1.65.0")] +#![stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] #[cfg(test)] mod tests; @@ -104,7 +104,7 @@ use crate::vec::Vec; /// previous point in time. In some instances the `Backtrace` type may /// internally be empty due to configuration. For more information see /// `Backtrace::capture`. -#[stable(feature = "backtrace", since = "1.65.0")] +#[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] #[must_use] pub struct Backtrace { inner: Inner, @@ -112,21 +112,21 @@ pub struct Backtrace { /// The current status of a backtrace, indicating whether it was captured or /// whether it is empty for some other reason. -#[stable(feature = "backtrace", since = "1.65.0")] +#[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] #[non_exhaustive] #[derive(Debug, PartialEq, Eq)] pub enum BacktraceStatus { /// Capturing a backtrace is not supported, likely because it's not /// implemented for the current platform. - #[stable(feature = "backtrace", since = "1.65.0")] + #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] Unsupported, /// Capturing a backtrace has been disabled through either the /// `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` environment variables. - #[stable(feature = "backtrace", since = "1.65.0")] + #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] Disabled, /// A backtrace has been captured and the `Backtrace` should print /// reasonable information when rendered. - #[stable(feature = "backtrace", since = "1.65.0")] + #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] Captured, } @@ -173,7 +173,7 @@ enum BytesOrWide { Wide(Vec), } -#[stable(feature = "backtrace", since = "1.65.0")] +#[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for Backtrace { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let capture = match &self.inner { @@ -289,7 +289,7 @@ impl Backtrace { /// /// To forcibly capture a backtrace regardless of environment variables, use /// the `Backtrace::force_capture` function. - #[stable(feature = "backtrace", since = "1.65.0")] + #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] #[inline(never)] // want to make sure there's a frame here to remove pub fn capture() -> Backtrace { if !Backtrace::enabled() { @@ -308,7 +308,7 @@ impl Backtrace { /// Note that capturing a backtrace can be an expensive operation on some /// platforms, so this should be used with caution in performance-sensitive /// parts of code. - #[stable(feature = "backtrace", since = "1.65.0")] + #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] #[inline(never)] // want to make sure there's a frame here to remove pub fn force_capture() -> Backtrace { Backtrace::create(Backtrace::force_capture as usize) @@ -316,8 +316,8 @@ impl Backtrace { /// Forcibly captures a disabled backtrace, regardless of environment /// variable configuration. - #[stable(feature = "backtrace", since = "1.65.0")] - #[rustc_const_stable(feature = "backtrace", since = "1.65.0")] + #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] pub const fn disabled() -> Backtrace { Backtrace { inner: Inner::Disabled } } @@ -361,7 +361,7 @@ impl Backtrace { /// Returns the status of this backtrace, indicating whether this backtrace /// request was unsupported, disabled, or a stack trace was actually /// captured. - #[stable(feature = "backtrace", since = "1.65.0")] + #[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] #[must_use] pub fn status(&self) -> BacktraceStatus { match self.inner { @@ -381,7 +381,7 @@ impl<'a> Backtrace { } } -#[stable(feature = "backtrace", since = "1.65.0")] +#[stable(feature = "backtrace", since = "CURRENT_RUSTC_VERSION")] impl fmt::Display for Backtrace { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let capture = match &self.inner { From 4caedbae869855a19ca49455e2cd338ae3b8c1ef Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 27 Aug 2022 17:35:46 +0200 Subject: [PATCH 5/7] Adjust label break value stabilization version to CURRENT_RUSTC_VERSION --- compiler/rustc_feature/src/accepted.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 37b2b0ecad7..fb1ad8d6beb 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -187,7 +187,7 @@ declare_features! ( /// especially around globs and shadowing (RFC 1560). (accepted, item_like_imports, "1.15.0", Some(35120), None), /// Allows `'a: { break 'a; }`. - (accepted, label_break_value, "1.65.0", Some(48594), None), + (accepted, label_break_value, "CURRENT_RUSTC_VERSION", Some(48594), None), /// Allows `if/while p && let q = r && ...` chains. (accepted, let_chains, "1.64.0", Some(53667), None), /// Allows `break {expr}` with a value inside `loop`s. From a2e2d7676822600c81a519343c7eccab9204334b Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 23 Aug 2022 18:45:29 +0200 Subject: [PATCH 6/7] tidy: move directory traversal utility functions into dedicated module --- src/tools/tidy/src/lib.rs | 69 +++++--------------------------------- src/tools/tidy/src/walk.rs | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 61 deletions(-) create mode 100644 src/tools/tidy/src/walk.rs diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index e9315df4330..12d3bdcd76f 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -3,12 +3,14 @@ //! This library contains the tidy lints and exposes it //! to be used by tools. -use std::fs::File; -use std::io::Read; -use walkdir::{DirEntry, WalkDir}; - -use std::path::Path; +use walk::{filter_dirs, walk, walk_many, walk_no_read}; +/// A helper macro to `unwrap` a result except also print out details like: +/// +/// * The expression that failed +/// * The error itself +/// * (optionally) a path connected to the error (e.g. failure to open a file) +#[macro_export] macro_rules! t { ($e:expr, $p:expr) => { match $e { @@ -53,59 +55,4 @@ pub mod target_specific_tests; pub mod ui_tests; pub mod unit_tests; pub mod unstable_book; - -fn filter_dirs(path: &Path) -> bool { - let skip = [ - "tidy-test-file", - "compiler/rustc_codegen_cranelift", - "compiler/rustc_codegen_gcc", - "src/llvm-project", - "library/backtrace", - "library/portable-simd", - "library/stdarch", - "src/tools/cargo", - "src/tools/clippy", - "src/tools/miri", - "src/tools/rls", - "src/tools/rust-analyzer", - "src/tools/rust-installer", - "src/tools/rustfmt", - "src/doc/book", - // Filter RLS output directories - "target/rls", - ]; - skip.iter().any(|p| path.ends_with(p)) -} - -fn walk_many( - paths: &[&Path], - skip: &mut dyn FnMut(&Path) -> bool, - f: &mut dyn FnMut(&DirEntry, &str), -) { - for path in paths { - walk(path, skip, f); - } -} - -fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry, &str)) { - let mut contents = String::new(); - walk_no_read(path, skip, &mut |entry| { - contents.clear(); - if t!(File::open(entry.path()), entry.path()).read_to_string(&mut contents).is_err() { - contents.clear(); - } - f(&entry, &contents); - }); -} - -fn walk_no_read(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry)) { - let walker = WalkDir::new(path).into_iter().filter_entry(|e| !skip(e.path())); - for entry in walker { - if let Ok(entry) = entry { - if entry.file_type().is_dir() { - continue; - } - f(&entry); - } - } -} +pub mod walk; diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs new file mode 100644 index 00000000000..6dca55dfa9f --- /dev/null +++ b/src/tools/tidy/src/walk.rs @@ -0,0 +1,65 @@ +use std::fs::File; +use std::io::Read; +use walkdir::{DirEntry, WalkDir}; + +use std::path::Path; + +pub fn filter_dirs(path: &Path) -> bool { + let skip = [ + "tidy-test-file", + "compiler/rustc_codegen_cranelift", + "compiler/rustc_codegen_gcc", + "src/llvm-project", + "library/backtrace", + "library/portable-simd", + "library/stdarch", + "src/tools/cargo", + "src/tools/clippy", + "src/tools/miri", + "src/tools/rls", + "src/tools/rust-analyzer", + "src/tools/rust-installer", + "src/tools/rustfmt", + "src/doc/book", + // Filter RLS output directories + "target/rls", + ]; + skip.iter().any(|p| path.ends_with(p)) +} + +pub fn walk_many( + paths: &[&Path], + skip: &mut dyn FnMut(&Path) -> bool, + f: &mut dyn FnMut(&DirEntry, &str), +) { + for path in paths { + walk(path, skip, f); + } +} + +pub fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry, &str)) { + let mut contents = String::new(); + walk_no_read(path, skip, &mut |entry| { + contents.clear(); + if t!(File::open(entry.path()), entry.path()).read_to_string(&mut contents).is_err() { + contents.clear(); + } + f(&entry, &contents); + }); +} + +pub(crate) fn walk_no_read( + path: &Path, + skip: &mut dyn FnMut(&Path) -> bool, + f: &mut dyn FnMut(&DirEntry), +) { + let walker = WalkDir::new(path).into_iter().filter_entry(|e| !skip(e.path())); + for entry in walker { + if let Ok(entry) = entry { + if entry.file_type().is_dir() { + continue; + } + f(&entry); + } + } +} From d32ff14b86c72f55a113a3f477c42b2995e8c620 Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 23 Aug 2022 22:14:12 +0200 Subject: [PATCH 7/7] Add replace-version-placeholder tool This tool is to be ran at specific points in the release process to replace the version place holder made by stabilizations with the version number. --- Cargo.lock | 8 ++++ Cargo.toml | 1 + src/bootstrap/builder.rs | 8 +++- src/bootstrap/run.rs | 22 +++++++++++ src/bootstrap/test.rs | 37 +++++++++++++++++++ src/bootstrap/tool.rs | 1 + .../replace-version-placeholder/Cargo.toml | 10 +++++ .../replace-version-placeholder/src/main.rs | 30 +++++++++++++++ 8 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 src/tools/replace-version-placeholder/Cargo.toml create mode 100644 src/tools/replace-version-placeholder/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 2ea32a80120..dda8c03e256 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3293,6 +3293,14 @@ dependencies = [ "winapi", ] +[[package]] +name = "replace-version-placeholder" +version = "0.1.0" +dependencies = [ + "tidy", + "walkdir", +] + [[package]] name = "rls" version = "1.41.0" diff --git a/Cargo.toml b/Cargo.toml index ffc886d47f3..1e83f05e0ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ members = [ "src/tools/jsondocck", "src/tools/html-checker", "src/tools/bump-stage0", + "src/tools/replace-version-placeholder", "src/tools/lld-wrapper", ] diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index ba732cd7742..c4710e8faec 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -647,6 +647,7 @@ impl<'a> Builder<'a> { test::CrateRustdocJsonTypes, test::Linkcheck, test::TierCheck, + test::ReplacePlaceholderTest, test::Cargotest, test::Cargo, test::Rls, @@ -746,7 +747,12 @@ impl<'a> Builder<'a> { install::Src, install::Rustc ), - Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest, run::BumpStage0), + Kind::Run => describe!( + run::ExpandYamlAnchors, + run::BuildManifest, + run::BumpStage0, + run::ReplaceVersionPlaceholder, + ), // These commands either don't use paths, or they're special-cased in Build::build() Kind::Clean | Kind::Format | Kind::Setup => vec![], } diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 25abe7a72fd..511872903d1 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -103,3 +103,25 @@ impl Step for BumpStage0 { builder.run(&mut cmd); } } + +#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ReplaceVersionPlaceholder; + +impl Step for ReplaceVersionPlaceholder { + type Output = (); + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/replace-version-placeholder") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(ReplaceVersionPlaceholder); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + let mut cmd = builder.tool_cmd(Tool::ReplaceVersionPlaceholder); + cmd.arg(&builder.src); + builder.run(&mut cmd); + } +} diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index c759d9b88e2..9cbdb3aca32 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -2527,6 +2527,43 @@ impl Step for TierCheck { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct ReplacePlaceholderTest; + +impl Step for ReplacePlaceholderTest { + type Output = (); + const ONLY_HOSTS: bool = true; + const DEFAULT: bool = true; + + /// Ensure the version placeholder replacement tool builds + fn run(self, builder: &Builder<'_>) { + builder.info("build check for version replacement placeholder"); + + // Test the version placeholder replacement tool itself. + let bootstrap_host = builder.config.build; + let compiler = builder.compiler(0, bootstrap_host); + let cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolBootstrap, + bootstrap_host, + "test", + "src/tools/replace-version-placeholder", + SourceType::InTree, + &[], + ); + try_run(builder, &mut cargo.into()); + } + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/replace-version-placeholder") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Self); + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct LintDocs { pub compiler: Compiler, diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 570da20e7d6..5bb40014eb9 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -378,6 +378,7 @@ bootstrap_tool!( JsonDocCk, "src/tools/jsondocck", "jsondocck"; HtmlChecker, "src/tools/html-checker", "html-checker"; BumpStage0, "src/tools/bump-stage0", "bump-stage0"; + ReplaceVersionPlaceholder, "src/tools/replace-version-placeholder", "replace-version-placeholder"; ); #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] diff --git a/src/tools/replace-version-placeholder/Cargo.toml b/src/tools/replace-version-placeholder/Cargo.toml new file mode 100644 index 00000000000..346ce6bd1db --- /dev/null +++ b/src/tools/replace-version-placeholder/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "replace-version-placeholder" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tidy = { path = "../tidy" } +walkdir = "2" diff --git a/src/tools/replace-version-placeholder/src/main.rs b/src/tools/replace-version-placeholder/src/main.rs new file mode 100644 index 00000000000..146e53f2e9a --- /dev/null +++ b/src/tools/replace-version-placeholder/src/main.rs @@ -0,0 +1,30 @@ +use std::path::PathBuf; +use tidy::{t, walk}; + +pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION"; + +fn main() { + let root_path: PathBuf = std::env::args_os().nth(1).expect("need path to root of repo").into(); + let version_path = root_path.join("src").join("version"); + let version_str = t!(std::fs::read_to_string(&version_path), version_path); + let version_str = version_str.trim(); + walk::walk( + &root_path, + &mut |path| { + walk::filter_dirs(path) + // We exempt these as they require the placeholder + // for their operation + || path.ends_with("compiler/rustc_passes/src/lib_features.rs") + || path.ends_with("src/tools/tidy/src/features/version.rs") + || path.ends_with("src/tools/replace-version-placeholder") + }, + &mut |entry, contents| { + if !contents.contains(VERSION_PLACEHOLDER) { + return; + } + let new_contents = contents.replace(VERSION_PLACEHOLDER, version_str); + let path = entry.path(); + t!(std::fs::write(&path, new_contents), path); + }, + ); +}