Make code generation just work

Contributors don't need to learn about `cargo xtask codegen` if `cargo
test` just does the right thing.
This commit is contained in:
Aleksey Kladov 2021-03-08 21:13:15 +03:00
parent abb6b8f14c
commit 1eb61203b7
8 changed files with 42 additions and 50 deletions

View file

@ -864,7 +864,7 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn ensure_schema_in_package_json() { fn generate_package_json_config() {
let s = Config::json_schema(); let s = Config::json_schema();
let schema = format!("{:#}", s); let schema = format!("{:#}", s);
let mut schema = schema let mut schema = schema
@ -895,7 +895,7 @@ mod tests {
} }
#[test] #[test]
fn schema_in_sync_with_docs() { fn generate_config_documentation() {
let docs_path = project_root().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 current = fs::read_to_string(&docs_path).unwrap();
let expected = ConfigData::manual(); let expected = ConfigData::manual();

View file

@ -18,7 +18,7 @@ use std::{
}; };
use profile::StopWatch; use profile::StopWatch;
use stdx::lines_with_ends; use stdx::{is_ci, lines_with_ends};
use text_size::{TextRange, TextSize}; use text_size::{TextRange, TextSize};
pub use dissimilar::diff as __diff; 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", "\n\x1b[31;1merror\x1b[0m: {} was not up-to-date, updating\n",
display_path.display() 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() { if let Some(parent) = file.parent() {
let _ = std::fs::create_dir_all(parent); let _ = std::fs::create_dir_all(parent);
} }

View file

@ -308,9 +308,8 @@ This sections talks about the things which are everywhere and nowhere in particu
### Code generation ### Code generation
Some of the components of this repository are generated through automatic processes. 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. Generated code is generally committed to the git repository.
There are tests to check that the generated code is fresh.
In particular, we generate: In particular, we generate:

View file

@ -7,9 +7,9 @@
mod gen_syntax; mod gen_syntax;
mod gen_parser_tests; mod gen_parser_tests;
mod gen_lint_completions;
mod gen_assists_docs; mod gen_assists_docs;
mod gen_feature_docs; mod gen_feature_docs;
mod gen_lint_completions;
mod gen_diagnostic_docs; mod gen_diagnostic_docs;
use std::{ use std::{
@ -18,38 +18,35 @@ use std::{
}; };
use xshell::{cmd, pushenv, read_file, write_file}; 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::{ pub(crate) use self::{
gen_assists_docs::{generate_assists_docs, generate_assists_tests}, gen_assists_docs::generate_assists_tests, gen_lint_completions::generate_lint_completions,
gen_diagnostic_docs::generate_diagnostic_docs, gen_parser_tests::generate_parser_tests, gen_syntax::generate_syntax,
gen_feature_docs::generate_feature_docs,
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)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub(crate) enum Mode { pub(crate) enum Mode {
Overwrite, Overwrite,
Ensure, 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. /// A helper to update file on disk if it has changed.
/// With verify = false, /// With verify = false,
fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> {

View file

@ -27,10 +27,6 @@ xflags::xflags! {
optional --jemalloc optional --jemalloc
} }
cmd codegen {
optional --features
}
cmd lint {} cmd lint {}
cmd fuzz-tests {} cmd fuzz-tests {}
cmd pre-cache {} cmd pre-cache {}
@ -67,7 +63,6 @@ pub struct Xtask {
pub enum XtaskCmd { pub enum XtaskCmd {
Help(Help), Help(Help),
Install(Install), Install(Install),
Codegen(Codegen),
Lint(Lint), Lint(Lint),
FuzzTests(FuzzTests), FuzzTests(FuzzTests),
PreCache(PreCache), PreCache(PreCache),
@ -92,11 +87,6 @@ pub struct Install {
pub jemalloc: bool, pub jemalloc: bool,
} }
#[derive(Debug)]
pub struct Codegen {
pub features: bool,
}
#[derive(Debug)] #[derive(Debug)]
pub struct Lint; pub struct Lint;

View file

@ -40,7 +40,6 @@ fn main() -> Result<()> {
return Ok(()); return Ok(());
} }
flags::XtaskCmd::Install(cmd) => cmd.run(), flags::XtaskCmd::Install(cmd) => cmd.run(),
flags::XtaskCmd::Codegen(cmd) => cmd.run(),
flags::XtaskCmd::Lint(_) => run_clippy(), flags::XtaskCmd::Lint(_) => run_clippy(),
flags::XtaskCmd::FuzzTests(_) => run_fuzzer(), flags::XtaskCmd::FuzzTests(_) => run_fuzzer(),
flags::XtaskCmd::PreCache(cmd) => cmd.run(), flags::XtaskCmd::PreCache(cmd) => cmd.run(),

View file

@ -2,7 +2,7 @@ use std::fmt::Write;
use xshell::{cmd, cp, pushd, read_dir, write_file}; 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 { impl flags::Release {
pub(crate) fn run(self) -> Result<()> { pub(crate) fn run(self) -> Result<()> {
@ -12,8 +12,7 @@ impl flags::Release {
cmd!("git reset --hard tags/nightly").run()?; cmd!("git reset --hard tags/nightly").run()?;
cmd!("git push").run()?; cmd!("git push").run()?;
} }
codegen::generate_assists_docs(Mode::Overwrite)?; codegen::docs()?;
codegen::generate_feature_docs(Mode::Overwrite)?;
let website_root = project_root().join("../rust-analyzer.github.io"); let website_root = project_root().join("../rust-analyzer.github.io");
let changelog_dir = website_root.join("./thisweek/_posts"); let changelog_dir = website_root.join("./thisweek/_posts");

View file

@ -12,31 +12,36 @@ use crate::{
}; };
#[test] #[test]
fn generated_grammar_is_fresh() { fn generate_grammar() {
codegen::generate_syntax(Mode::Ensure).unwrap() codegen::generate_syntax(Mode::Ensure).unwrap()
} }
#[test] #[test]
fn generated_tests_are_fresh() { fn generate_parser_tests() {
codegen::generate_parser_tests(Mode::Ensure).unwrap() codegen::generate_parser_tests(Mode::Ensure).unwrap()
} }
#[test] #[test]
fn generated_assists_are_fresh() { fn generate_assists_tests() {
codegen::generate_assists_tests(Mode::Ensure).unwrap(); 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] #[test]
fn check_code_formatting() { fn check_code_formatting() {
run_rustfmt(Mode::Ensure).unwrap() run_rustfmt(Mode::Ensure).unwrap()
} }
#[test] #[test]
fn smoke_test_docs_generation() { fn smoke_test_generate_documentation() {
// We don't commit docs to the repo, so we can just overwrite in tests. codegen::docs().unwrap()
codegen::generate_assists_docs(Mode::Overwrite).unwrap();
codegen::generate_feature_docs(Mode::Overwrite).unwrap();
codegen::generate_diagnostic_docs(Mode::Overwrite).unwrap();
} }
#[test] #[test]