From 0f6f458cc1b460076093efda903bf1a1b9062697 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Mar 2021 16:35:27 +0300 Subject: Make working with codegen less annoying We probably should look into removing `xtask codegen` altogether. The test workflow works perfectly for package.json config. There are two things preventing that: * Lint completions are generated on demand. * Docs are not committed to the repository. --- xtask/src/codegen.rs | 17 ++++++++++++----- xtask/src/main.rs | 13 +++++++++---- xtask/src/tidy.rs | 16 ++++------------ 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index 2f56c5ad0..e3f9ccada 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs @@ -32,7 +32,7 @@ pub(crate) use self::{ #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub(crate) enum Mode { Overwrite, - Verify, + Ensure, } impl flags::Codegen { @@ -59,12 +59,19 @@ fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { } _ => (), } - if mode == Mode::Verify { - anyhow::bail!("`{}` is not up-to-date", path.display()); - } + let return_error = match mode { + Mode::Overwrite => false, + Mode::Ensure => true, + }; eprintln!("updating {}", path.display()); write_file(path, contents)?; - return Ok(()); + + return if return_error { + let path = path.strip_prefix(&project_root()).unwrap_or(path); + anyhow::bail!("`{}` was not up-to-date, updating", path.display()); + } else { + Ok(()) + }; fn normalize(s: &str) -> String { s.replace("\r\n", "\n") diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 3c4332f75..25fd32f92 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -89,11 +89,16 @@ fn run_rustfmt(mode: Mode) -> Result<()> { let _dir = pushd(project_root())?; let _e = pushenv("RUSTUP_TOOLCHAIN", "stable"); ensure_rustfmt()?; - let check = match mode { - Mode::Overwrite => &[][..], - Mode::Verify => &["--", "--check"], + match mode { + Mode::Overwrite => cmd!("cargo fmt").run()?, + Mode::Ensure => { + let res = cmd!("cargo fmt -- --check").run(); + if !res.is_ok() { + let _ = cmd!("cargo fmt").run(); + } + res?; + } }; - cmd!("cargo fmt {check...}").run()?; Ok(()) } diff --git a/xtask/src/tidy.rs b/xtask/src/tidy.rs index 349ca14d0..3818b9e0f 100644 --- a/xtask/src/tidy.rs +++ b/xtask/src/tidy.rs @@ -13,30 +13,22 @@ use crate::{ #[test] fn generated_grammar_is_fresh() { - if let Err(error) = codegen::generate_syntax(Mode::Verify) { - panic!("{}. Please update it by running `cargo xtask codegen`", error); - } + codegen::generate_syntax(Mode::Ensure).unwrap() } #[test] fn generated_tests_are_fresh() { - if let Err(error) = codegen::generate_parser_tests(Mode::Verify) { - panic!("{}. Please update tests by running `cargo xtask codegen`", error); - } + codegen::generate_parser_tests(Mode::Ensure).unwrap() } #[test] fn generated_assists_are_fresh() { - if let Err(error) = codegen::generate_assists_tests(Mode::Verify) { - panic!("{}. Please update assists by running `cargo xtask codegen`", error); - } + codegen::generate_assists_tests(Mode::Ensure).unwrap(); } #[test] fn check_code_formatting() { - if let Err(error) = run_rustfmt(Mode::Verify) { - panic!("{}. Please format the code by running `cargo format`", error); - } + run_rustfmt(Mode::Ensure).unwrap() } #[test] -- cgit v1.2.3 From b6ba0dec0c08dd2afcda951b09966b457f2c8bc3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Mar 2021 17:20:36 +0300 Subject: Generalize file ensuring infrastructure --- crates/rust-analyzer/src/config.rs | 9 ++++----- crates/test_utils/src/lib.rs | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 4dbabdba7..02468631b 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -859,12 +859,12 @@ fn manual(fields: &[(&'static str, &'static str, &[&str], &str)]) -> String { mod tests { use std::fs; - use test_utils::project_dir; + use test_utils::{ensure_file_contents, project_dir}; use super::*; #[test] - fn schema_in_sync_with_package_json() { + fn ensure_schema_in_package_json() { let s = Config::json_schema(); let schema = format!("{:#}", s); let mut schema = schema @@ -885,13 +885,12 @@ mod tests { let start = package_json.find(start_marker).unwrap() + start_marker.len(); let end = package_json.find(end_marker).unwrap(); + let p = remove_ws(&package_json[start..end]); let s = remove_ws(&schema); - if !p.contains(&s) { package_json.replace_range(start..end, &schema); - fs::write(&package_json_path, &mut package_json).unwrap(); - panic!("new config, updating package.json") + ensure_file_contents(&package_json_path, &package_json) } } diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 27b05e34b..7f122b13e 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs @@ -14,7 +14,7 @@ mod fixture; use std::{ convert::{TryFrom, TryInto}, env, fs, - path::PathBuf, + path::{Path, PathBuf}, }; use profile::StopWatch; @@ -353,3 +353,36 @@ pub fn bench(label: &'static str) -> impl Drop { Bencher { sw: StopWatch::start(), label } } + +/// Checks that the `file` has the specified `contents`. If that is not the +/// case, updates the file and then fails the test. +pub fn ensure_file_contents(file: &Path, contents: &str) { + if let Err(()) = try_ensure_file_contents(file, contents) { + panic!("Some files were not up-to-date"); + } +} + +/// Checks that the `file` has the specified `contents`. If that is not the +/// case, updates the file and return an Error. +pub fn try_ensure_file_contents(file: &Path, contents: &str) -> Result<(), ()> { + match std::fs::read_to_string(file) { + Ok(old_contents) if normalize_newlines(&old_contents) == normalize_newlines(contents) => { + return Ok(()) + } + _ => (), + } + let display_path = file.strip_prefix(&project_dir()).unwrap_or(file); + eprintln!( + "\n\x1b[31;1merror\x1b[0m: {} was not up-to-date, updating\n", + display_path.display() + ); + if let Some(parent) = file.parent() { + let _ = std::fs::create_dir_all(parent); + } + std::fs::write(file, contents).unwrap(); + Err(()) +} + +fn normalize_newlines(s: &str) -> String { + s.replace("\r\n", "\n") +} -- cgit v1.2.3 From abb6b8f14c4d05cf344048263651d8192997b6cf Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Mar 2021 20:22:33 +0300 Subject: Use the same name in xtask and test utils --- crates/rust-analyzer/src/config.rs | 6 +++--- crates/syntax/src/tests.rs | 6 +++--- crates/test_utils/src/bench_fixture.rs | 6 +++--- crates/test_utils/src/lib.rs | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 02468631b..bceca2b0f 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -859,7 +859,7 @@ fn manual(fields: &[(&'static str, &'static str, &[&str], &str)]) -> String { mod tests { use std::fs; - use test_utils::{ensure_file_contents, project_dir}; + use test_utils::{ensure_file_contents, project_root}; use super::*; @@ -877,7 +877,7 @@ mod tests { .to_string(); schema.push_str(",\n"); - let package_json_path = project_dir().join("editors/code/package.json"); + let package_json_path = project_root().join("editors/code/package.json"); let mut package_json = fs::read_to_string(&package_json_path).unwrap(); let start_marker = " \"$generated-start\": false,\n"; @@ -896,7 +896,7 @@ mod tests { #[test] fn schema_in_sync_with_docs() { - let docs_path = project_dir().join("docs/user/generated_config.adoc"); + let docs_path = project_root().join("docs/user/generated_config.adoc"); let current = fs::read_to_string(&docs_path).unwrap(); let expected = ConfigData::manual(); diff --git a/crates/syntax/src/tests.rs b/crates/syntax/src/tests.rs index b2c06e24f..ba0ccfaed 100644 --- a/crates/syntax/src/tests.rs +++ b/crates/syntax/src/tests.rs @@ -7,7 +7,7 @@ use std::{ use ast::NameOwner; use expect_test::expect_file; use rayon::prelude::*; -use test_utils::{bench, bench_fixture, project_dir, skip_slow_tests}; +use test_utils::{bench, bench_fixture, project_root, skip_slow_tests}; use crate::{ast, fuzz, tokenize, AstNode, SourceFile, SyntaxError, TextRange, TextSize, Token}; @@ -153,7 +153,7 @@ fn reparse_fuzz_tests() { /// Test that Rust-analyzer can parse and validate the rust-analyzer #[test] fn self_hosting_parsing() { - let dir = project_dir().join("crates"); + let dir = project_root().join("crates"); let files = walkdir::WalkDir::new(dir) .into_iter() .filter_entry(|entry| { @@ -193,7 +193,7 @@ fn self_hosting_parsing() { } fn test_data_dir() -> PathBuf { - project_dir().join("crates/syntax/test_data") + project_root().join("crates/syntax/test_data") } fn assert_errors_are_present(errors: &[SyntaxError], path: &Path) { diff --git a/crates/test_utils/src/bench_fixture.rs b/crates/test_utils/src/bench_fixture.rs index d775e2cc9..3a37c4473 100644 --- a/crates/test_utils/src/bench_fixture.rs +++ b/crates/test_utils/src/bench_fixture.rs @@ -4,7 +4,7 @@ use std::fs; use stdx::format_to; -use crate::project_dir; +use crate::project_root; pub fn big_struct() -> String { let n = 1_000; @@ -32,11 +32,11 @@ struct S{} {{ } pub fn glorious_old_parser() -> String { - let path = project_dir().join("bench_data/glorious_old_parser"); + let path = project_root().join("bench_data/glorious_old_parser"); fs::read_to_string(&path).unwrap() } pub fn numerous_macro_rules() -> String { - let path = project_dir().join("bench_data/numerous_macro_rules"); + let path = project_root().join("bench_data/numerous_macro_rules"); fs::read_to_string(&path).unwrap() } diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 7f122b13e..097a54139 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs @@ -288,14 +288,14 @@ pub fn skip_slow_tests() -> bool { if should_skip { eprintln!("ignoring slow test") } else { - let path = project_dir().join("./target/.slow_tests_cookie"); + let path = project_root().join("./target/.slow_tests_cookie"); fs::write(&path, ".").unwrap(); } should_skip } /// Returns the path to the root directory of `rust-analyzer` project. -pub fn project_dir() -> PathBuf { +pub fn project_root() -> PathBuf { let dir = env!("CARGO_MANIFEST_DIR"); PathBuf::from(dir).parent().unwrap().parent().unwrap().to_owned() } @@ -371,7 +371,7 @@ pub fn try_ensure_file_contents(file: &Path, contents: &str) -> Result<(), ()> { } _ => (), } - let display_path = file.strip_prefix(&project_dir()).unwrap_or(file); + let display_path = file.strip_prefix(&project_root()).unwrap_or(file); eprintln!( "\n\x1b[31;1merror\x1b[0m: {} was not up-to-date, updating\n", display_path.display() -- cgit v1.2.3 From 1eb61203b725684fd2c7e25ac7e2d53eef10c64c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Mar 2021 21:13:15 +0300 Subject: Make `code generation` just work Contributors don't need to learn about `cargo xtask codegen` if `cargo test` just does the right thing. --- crates/rust-analyzer/src/config.rs | 4 ++-- crates/test_utils/src/lib.rs | 5 ++++- docs/dev/architecture.md | 3 +-- xtask/src/codegen.rs | 43 ++++++++++++++++++-------------------- xtask/src/flags.rs | 10 --------- xtask/src/main.rs | 1 - xtask/src/release.rs | 5 ++--- xtask/src/tidy.rs | 21 ++++++++++++------- 8 files changed, 42 insertions(+), 50 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index bceca2b0f..078c83f75 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -864,7 +864,7 @@ mod tests { use super::*; #[test] - fn ensure_schema_in_package_json() { + fn generate_package_json_config() { let s = Config::json_schema(); let schema = format!("{:#}", s); let mut schema = schema @@ -895,7 +895,7 @@ mod tests { } #[test] - fn schema_in_sync_with_docs() { + fn generate_config_documentation() { let docs_path = project_root().join("docs/user/generated_config.adoc"); let current = fs::read_to_string(&docs_path).unwrap(); let expected = ConfigData::manual(); diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 097a54139..dd582c77c 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs @@ -18,7 +18,7 @@ use std::{ }; use profile::StopWatch; -use stdx::lines_with_ends; +use stdx::{is_ci, lines_with_ends}; use text_size::{TextRange, TextSize}; pub use dissimilar::diff as __diff; @@ -376,6 +376,9 @@ pub fn try_ensure_file_contents(file: &Path, contents: &str) -> Result<(), ()> { "\n\x1b[31;1merror\x1b[0m: {} was not up-to-date, updating\n", display_path.display() ); + if is_ci() { + eprintln!("\n NOTE: run `cargo test` locally and commit the updated files\n"); + } if let Some(parent) = file.parent() { let _ = std::fs::create_dir_all(parent); } diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md index ead12616e..0a3fd4285 100644 --- a/docs/dev/architecture.md +++ b/docs/dev/architecture.md @@ -308,9 +308,8 @@ This sections talks about the things which are everywhere and nowhere in particu ### Code generation Some of the components of this repository are generated through automatic processes. -`cargo xtask codegen` runs all generation tasks. +Generated code is updated automatically on `cargo test`. Generated code is generally committed to the git repository. -There are tests to check that the generated code is fresh. In particular, we generate: diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index e3f9ccada..7cdd8f251 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs @@ -7,9 +7,9 @@ mod gen_syntax; mod gen_parser_tests; +mod gen_lint_completions; mod gen_assists_docs; mod gen_feature_docs; -mod gen_lint_completions; mod gen_diagnostic_docs; use std::{ @@ -18,38 +18,35 @@ use std::{ }; use xshell::{cmd, pushenv, read_file, write_file}; -use crate::{ensure_rustfmt, flags, project_root, Result}; +use crate::{ensure_rustfmt, project_root, Result}; pub(crate) use self::{ - gen_assists_docs::{generate_assists_docs, generate_assists_tests}, - gen_diagnostic_docs::generate_diagnostic_docs, - gen_feature_docs::generate_feature_docs, - gen_lint_completions::generate_lint_completions, - gen_parser_tests::generate_parser_tests, - gen_syntax::generate_syntax, + gen_assists_docs::generate_assists_tests, gen_lint_completions::generate_lint_completions, + gen_parser_tests::generate_parser_tests, gen_syntax::generate_syntax, }; +pub(crate) fn docs() -> Result<()> { + // We don't commit docs to the repo, so we can just overwrite them. + gen_assists_docs::generate_assists_docs(Mode::Overwrite)?; + gen_feature_docs::generate_feature_docs(Mode::Overwrite)?; + gen_diagnostic_docs::generate_diagnostic_docs(Mode::Overwrite)?; + Ok(()) +} + +#[allow(unused)] +fn used() { + generate_parser_tests(Mode::Overwrite); + generate_assists_tests(Mode::Overwrite); + generate_syntax(Mode::Overwrite); + generate_lint_completions(Mode::Overwrite); +} + #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub(crate) enum Mode { Overwrite, Ensure, } -impl flags::Codegen { - pub(crate) fn run(self) -> Result<()> { - if self.features { - generate_lint_completions(Mode::Overwrite)?; - } - generate_syntax(Mode::Overwrite)?; - generate_parser_tests(Mode::Overwrite)?; - generate_assists_tests(Mode::Overwrite)?; - generate_assists_docs(Mode::Overwrite)?; - generate_feature_docs(Mode::Overwrite)?; - generate_diagnostic_docs(Mode::Overwrite)?; - Ok(()) - } -} - /// A helper to update file on disk if it has changed. /// With verify = false, fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs index b39d937ca..48d1ad45e 100644 --- a/xtask/src/flags.rs +++ b/xtask/src/flags.rs @@ -27,10 +27,6 @@ xflags::xflags! { optional --jemalloc } - cmd codegen { - optional --features - } - cmd lint {} cmd fuzz-tests {} cmd pre-cache {} @@ -67,7 +63,6 @@ pub struct Xtask { pub enum XtaskCmd { Help(Help), Install(Install), - Codegen(Codegen), Lint(Lint), FuzzTests(FuzzTests), PreCache(PreCache), @@ -92,11 +87,6 @@ pub struct Install { pub jemalloc: bool, } -#[derive(Debug)] -pub struct Codegen { - pub features: bool, -} - #[derive(Debug)] pub struct Lint; diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 25fd32f92..c2dda928e 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -40,7 +40,6 @@ fn main() -> Result<()> { return Ok(()); } flags::XtaskCmd::Install(cmd) => cmd.run(), - flags::XtaskCmd::Codegen(cmd) => cmd.run(), flags::XtaskCmd::Lint(_) => run_clippy(), flags::XtaskCmd::FuzzTests(_) => run_fuzzer(), flags::XtaskCmd::PreCache(cmd) => cmd.run(), diff --git a/xtask/src/release.rs b/xtask/src/release.rs index d8d86fd63..dde5d14ee 100644 --- a/xtask/src/release.rs +++ b/xtask/src/release.rs @@ -2,7 +2,7 @@ use std::fmt::Write; use xshell::{cmd, cp, pushd, read_dir, write_file}; -use crate::{codegen, date_iso, flags, is_release_tag, project_root, Mode, Result}; +use crate::{codegen, date_iso, flags, is_release_tag, project_root, Result}; impl flags::Release { pub(crate) fn run(self) -> Result<()> { @@ -12,8 +12,7 @@ impl flags::Release { cmd!("git reset --hard tags/nightly").run()?; cmd!("git push").run()?; } - codegen::generate_assists_docs(Mode::Overwrite)?; - codegen::generate_feature_docs(Mode::Overwrite)?; + codegen::docs()?; let website_root = project_root().join("../rust-analyzer.github.io"); let changelog_dir = website_root.join("./thisweek/_posts"); diff --git a/xtask/src/tidy.rs b/xtask/src/tidy.rs index 3818b9e0f..03b4c0092 100644 --- a/xtask/src/tidy.rs +++ b/xtask/src/tidy.rs @@ -12,31 +12,36 @@ use crate::{ }; #[test] -fn generated_grammar_is_fresh() { +fn generate_grammar() { codegen::generate_syntax(Mode::Ensure).unwrap() } #[test] -fn generated_tests_are_fresh() { +fn generate_parser_tests() { codegen::generate_parser_tests(Mode::Ensure).unwrap() } #[test] -fn generated_assists_are_fresh() { +fn generate_assists_tests() { codegen::generate_assists_tests(Mode::Ensure).unwrap(); } +/// This clones rustc repo, and so is not worth to keep up-to-date. We update +/// manually by un-ignoring the test from time to time. +#[test] +#[ignore] +fn generate_lint_completions() { + codegen::generate_lint_completions(Mode::Overwrite).unwrap() +} + #[test] fn check_code_formatting() { run_rustfmt(Mode::Ensure).unwrap() } #[test] -fn smoke_test_docs_generation() { - // We don't commit docs to the repo, so we can just overwrite in tests. - codegen::generate_assists_docs(Mode::Overwrite).unwrap(); - codegen::generate_feature_docs(Mode::Overwrite).unwrap(); - codegen::generate_diagnostic_docs(Mode::Overwrite).unwrap(); +fn smoke_test_generate_documentation() { + codegen::docs().unwrap() } #[test] -- cgit v1.2.3 From 095b9110b5e4e166c86501a1f0603cf626a48127 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Mar 2021 21:25:44 +0300 Subject: Unused params --- xtask/src/codegen.rs | 6 +++--- xtask/src/codegen/gen_assists_docs.rs | 4 ++-- xtask/src/codegen/gen_diagnostic_docs.rs | 4 ++-- xtask/src/codegen/gen_feature_docs.rs | 4 ++-- xtask/src/tidy.rs | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index 7cdd8f251..2248a079f 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs @@ -27,9 +27,9 @@ pub(crate) use self::{ pub(crate) fn docs() -> Result<()> { // We don't commit docs to the repo, so we can just overwrite them. - gen_assists_docs::generate_assists_docs(Mode::Overwrite)?; - gen_feature_docs::generate_feature_docs(Mode::Overwrite)?; - gen_diagnostic_docs::generate_diagnostic_docs(Mode::Overwrite)?; + gen_assists_docs::generate_assists_docs()?; + gen_feature_docs::generate_feature_docs()?; + gen_diagnostic_docs::generate_diagnostic_docs()?; Ok(()) } diff --git a/xtask/src/codegen/gen_assists_docs.rs b/xtask/src/codegen/gen_assists_docs.rs index c469b388d..a5af1331d 100644 --- a/xtask/src/codegen/gen_assists_docs.rs +++ b/xtask/src/codegen/gen_assists_docs.rs @@ -12,12 +12,12 @@ pub(crate) fn generate_assists_tests(mode: Mode) -> Result<()> { generate_tests(&assists, mode) } -pub(crate) fn generate_assists_docs(mode: Mode) -> Result<()> { +pub(crate) fn generate_assists_docs() -> Result<()> { let assists = Assist::collect()?; let contents = assists.into_iter().map(|it| it.to_string()).collect::>().join("\n\n"); let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); let dst = project_root().join("docs/user/generated_assists.adoc"); - codegen::update(&dst, &contents, mode) + codegen::update(&dst, &contents, Mode::Overwrite) } #[derive(Debug)] diff --git a/xtask/src/codegen/gen_diagnostic_docs.rs b/xtask/src/codegen/gen_diagnostic_docs.rs index a2561817b..2504e09ef 100644 --- a/xtask/src/codegen/gen_diagnostic_docs.rs +++ b/xtask/src/codegen/gen_diagnostic_docs.rs @@ -7,13 +7,13 @@ use crate::{ project_root, rust_files, Result, }; -pub(crate) fn generate_diagnostic_docs(mode: Mode) -> Result<()> { +pub(crate) fn generate_diagnostic_docs() -> Result<()> { let diagnostics = Diagnostic::collect()?; let contents = diagnostics.into_iter().map(|it| it.to_string()).collect::>().join("\n\n"); let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); let dst = project_root().join("docs/user/generated_diagnostic.adoc"); - codegen::update(&dst, &contents, mode)?; + codegen::update(&dst, &contents, Mode::Overwrite)?; Ok(()) } diff --git a/xtask/src/codegen/gen_feature_docs.rs b/xtask/src/codegen/gen_feature_docs.rs index cad7ff477..8509fec26 100644 --- a/xtask/src/codegen/gen_feature_docs.rs +++ b/xtask/src/codegen/gen_feature_docs.rs @@ -7,12 +7,12 @@ use crate::{ project_root, rust_files, Result, }; -pub(crate) fn generate_feature_docs(mode: Mode) -> Result<()> { +pub(crate) fn generate_feature_docs() -> Result<()> { let features = Feature::collect()?; let contents = features.into_iter().map(|it| it.to_string()).collect::>().join("\n\n"); let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); let dst = project_root().join("docs/user/generated_features.adoc"); - codegen::update(&dst, &contents, mode)?; + codegen::update(&dst, &contents, Mode::Overwrite)?; Ok(()) } diff --git a/xtask/src/tidy.rs b/xtask/src/tidy.rs index 03b4c0092..096bc3af1 100644 --- a/xtask/src/tidy.rs +++ b/xtask/src/tidy.rs @@ -31,7 +31,7 @@ fn generate_assists_tests() { #[test] #[ignore] fn generate_lint_completions() { - codegen::generate_lint_completions(Mode::Overwrite).unwrap() + codegen::generate_lint_completions(Mode::Ensure).unwrap() } #[test] -- cgit v1.2.3 From e89c0e39613e381da45b6a774c6666dcc3e632a2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Mar 2021 21:39:09 +0300 Subject: Remove now dead code --- xtask/src/codegen.rs | 60 ++++++++++++++----------------- xtask/src/codegen/gen_assists_docs.rs | 18 ++++++---- xtask/src/codegen/gen_diagnostic_docs.rs | 6 ++-- xtask/src/codegen/gen_feature_docs.rs | 6 ++-- xtask/src/codegen/gen_lint_completions.rs | 10 ++---- xtask/src/codegen/gen_parser_tests.rs | 12 +++---- xtask/src/codegen/gen_syntax.rs | 10 +++--- xtask/src/main.rs | 19 +--------- xtask/src/tidy.rs | 25 +++++++------ 9 files changed, 76 insertions(+), 90 deletions(-) diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index 2248a079f..e43d4fa73 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs @@ -16,7 +16,7 @@ use std::{ fmt, mem, path::{Path, PathBuf}, }; -use xshell::{cmd, pushenv, read_file, write_file}; +use xshell::{cmd, pushenv}; use crate::{ensure_rustfmt, project_root, Result}; @@ -35,44 +35,38 @@ pub(crate) fn docs() -> Result<()> { #[allow(unused)] fn used() { - generate_parser_tests(Mode::Overwrite); - generate_assists_tests(Mode::Overwrite); - generate_syntax(Mode::Overwrite); - generate_lint_completions(Mode::Overwrite); + generate_parser_tests(); + generate_assists_tests(); + generate_syntax(); + generate_lint_completions(); } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub(crate) enum Mode { - Overwrite, - Ensure, -} - -/// A helper to update file on disk if it has changed. -/// With verify = false, -fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { - match read_file(path) { - Ok(old_contents) if normalize(&old_contents) == normalize(contents) => { - return Ok(()); +/// Checks that the `file` has the specified `contents`. If that is not the +/// case, updates the file and then fails the test. +pub(crate) fn ensure_file_contents(file: &Path, contents: &str) -> Result<()> { + match std::fs::read_to_string(file) { + Ok(old_contents) if normalize_newlines(&old_contents) == normalize_newlines(contents) => { + return Ok(()) } _ => (), } - let return_error = match mode { - Mode::Overwrite => false, - Mode::Ensure => true, - }; - eprintln!("updating {}", path.display()); - write_file(path, contents)?; - - return if return_error { - let path = path.strip_prefix(&project_root()).unwrap_or(path); - anyhow::bail!("`{}` was not up-to-date, updating", path.display()); - } else { - Ok(()) - }; - - fn normalize(s: &str) -> String { - s.replace("\r\n", "\n") + let display_path = file.strip_prefix(&project_root()).unwrap_or(file); + eprintln!( + "\n\x1b[31;1merror\x1b[0m: {} was not up-to-date, updating\n", + display_path.display() + ); + if std::env::var("CI").is_ok() { + eprintln!("\n NOTE: run `cargo test` locally and commit the updated files\n"); + } + if let Some(parent) = file.parent() { + let _ = std::fs::create_dir_all(parent); } + std::fs::write(file, contents).unwrap(); + anyhow::bail!("some file were not up to date") +} + +fn normalize_newlines(s: &str) -> String { + s.replace("\r\n", "\n") } const PREAMBLE: &str = "Generated file, do not edit by hand, see `xtask/src/codegen`"; diff --git a/xtask/src/codegen/gen_assists_docs.rs b/xtask/src/codegen/gen_assists_docs.rs index a5af1331d..158680993 100644 --- a/xtask/src/codegen/gen_assists_docs.rs +++ b/xtask/src/codegen/gen_assists_docs.rs @@ -2,14 +2,16 @@ use std::{fmt, path::Path}; +use xshell::write_file; + use crate::{ - codegen::{self, extract_comment_blocks_with_empty_lines, reformat, Location, Mode, PREAMBLE}, + codegen::{self, extract_comment_blocks_with_empty_lines, reformat, Location, PREAMBLE}, project_root, rust_files_in, Result, }; -pub(crate) fn generate_assists_tests(mode: Mode) -> Result<()> { +pub(crate) fn generate_assists_tests() -> Result<()> { let assists = Assist::collect()?; - generate_tests(&assists, mode) + generate_tests(&assists) } pub(crate) fn generate_assists_docs() -> Result<()> { @@ -17,7 +19,8 @@ pub(crate) fn generate_assists_docs() -> Result<()> { let contents = assists.into_iter().map(|it| it.to_string()).collect::>().join("\n\n"); let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); let dst = project_root().join("docs/user/generated_assists.adoc"); - codegen::update(&dst, &contents, Mode::Overwrite) + write_file(dst, &contents)?; + Ok(()) } #[derive(Debug)] @@ -111,7 +114,7 @@ impl fmt::Display for Assist { } } -fn generate_tests(assists: &[Assist], mode: Mode) -> Result<()> { +fn generate_tests(assists: &[Assist]) -> Result<()> { let mut buf = String::from("use super::check_doc_test;\n"); for assist in assists.iter() { @@ -135,7 +138,10 @@ r#####" buf.push_str(&test) } let buf = reformat(&buf)?; - codegen::update(&project_root().join("crates/ide_assists/src/tests/generated.rs"), &buf, mode) + codegen::ensure_file_contents( + &project_root().join("crates/ide_assists/src/tests/generated.rs"), + &buf, + ) } fn hide_hash_comments(text: &str) -> String { diff --git a/xtask/src/codegen/gen_diagnostic_docs.rs b/xtask/src/codegen/gen_diagnostic_docs.rs index 2504e09ef..9cf4d0a88 100644 --- a/xtask/src/codegen/gen_diagnostic_docs.rs +++ b/xtask/src/codegen/gen_diagnostic_docs.rs @@ -2,8 +2,10 @@ use std::{fmt, path::PathBuf}; +use xshell::write_file; + use crate::{ - codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode, PREAMBLE}, + codegen::{extract_comment_blocks_with_empty_lines, Location, PREAMBLE}, project_root, rust_files, Result, }; @@ -13,7 +15,7 @@ pub(crate) fn generate_diagnostic_docs() -> Result<()> { diagnostics.into_iter().map(|it| it.to_string()).collect::>().join("\n\n"); let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); let dst = project_root().join("docs/user/generated_diagnostic.adoc"); - codegen::update(&dst, &contents, Mode::Overwrite)?; + write_file(&dst, &contents)?; Ok(()) } diff --git a/xtask/src/codegen/gen_feature_docs.rs b/xtask/src/codegen/gen_feature_docs.rs index 8509fec26..c373d7d70 100644 --- a/xtask/src/codegen/gen_feature_docs.rs +++ b/xtask/src/codegen/gen_feature_docs.rs @@ -2,8 +2,10 @@ use std::{fmt, path::PathBuf}; +use xshell::write_file; + use crate::{ - codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode, PREAMBLE}, + codegen::{extract_comment_blocks_with_empty_lines, Location, PREAMBLE}, project_root, rust_files, Result, }; @@ -12,7 +14,7 @@ pub(crate) fn generate_feature_docs() -> Result<()> { let contents = features.into_iter().map(|it| it.to_string()).collect::>().join("\n\n"); let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); let dst = project_root().join("docs/user/generated_features.adoc"); - codegen::update(&dst, &contents, Mode::Overwrite)?; + write_file(&dst, &contents)?; Ok(()) } diff --git a/xtask/src/codegen/gen_lint_completions.rs b/xtask/src/codegen/gen_lint_completions.rs index b1c057037..3a2937670 100644 --- a/xtask/src/codegen/gen_lint_completions.rs +++ b/xtask/src/codegen/gen_lint_completions.rs @@ -5,12 +5,9 @@ use std::path::{Path, PathBuf}; use walkdir::WalkDir; use xshell::{cmd, read_file}; -use crate::{ - codegen::{project_root, reformat, update, Mode, Result}, - run_rustfmt, -}; +use crate::codegen::{ensure_file_contents, project_root, reformat, Result}; -pub(crate) fn generate_lint_completions(mode: Mode) -> Result<()> { +pub(crate) fn generate_lint_completions() -> Result<()> { if !Path::new("./target/rust").exists() { cmd!("git clone --depth=1 https://github.com/rust-lang/rust ./target/rust").run()?; } @@ -25,8 +22,7 @@ pub(crate) fn generate_lint_completions(mode: Mode) -> Result<()> { let destination = project_root().join("crates/ide_completion/src/generated_lint_completions.rs"); - update(destination.as_path(), &contents, mode)?; - run_rustfmt(mode)?; + ensure_file_contents(destination.as_path(), &contents)?; Ok(()) } diff --git a/xtask/src/codegen/gen_parser_tests.rs b/xtask/src/codegen/gen_parser_tests.rs index cb8939063..096590653 100644 --- a/xtask/src/codegen/gen_parser_tests.rs +++ b/xtask/src/codegen/gen_parser_tests.rs @@ -8,13 +8,13 @@ use std::{ }; use crate::{ - codegen::{extract_comment_blocks, update, Mode}, + codegen::{ensure_file_contents, extract_comment_blocks}, project_root, Result, }; -pub(crate) fn generate_parser_tests(mode: Mode) -> Result<()> { +pub(crate) fn generate_parser_tests() -> Result<()> { let tests = tests_from_dir(&project_root().join(Path::new("crates/parser/src/grammar")))?; - fn install_tests(tests: &HashMap, into: &str, mode: Mode) -> Result<()> { + fn install_tests(tests: &HashMap, into: &str) -> Result<()> { let tests_dir = project_root().join(into); if !tests_dir.is_dir() { fs::create_dir_all(&tests_dir)?; @@ -35,12 +35,12 @@ pub(crate) fn generate_parser_tests(mode: Mode) -> Result<()> { tests_dir.join(file_name) } }; - update(&path, &test.text, mode)?; + ensure_file_contents(&path, &test.text)?; } Ok(()) } - install_tests(&tests.ok, "crates/syntax/test_data/parser/inline/ok", mode)?; - install_tests(&tests.err, "crates/syntax/test_data/parser/inline/err", mode) + install_tests(&tests.ok, "crates/syntax/test_data/parser/inline/ok")?; + install_tests(&tests.err, "crates/syntax/test_data/parser/inline/err") } #[derive(Debug)] diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs index 191bc0e9d..80f26e8f5 100644 --- a/xtask/src/codegen/gen_syntax.rs +++ b/xtask/src/codegen/gen_syntax.rs @@ -14,25 +14,25 @@ use ungrammar::{rust_grammar, Grammar, Rule}; use crate::{ ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC}, - codegen::{reformat, update, Mode}, + codegen::{ensure_file_contents, reformat}, project_root, Result, }; -pub(crate) fn generate_syntax(mode: Mode) -> Result<()> { +pub(crate) fn generate_syntax() -> Result<()> { let grammar = rust_grammar(); let ast = lower(&grammar); let syntax_kinds_file = project_root().join("crates/parser/src/syntax_kind/generated.rs"); let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; - update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; + ensure_file_contents(syntax_kinds_file.as_path(), &syntax_kinds)?; let ast_tokens_file = project_root().join("crates/syntax/src/ast/generated/tokens.rs"); let contents = generate_tokens(&ast)?; - update(ast_tokens_file.as_path(), &contents, mode)?; + ensure_file_contents(ast_tokens_file.as_path(), &contents)?; let ast_nodes_file = project_root().join("crates/syntax/src/ast/generated/nodes.rs"); let contents = generate_nodes(KINDS_SRC, &ast)?; - update(ast_nodes_file.as_path(), &contents, mode)?; + ensure_file_contents(ast_nodes_file.as_path(), &contents)?; Ok(()) } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index c2dda928e..35cc7c108 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -28,7 +28,7 @@ use std::{ use walkdir::{DirEntry, WalkDir}; use xshell::{cmd, cp, pushd, pushenv}; -use crate::{codegen::Mode, dist::DistCmd}; +use crate::dist::DistCmd; fn main() -> Result<()> { let _d = pushd(project_root())?; @@ -84,23 +84,6 @@ fn rust_files_in(path: &Path) -> impl Iterator { files_in(path, "rs") } -fn run_rustfmt(mode: Mode) -> Result<()> { - let _dir = pushd(project_root())?; - let _e = pushenv("RUSTUP_TOOLCHAIN", "stable"); - ensure_rustfmt()?; - match mode { - Mode::Overwrite => cmd!("cargo fmt").run()?, - Mode::Ensure => { - let res = cmd!("cargo fmt -- --check").run(); - if !res.is_ok() { - let _ = cmd!("cargo fmt").run(); - } - res?; - } - }; - Ok(()) -} - fn ensure_rustfmt() -> Result<()> { let out = cmd!("rustfmt --version").read()?; if !out.contains("stable") { diff --git a/xtask/src/tidy.rs b/xtask/src/tidy.rs index 096bc3af1..1352d1218 100644 --- a/xtask/src/tidy.rs +++ b/xtask/src/tidy.rs @@ -3,27 +3,23 @@ use std::{ path::{Path, PathBuf}, }; -use xshell::{cmd, read_file}; +use xshell::{cmd, pushd, pushenv, read_file}; -use crate::{ - cargo_files, - codegen::{self, Mode}, - project_root, run_rustfmt, rust_files, -}; +use crate::{cargo_files, codegen, project_root, rust_files}; #[test] fn generate_grammar() { - codegen::generate_syntax(Mode::Ensure).unwrap() + codegen::generate_syntax().unwrap() } #[test] fn generate_parser_tests() { - codegen::generate_parser_tests(Mode::Ensure).unwrap() + codegen::generate_parser_tests().unwrap() } #[test] fn generate_assists_tests() { - codegen::generate_assists_tests(Mode::Ensure).unwrap(); + codegen::generate_assists_tests().unwrap(); } /// This clones rustc repo, and so is not worth to keep up-to-date. We update @@ -31,12 +27,19 @@ fn generate_assists_tests() { #[test] #[ignore] fn generate_lint_completions() { - codegen::generate_lint_completions(Mode::Ensure).unwrap() + codegen::generate_lint_completions().unwrap() } #[test] fn check_code_formatting() { - run_rustfmt(Mode::Ensure).unwrap() + let _dir = pushd(project_root()).unwrap(); + let _e = pushenv("RUSTUP_TOOLCHAIN", "stable"); + crate::ensure_rustfmt().unwrap(); + let res = cmd!("cargo fmt -- --check").run(); + if !res.is_ok() { + let _ = cmd!("cargo fmt").run(); + } + res.unwrap() } #[test] -- cgit v1.2.3 From c0943f84fdb67025662dbcfc011e415870ee80a6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Mar 2021 21:41:45 +0300 Subject: Cleanup the error message --- crates/test_utils/src/lib.rs | 2 +- xtask/src/codegen.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index dd582c77c..6041ab5e4 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs @@ -377,7 +377,7 @@ pub fn try_ensure_file_contents(file: &Path, contents: &str) -> Result<(), ()> { display_path.display() ); if is_ci() { - eprintln!("\n NOTE: run `cargo test` locally and commit the updated files\n"); + eprintln!(" NOTE: run `cargo test` locally and commit the updated files\n"); } if let Some(parent) = file.parent() { let _ = std::fs::create_dir_all(parent); diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index e43d4fa73..2cf3c6fdc 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs @@ -56,7 +56,7 @@ pub(crate) fn ensure_file_contents(file: &Path, contents: &str) -> Result<()> { display_path.display() ); if std::env::var("CI").is_ok() { - eprintln!("\n NOTE: run `cargo test` locally and commit the updated files\n"); + eprintln!(" NOTE: run `cargo test` locally and commit the updated files\n"); } if let Some(parent) = file.parent() { let _ = std::fs::create_dir_all(parent); -- cgit v1.2.3 From d2bb2268d3a9cc0e2a6970c85c45724af5eb255c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Mar 2021 21:49:25 +0300 Subject: Minor --- xtask/src/codegen/gen_lint_completions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtask/src/codegen/gen_lint_completions.rs b/xtask/src/codegen/gen_lint_completions.rs index 3a2937670..24dbc6a39 100644 --- a/xtask/src/codegen/gen_lint_completions.rs +++ b/xtask/src/codegen/gen_lint_completions.rs @@ -8,7 +8,7 @@ use xshell::{cmd, read_file}; use crate::codegen::{ensure_file_contents, project_root, reformat, Result}; pub(crate) fn generate_lint_completions() -> Result<()> { - if !Path::new("./target/rust").exists() { + if !project_root().join("./target/rust").exists() { cmd!("git clone --depth=1 https://github.com/rust-lang/rust ./target/rust").run()?; } -- cgit v1.2.3