aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/codegen.rs60
-rw-r--r--xtask/src/codegen/gen_assists_docs.rs18
-rw-r--r--xtask/src/codegen/gen_diagnostic_docs.rs6
-rw-r--r--xtask/src/codegen/gen_feature_docs.rs6
-rw-r--r--xtask/src/codegen/gen_lint_completions.rs10
-rw-r--r--xtask/src/codegen/gen_parser_tests.rs12
-rw-r--r--xtask/src/codegen/gen_syntax.rs10
-rw-r--r--xtask/src/main.rs19
-rw-r--r--xtask/src/tidy.rs25
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::{
16 fmt, mem, 16 fmt, mem,
17 path::{Path, PathBuf}, 17 path::{Path, PathBuf},
18}; 18};
19use xshell::{cmd, pushenv, read_file, write_file}; 19use xshell::{cmd, pushenv};
20 20
21use crate::{ensure_rustfmt, project_root, Result}; 21use crate::{ensure_rustfmt, project_root, Result};
22 22
@@ -35,44 +35,38 @@ pub(crate) fn docs() -> Result<()> {
35 35
36#[allow(unused)] 36#[allow(unused)]
37fn used() { 37fn used() {
38 generate_parser_tests(Mode::Overwrite); 38 generate_parser_tests();
39 generate_assists_tests(Mode::Overwrite); 39 generate_assists_tests();
40 generate_syntax(Mode::Overwrite); 40 generate_syntax();
41 generate_lint_completions(Mode::Overwrite); 41 generate_lint_completions();
42} 42}
43 43
44#[derive(Debug, PartialEq, Eq, Clone, Copy)] 44/// Checks that the `file` has the specified `contents`. If that is not the
45pub(crate) enum Mode { 45/// case, updates the file and then fails the test.
46 Overwrite, 46pub(crate) fn ensure_file_contents(file: &Path, contents: &str) -> Result<()> {
47 Ensure, 47 match std::fs::read_to_string(file) {
48} 48 Ok(old_contents) if normalize_newlines(&old_contents) == normalize_newlines(contents) => {
49 49 return Ok(())
50/// A helper to update file on disk if it has changed.
51/// With verify = false,
52fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> {
53 match read_file(path) {
54 Ok(old_contents) if normalize(&old_contents) == normalize(contents) => {
55 return Ok(());
56 } 50 }
57 _ => (), 51 _ => (),
58 } 52 }
59 let return_error = match mode { 53 let display_path = file.strip_prefix(&project_root()).unwrap_or(file);
60 Mode::Overwrite => false, 54 eprintln!(
61 Mode::Ensure => true, 55 "\n\x1b[31;1merror\x1b[0m: {} was not up-to-date, updating\n",
62 }; 56 display_path.display()
63 eprintln!("updating {}", path.display()); 57 );
64 write_file(path, contents)?; 58 if std::env::var("CI").is_ok() {
65 59 eprintln!("\n NOTE: run `cargo test` locally and commit the updated files\n");
66 return if return_error { 60 }
67 let path = path.strip_prefix(&project_root()).unwrap_or(path); 61 if let Some(parent) = file.parent() {
68 anyhow::bail!("`{}` was not up-to-date, updating", path.display()); 62 let _ = std::fs::create_dir_all(parent);
69 } else {
70 Ok(())
71 };
72
73 fn normalize(s: &str) -> String {
74 s.replace("\r\n", "\n")
75 } 63 }
64 std::fs::write(file, contents).unwrap();
65 anyhow::bail!("some file were not up to date")
66}
67
68fn normalize_newlines(s: &str) -> String {
69 s.replace("\r\n", "\n")
76} 70}
77 71
78const PREAMBLE: &str = "Generated file, do not edit by hand, see `xtask/src/codegen`"; 72const 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 @@
2 2
3use std::{fmt, path::Path}; 3use std::{fmt, path::Path};
4 4
5use xshell::write_file;
6
5use crate::{ 7use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, reformat, Location, Mode, PREAMBLE}, 8 codegen::{self, extract_comment_blocks_with_empty_lines, reformat, Location, PREAMBLE},
7 project_root, rust_files_in, Result, 9 project_root, rust_files_in, Result,
8}; 10};
9 11
10pub(crate) fn generate_assists_tests(mode: Mode) -> Result<()> { 12pub(crate) fn generate_assists_tests() -> Result<()> {
11 let assists = Assist::collect()?; 13 let assists = Assist::collect()?;
12 generate_tests(&assists, mode) 14 generate_tests(&assists)
13} 15}
14 16
15pub(crate) fn generate_assists_docs() -> Result<()> { 17pub(crate) fn generate_assists_docs() -> Result<()> {
@@ -17,7 +19,8 @@ pub(crate) fn generate_assists_docs() -> Result<()> {
17 let contents = assists.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); 19 let contents = assists.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
18 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); 20 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim());
19 let dst = project_root().join("docs/user/generated_assists.adoc"); 21 let dst = project_root().join("docs/user/generated_assists.adoc");
20 codegen::update(&dst, &contents, Mode::Overwrite) 22 write_file(dst, &contents)?;
23 Ok(())
21} 24}
22 25
23#[derive(Debug)] 26#[derive(Debug)]
@@ -111,7 +114,7 @@ impl fmt::Display for Assist {
111 } 114 }
112} 115}
113 116
114fn generate_tests(assists: &[Assist], mode: Mode) -> Result<()> { 117fn generate_tests(assists: &[Assist]) -> Result<()> {
115 let mut buf = String::from("use super::check_doc_test;\n"); 118 let mut buf = String::from("use super::check_doc_test;\n");
116 119
117 for assist in assists.iter() { 120 for assist in assists.iter() {
@@ -135,7 +138,10 @@ r#####"
135 buf.push_str(&test) 138 buf.push_str(&test)
136 } 139 }
137 let buf = reformat(&buf)?; 140 let buf = reformat(&buf)?;
138 codegen::update(&project_root().join("crates/ide_assists/src/tests/generated.rs"), &buf, mode) 141 codegen::ensure_file_contents(
142 &project_root().join("crates/ide_assists/src/tests/generated.rs"),
143 &buf,
144 )
139} 145}
140 146
141fn hide_hash_comments(text: &str) -> String { 147fn 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 @@
2 2
3use std::{fmt, path::PathBuf}; 3use std::{fmt, path::PathBuf};
4 4
5use xshell::write_file;
6
5use crate::{ 7use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode, PREAMBLE}, 8 codegen::{extract_comment_blocks_with_empty_lines, Location, PREAMBLE},
7 project_root, rust_files, Result, 9 project_root, rust_files, Result,
8}; 10};
9 11
@@ -13,7 +15,7 @@ pub(crate) fn generate_diagnostic_docs() -> Result<()> {
13 diagnostics.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); 15 diagnostics.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
14 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); 16 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim());
15 let dst = project_root().join("docs/user/generated_diagnostic.adoc"); 17 let dst = project_root().join("docs/user/generated_diagnostic.adoc");
16 codegen::update(&dst, &contents, Mode::Overwrite)?; 18 write_file(&dst, &contents)?;
17 Ok(()) 19 Ok(())
18} 20}
19 21
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 @@
2 2
3use std::{fmt, path::PathBuf}; 3use std::{fmt, path::PathBuf};
4 4
5use xshell::write_file;
6
5use crate::{ 7use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode, PREAMBLE}, 8 codegen::{extract_comment_blocks_with_empty_lines, Location, PREAMBLE},
7 project_root, rust_files, Result, 9 project_root, rust_files, Result,
8}; 10};
9 11
@@ -12,7 +14,7 @@ pub(crate) fn generate_feature_docs() -> Result<()> {
12 let contents = features.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); 14 let contents = features.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
13 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); 15 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim());
14 let dst = project_root().join("docs/user/generated_features.adoc"); 16 let dst = project_root().join("docs/user/generated_features.adoc");
15 codegen::update(&dst, &contents, Mode::Overwrite)?; 17 write_file(&dst, &contents)?;
16 Ok(()) 18 Ok(())
17} 19}
18 20
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};
5use walkdir::WalkDir; 5use walkdir::WalkDir;
6use xshell::{cmd, read_file}; 6use xshell::{cmd, read_file};
7 7
8use crate::{ 8use crate::codegen::{ensure_file_contents, project_root, reformat, Result};
9 codegen::{project_root, reformat, update, Mode, Result},
10 run_rustfmt,
11};
12 9
13pub(crate) fn generate_lint_completions(mode: Mode) -> Result<()> { 10pub(crate) fn generate_lint_completions() -> Result<()> {
14 if !Path::new("./target/rust").exists() { 11 if !Path::new("./target/rust").exists() {
15 cmd!("git clone --depth=1 https://github.com/rust-lang/rust ./target/rust").run()?; 12 cmd!("git clone --depth=1 https://github.com/rust-lang/rust ./target/rust").run()?;
16 } 13 }
@@ -25,8 +22,7 @@ pub(crate) fn generate_lint_completions(mode: Mode) -> Result<()> {
25 22
26 let destination = 23 let destination =
27 project_root().join("crates/ide_completion/src/generated_lint_completions.rs"); 24 project_root().join("crates/ide_completion/src/generated_lint_completions.rs");
28 update(destination.as_path(), &contents, mode)?; 25 ensure_file_contents(destination.as_path(), &contents)?;
29 run_rustfmt(mode)?;
30 26
31 Ok(()) 27 Ok(())
32} 28}
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::{
8}; 8};
9 9
10use crate::{ 10use crate::{
11 codegen::{extract_comment_blocks, update, Mode}, 11 codegen::{ensure_file_contents, extract_comment_blocks},
12 project_root, Result, 12 project_root, Result,
13}; 13};
14 14
15pub(crate) fn generate_parser_tests(mode: Mode) -> Result<()> { 15pub(crate) fn generate_parser_tests() -> Result<()> {
16 let tests = tests_from_dir(&project_root().join(Path::new("crates/parser/src/grammar")))?; 16 let tests = tests_from_dir(&project_root().join(Path::new("crates/parser/src/grammar")))?;
17 fn install_tests(tests: &HashMap<String, Test>, into: &str, mode: Mode) -> Result<()> { 17 fn install_tests(tests: &HashMap<String, Test>, into: &str) -> Result<()> {
18 let tests_dir = project_root().join(into); 18 let tests_dir = project_root().join(into);
19 if !tests_dir.is_dir() { 19 if !tests_dir.is_dir() {
20 fs::create_dir_all(&tests_dir)?; 20 fs::create_dir_all(&tests_dir)?;
@@ -35,12 +35,12 @@ pub(crate) fn generate_parser_tests(mode: Mode) -> Result<()> {
35 tests_dir.join(file_name) 35 tests_dir.join(file_name)
36 } 36 }
37 }; 37 };
38 update(&path, &test.text, mode)?; 38 ensure_file_contents(&path, &test.text)?;
39 } 39 }
40 Ok(()) 40 Ok(())
41 } 41 }
42 install_tests(&tests.ok, "crates/syntax/test_data/parser/inline/ok", mode)?; 42 install_tests(&tests.ok, "crates/syntax/test_data/parser/inline/ok")?;
43 install_tests(&tests.err, "crates/syntax/test_data/parser/inline/err", mode) 43 install_tests(&tests.err, "crates/syntax/test_data/parser/inline/err")
44} 44}
45 45
46#[derive(Debug)] 46#[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};
14 14
15use crate::{ 15use crate::{
16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC}, 16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC},
17 codegen::{reformat, update, Mode}, 17 codegen::{ensure_file_contents, reformat},
18 project_root, Result, 18 project_root, Result,
19}; 19};
20 20
21pub(crate) fn generate_syntax(mode: Mode) -> Result<()> { 21pub(crate) fn generate_syntax() -> Result<()> {
22 let grammar = rust_grammar(); 22 let grammar = rust_grammar();
23 let ast = lower(&grammar); 23 let ast = lower(&grammar);
24 24
25 let syntax_kinds_file = project_root().join("crates/parser/src/syntax_kind/generated.rs"); 25 let syntax_kinds_file = project_root().join("crates/parser/src/syntax_kind/generated.rs");
26 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; 26 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?;
27 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; 27 ensure_file_contents(syntax_kinds_file.as_path(), &syntax_kinds)?;
28 28
29 let ast_tokens_file = project_root().join("crates/syntax/src/ast/generated/tokens.rs"); 29 let ast_tokens_file = project_root().join("crates/syntax/src/ast/generated/tokens.rs");
30 let contents = generate_tokens(&ast)?; 30 let contents = generate_tokens(&ast)?;
31 update(ast_tokens_file.as_path(), &contents, mode)?; 31 ensure_file_contents(ast_tokens_file.as_path(), &contents)?;
32 32
33 let ast_nodes_file = project_root().join("crates/syntax/src/ast/generated/nodes.rs"); 33 let ast_nodes_file = project_root().join("crates/syntax/src/ast/generated/nodes.rs");
34 let contents = generate_nodes(KINDS_SRC, &ast)?; 34 let contents = generate_nodes(KINDS_SRC, &ast)?;
35 update(ast_nodes_file.as_path(), &contents, mode)?; 35 ensure_file_contents(ast_nodes_file.as_path(), &contents)?;
36 36
37 Ok(()) 37 Ok(())
38} 38}
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::{
28use walkdir::{DirEntry, WalkDir}; 28use walkdir::{DirEntry, WalkDir};
29use xshell::{cmd, cp, pushd, pushenv}; 29use xshell::{cmd, cp, pushd, pushenv};
30 30
31use crate::{codegen::Mode, dist::DistCmd}; 31use crate::dist::DistCmd;
32 32
33fn main() -> Result<()> { 33fn main() -> Result<()> {
34 let _d = pushd(project_root())?; 34 let _d = pushd(project_root())?;
@@ -84,23 +84,6 @@ fn rust_files_in(path: &Path) -> impl Iterator<Item = PathBuf> {
84 files_in(path, "rs") 84 files_in(path, "rs")
85} 85}
86 86
87fn run_rustfmt(mode: Mode) -> Result<()> {
88 let _dir = pushd(project_root())?;
89 let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
90 ensure_rustfmt()?;
91 match mode {
92 Mode::Overwrite => cmd!("cargo fmt").run()?,
93 Mode::Ensure => {
94 let res = cmd!("cargo fmt -- --check").run();
95 if !res.is_ok() {
96 let _ = cmd!("cargo fmt").run();
97 }
98 res?;
99 }
100 };
101 Ok(())
102}
103
104fn ensure_rustfmt() -> Result<()> { 87fn ensure_rustfmt() -> Result<()> {
105 let out = cmd!("rustfmt --version").read()?; 88 let out = cmd!("rustfmt --version").read()?;
106 if !out.contains("stable") { 89 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::{
3 path::{Path, PathBuf}, 3 path::{Path, PathBuf},
4}; 4};
5 5
6use xshell::{cmd, read_file}; 6use xshell::{cmd, pushd, pushenv, read_file};
7 7
8use crate::{ 8use crate::{cargo_files, codegen, project_root, rust_files};
9 cargo_files,
10 codegen::{self, Mode},
11 project_root, run_rustfmt, rust_files,
12};
13 9
14#[test] 10#[test]
15fn generate_grammar() { 11fn generate_grammar() {
16 codegen::generate_syntax(Mode::Ensure).unwrap() 12 codegen::generate_syntax().unwrap()
17} 13}
18 14
19#[test] 15#[test]
20fn generate_parser_tests() { 16fn generate_parser_tests() {
21 codegen::generate_parser_tests(Mode::Ensure).unwrap() 17 codegen::generate_parser_tests().unwrap()
22} 18}
23 19
24#[test] 20#[test]
25fn generate_assists_tests() { 21fn generate_assists_tests() {
26 codegen::generate_assists_tests(Mode::Ensure).unwrap(); 22 codegen::generate_assists_tests().unwrap();
27} 23}
28 24
29/// This clones rustc repo, and so is not worth to keep up-to-date. We update 25/// This clones rustc repo, and so is not worth to keep up-to-date. We update
@@ -31,12 +27,19 @@ fn generate_assists_tests() {
31#[test] 27#[test]
32#[ignore] 28#[ignore]
33fn generate_lint_completions() { 29fn generate_lint_completions() {
34 codegen::generate_lint_completions(Mode::Ensure).unwrap() 30 codegen::generate_lint_completions().unwrap()
35} 31}
36 32
37#[test] 33#[test]
38fn check_code_formatting() { 34fn check_code_formatting() {
39 run_rustfmt(Mode::Ensure).unwrap() 35 let _dir = pushd(project_root()).unwrap();
36 let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
37 crate::ensure_rustfmt().unwrap();
38 let res = cmd!("cargo fmt -- --check").run();
39 if !res.is_ok() {
40 let _ = cmd!("cargo fmt").run();
41 }
42 res.unwrap()
40} 43}
41 44
42#[test] 45#[test]