diff options
Diffstat (limited to 'xtask/src')
-rw-r--r-- | xtask/src/codegen.rs | 49 | ||||
-rw-r--r-- | xtask/src/codegen/gen_assists_docs.rs | 10 | ||||
-rw-r--r-- | xtask/src/codegen/gen_feature_docs.rs | 4 | ||||
-rw-r--r-- | xtask/src/codegen/gen_features.rs | 50 | ||||
-rw-r--r-- | xtask/src/codegen/gen_parser_tests.rs | 8 | ||||
-rw-r--r-- | xtask/src/codegen/gen_syntax.rs | 14 | ||||
-rw-r--r-- | xtask/src/lib.rs | 56 | ||||
-rw-r--r-- | xtask/src/main.rs | 14 | ||||
-rw-r--r-- | xtask/src/pre_cache.rs | 80 |
9 files changed, 196 insertions, 89 deletions
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index 78a84f68d..45b17bb48 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs | |||
@@ -9,38 +9,51 @@ mod gen_syntax; | |||
9 | mod gen_parser_tests; | 9 | mod gen_parser_tests; |
10 | mod gen_assists_docs; | 10 | mod gen_assists_docs; |
11 | mod gen_feature_docs; | 11 | mod gen_feature_docs; |
12 | mod gen_features; | ||
12 | 13 | ||
13 | use std::{ | 14 | use std::{ |
14 | fmt, mem, | 15 | fmt, mem, |
15 | path::{Path, PathBuf}, | 16 | path::{Path, PathBuf}, |
16 | }; | 17 | }; |
17 | 18 | ||
18 | use crate::{not_bash::fs2, project_root, Result}; | 19 | use crate::{ |
20 | ensure_rustfmt, | ||
21 | not_bash::{fs2, pushenv, run}, | ||
22 | project_root, Result, | ||
23 | }; | ||
19 | 24 | ||
20 | pub use self::{ | 25 | pub use self::{ |
21 | gen_assists_docs::{generate_assists_docs, generate_assists_tests}, | 26 | gen_assists_docs::{generate_assists_docs, generate_assists_tests}, |
22 | gen_feature_docs::generate_feature_docs, | 27 | gen_feature_docs::generate_feature_docs, |
28 | gen_features::generate_features, | ||
23 | gen_parser_tests::generate_parser_tests, | 29 | gen_parser_tests::generate_parser_tests, |
24 | gen_syntax::generate_syntax, | 30 | gen_syntax::generate_syntax, |
25 | }; | 31 | }; |
26 | 32 | ||
27 | const GRAMMAR_DIR: &str = "crates/parser/src/grammar"; | ||
28 | const OK_INLINE_TESTS_DIR: &str = "crates/syntax/test_data/parser/inline/ok"; | ||
29 | const ERR_INLINE_TESTS_DIR: &str = "crates/syntax/test_data/parser/inline/err"; | ||
30 | |||
31 | const SYNTAX_KINDS: &str = "crates/parser/src/syntax_kind/generated.rs"; | ||
32 | const AST_NODES: &str = "crates/syntax/src/ast/generated/nodes.rs"; | ||
33 | const AST_TOKENS: &str = "crates/syntax/src/ast/generated/tokens.rs"; | ||
34 | |||
35 | const ASSISTS_DIR: &str = "crates/assists/src/handlers"; | ||
36 | const ASSISTS_TESTS: &str = "crates/assists/src/tests/generated.rs"; | ||
37 | |||
38 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 33 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
39 | pub enum Mode { | 34 | pub enum Mode { |
40 | Overwrite, | 35 | Overwrite, |
41 | Verify, | 36 | Verify, |
42 | } | 37 | } |
43 | 38 | ||
39 | pub struct CodegenCmd { | ||
40 | pub features: bool, | ||
41 | } | ||
42 | |||
43 | impl CodegenCmd { | ||
44 | pub fn run(self) -> Result<()> { | ||
45 | if self.features { | ||
46 | generate_features(Mode::Overwrite)?; | ||
47 | } | ||
48 | generate_syntax(Mode::Overwrite)?; | ||
49 | generate_parser_tests(Mode::Overwrite)?; | ||
50 | generate_assists_tests(Mode::Overwrite)?; | ||
51 | generate_assists_docs(Mode::Overwrite)?; | ||
52 | generate_feature_docs(Mode::Overwrite)?; | ||
53 | Ok(()) | ||
54 | } | ||
55 | } | ||
56 | |||
44 | /// A helper to update file on disk if it has changed. | 57 | /// A helper to update file on disk if it has changed. |
45 | /// With verify = false, | 58 | /// With verify = false, |
46 | fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { | 59 | fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { |
@@ -62,6 +75,18 @@ fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { | |||
62 | } | 75 | } |
63 | } | 76 | } |
64 | 77 | ||
78 | const PREAMBLE: &str = "Generated file, do not edit by hand, see `xtask/src/codegen`"; | ||
79 | |||
80 | fn reformat(text: impl std::fmt::Display) -> Result<String> { | ||
81 | let _e = pushenv("RUSTUP_TOOLCHAIN", "stable"); | ||
82 | ensure_rustfmt()?; | ||
83 | let stdout = run!( | ||
84 | "rustfmt --config-path {} --config fn_single_line=true", project_root().join("rustfmt.toml").display(); | ||
85 | <text.to_string().as_bytes() | ||
86 | )?; | ||
87 | Ok(format!("//! {}\n\n{}\n", PREAMBLE, stdout)) | ||
88 | } | ||
89 | |||
65 | fn extract_comment_blocks(text: &str) -> Vec<Vec<String>> { | 90 | fn extract_comment_blocks(text: &str) -> Vec<Vec<String>> { |
66 | do_extract_comment_blocks(text, false).into_iter().map(|(_line, block)| block).collect() | 91 | do_extract_comment_blocks(text, false).into_iter().map(|(_line, block)| block).collect() |
67 | } | 92 | } |
diff --git a/xtask/src/codegen/gen_assists_docs.rs b/xtask/src/codegen/gen_assists_docs.rs index 526941f73..f0ded8b87 100644 --- a/xtask/src/codegen/gen_assists_docs.rs +++ b/xtask/src/codegen/gen_assists_docs.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::{fmt, fs, path::Path}; | 3 | use std::{fmt, fs, path::Path}; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode}, | 6 | codegen::{self, extract_comment_blocks_with_empty_lines, reformat, Location, Mode, PREAMBLE}, |
7 | project_root, rust_files, Result, | 7 | project_root, rust_files, Result, |
8 | }; | 8 | }; |
9 | 9 | ||
@@ -15,7 +15,7 @@ pub fn generate_assists_tests(mode: Mode) -> Result<()> { | |||
15 | pub fn generate_assists_docs(mode: Mode) -> Result<()> { | 15 | pub fn generate_assists_docs(mode: Mode) -> Result<()> { |
16 | let assists = Assist::collect()?; | 16 | let assists = Assist::collect()?; |
17 | let contents = assists.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); | 17 | let contents = assists.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); |
18 | let contents = contents.trim().to_string() + "\n"; | 18 | let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); |
19 | let dst = project_root().join("docs/user/generated_assists.adoc"); | 19 | let dst = project_root().join("docs/user/generated_assists.adoc"); |
20 | codegen::update(&dst, &contents, mode) | 20 | codegen::update(&dst, &contents, mode) |
21 | } | 21 | } |
@@ -32,7 +32,7 @@ struct Assist { | |||
32 | impl Assist { | 32 | impl Assist { |
33 | fn collect() -> Result<Vec<Assist>> { | 33 | fn collect() -> Result<Vec<Assist>> { |
34 | let mut res = Vec::new(); | 34 | let mut res = Vec::new(); |
35 | for path in rust_files(&project_root().join(codegen::ASSISTS_DIR)) { | 35 | for path in rust_files(&project_root().join("crates/assists/src/handlers")) { |
36 | collect_file(&mut res, path.as_path())?; | 36 | collect_file(&mut res, path.as_path())?; |
37 | } | 37 | } |
38 | res.sort_by(|lhs, rhs| lhs.id.cmp(&rhs.id)); | 38 | res.sort_by(|lhs, rhs| lhs.id.cmp(&rhs.id)); |
@@ -134,8 +134,8 @@ r#####" | |||
134 | 134 | ||
135 | buf.push_str(&test) | 135 | buf.push_str(&test) |
136 | } | 136 | } |
137 | let buf = crate::reformat(buf)?; | 137 | let buf = reformat(buf)?; |
138 | codegen::update(&project_root().join(codegen::ASSISTS_TESTS), &buf, mode) | 138 | codegen::update(&project_root().join("crates/assists/src/tests/generated.rs"), &buf, mode) |
139 | } | 139 | } |
140 | 140 | ||
141 | fn hide_hash_comments(text: &str) -> String { | 141 | fn hide_hash_comments(text: &str) -> String { |
diff --git a/xtask/src/codegen/gen_feature_docs.rs b/xtask/src/codegen/gen_feature_docs.rs index 31bc3839d..3f0013e82 100644 --- a/xtask/src/codegen/gen_feature_docs.rs +++ b/xtask/src/codegen/gen_feature_docs.rs | |||
@@ -3,14 +3,14 @@ | |||
3 | use std::{fmt, fs, path::PathBuf}; | 3 | use std::{fmt, fs, path::PathBuf}; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode}, | 6 | codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode, PREAMBLE}, |
7 | project_root, rust_files, Result, | 7 | project_root, rust_files, Result, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | pub fn generate_feature_docs(mode: Mode) -> Result<()> { | 10 | pub fn generate_feature_docs(mode: Mode) -> Result<()> { |
11 | let features = Feature::collect()?; | 11 | let features = Feature::collect()?; |
12 | let contents = features.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); | 12 | let contents = features.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); |
13 | let contents = contents.trim().to_string() + "\n"; | 13 | let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); |
14 | let dst = project_root().join("docs/user/generated_features.adoc"); | 14 | let dst = project_root().join("docs/user/generated_features.adoc"); |
15 | codegen::update(&dst, &contents, mode)?; | 15 | codegen::update(&dst, &contents, mode)?; |
16 | Ok(()) | 16 | Ok(()) |
diff --git a/xtask/src/codegen/gen_features.rs b/xtask/src/codegen/gen_features.rs new file mode 100644 index 000000000..78268308b --- /dev/null +++ b/xtask/src/codegen/gen_features.rs | |||
@@ -0,0 +1,50 @@ | |||
1 | //! Generates descriptors structure for unstable feature from Unstable Book | ||
2 | use std::path::{Path, PathBuf}; | ||
3 | |||
4 | use quote::quote; | ||
5 | use walkdir::WalkDir; | ||
6 | |||
7 | use crate::{ | ||
8 | codegen::{project_root, reformat, update, Mode, Result}, | ||
9 | not_bash::{fs2, run}, | ||
10 | }; | ||
11 | |||
12 | pub fn generate_features(mode: Mode) -> Result<()> { | ||
13 | if !Path::new("./target/rust").exists() { | ||
14 | run!("git clone https://github.com/rust-lang/rust ./target/rust")?; | ||
15 | } | ||
16 | |||
17 | let contents = generate_descriptor("./target/rust/src/doc/unstable-book/src".into())?; | ||
18 | |||
19 | let destination = project_root().join("crates/ide/src/completion/generated_features.rs"); | ||
20 | update(destination.as_path(), &contents, mode)?; | ||
21 | |||
22 | Ok(()) | ||
23 | } | ||
24 | |||
25 | fn generate_descriptor(src_dir: PathBuf) -> Result<String> { | ||
26 | let definitions = ["language-features", "library-features"] | ||
27 | .iter() | ||
28 | .flat_map(|it| WalkDir::new(src_dir.join(it))) | ||
29 | .filter_map(|e| e.ok()) | ||
30 | .filter(|entry| { | ||
31 | // Get all `.md ` files | ||
32 | entry.file_type().is_file() && entry.path().extension().unwrap_or_default() == "md" | ||
33 | }) | ||
34 | .map(|entry| { | ||
35 | let path = entry.path(); | ||
36 | let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_"); | ||
37 | let doc = fs2::read_to_string(path).unwrap(); | ||
38 | |||
39 | quote! { LintCompletion { label: #feature_ident, description: #doc } } | ||
40 | }); | ||
41 | |||
42 | let ts = quote! { | ||
43 | use crate::completion::complete_attribute::LintCompletion; | ||
44 | |||
45 | pub(super) const FEATURES: &[LintCompletion] = &[ | ||
46 | #(#definitions),* | ||
47 | ]; | ||
48 | }; | ||
49 | reformat(ts) | ||
50 | } | ||
diff --git a/xtask/src/codegen/gen_parser_tests.rs b/xtask/src/codegen/gen_parser_tests.rs index 2977da2fa..96fdd9216 100644 --- a/xtask/src/codegen/gen_parser_tests.rs +++ b/xtask/src/codegen/gen_parser_tests.rs | |||
@@ -8,12 +8,12 @@ use std::{ | |||
8 | }; | 8 | }; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | codegen::{self, extract_comment_blocks, update, Mode}, | 11 | codegen::{extract_comment_blocks, update, Mode}, |
12 | project_root, Result, | 12 | project_root, Result, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | pub fn generate_parser_tests(mode: Mode) -> Result<()> { | 15 | pub fn generate_parser_tests(mode: Mode) -> Result<()> { |
16 | let tests = tests_from_dir(&project_root().join(Path::new(codegen::GRAMMAR_DIR)))?; | 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, mode: Mode) -> 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() { |
@@ -39,8 +39,8 @@ pub fn generate_parser_tests(mode: Mode) -> Result<()> { | |||
39 | } | 39 | } |
40 | Ok(()) | 40 | Ok(()) |
41 | } | 41 | } |
42 | install_tests(&tests.ok, codegen::OK_INLINE_TESTS_DIR, mode)?; | 42 | install_tests(&tests.ok, "crates/syntax/test_data/parser/inline/ok", mode)?; |
43 | install_tests(&tests.err, codegen::ERR_INLINE_TESTS_DIR, mode) | 43 | install_tests(&tests.err, "crates/syntax/test_data/parser/inline/err", mode) |
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 dd1f4d6a2..53ae9f11c 100644 --- a/xtask/src/codegen/gen_syntax.rs +++ b/xtask/src/codegen/gen_syntax.rs | |||
@@ -14,7 +14,7 @@ use ungrammar::{rust_grammar, Grammar, Rule}; | |||
14 | 14 | ||
15 | use crate::{ | 15 | use 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::{self, update, Mode}, | 17 | codegen::{reformat, update, Mode}, |
18 | project_root, Result, | 18 | project_root, Result, |
19 | }; | 19 | }; |
20 | 20 | ||
@@ -22,15 +22,15 @@ pub fn generate_syntax(mode: Mode) -> 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(codegen::SYNTAX_KINDS); | 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 | update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; |
28 | 28 | ||
29 | let ast_tokens_file = project_root().join(codegen::AST_TOKENS); | 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 | update(ast_tokens_file.as_path(), &contents, mode)?; |
32 | 32 | ||
33 | let ast_nodes_file = project_root().join(codegen::AST_NODES); | 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 | update(ast_nodes_file.as_path(), &contents, mode)?; |
36 | 36 | ||
@@ -61,7 +61,7 @@ fn generate_tokens(grammar: &AstSrc) -> Result<String> { | |||
61 | } | 61 | } |
62 | }); | 62 | }); |
63 | 63 | ||
64 | let pretty = crate::reformat(quote! { | 64 | let pretty = reformat(quote! { |
65 | use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken}; | 65 | use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken}; |
66 | #(#tokens)* | 66 | #(#tokens)* |
67 | })? | 67 | })? |
@@ -261,7 +261,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> Result<String> { | |||
261 | } | 261 | } |
262 | } | 262 | } |
263 | 263 | ||
264 | let pretty = crate::reformat(res)?; | 264 | let pretty = reformat(res)?; |
265 | Ok(pretty) | 265 | Ok(pretty) |
266 | } | 266 | } |
267 | 267 | ||
@@ -383,7 +383,7 @@ fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> Result<String> { | |||
383 | } | 383 | } |
384 | }; | 384 | }; |
385 | 385 | ||
386 | crate::reformat(ast) | 386 | reformat(ast) |
387 | } | 387 | } |
388 | 388 | ||
389 | fn to_upper_snake_case(s: &str) -> String { | 389 | fn to_upper_snake_case(s: &str) -> String { |
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index 807ef587c..e790d995f 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs | |||
@@ -3,14 +3,15 @@ | |||
3 | //! See https://github.com/matklad/cargo-xtask/ | 3 | //! See https://github.com/matklad/cargo-xtask/ |
4 | 4 | ||
5 | pub mod not_bash; | 5 | pub mod not_bash; |
6 | pub mod codegen; | ||
7 | mod ast_src; | ||
8 | |||
6 | pub mod install; | 9 | pub mod install; |
7 | pub mod release; | 10 | pub mod release; |
8 | pub mod dist; | 11 | pub mod dist; |
9 | pub mod pre_commit; | 12 | pub mod pre_commit; |
10 | pub mod metrics; | 13 | pub mod metrics; |
11 | 14 | pub mod pre_cache; | |
12 | pub mod codegen; | ||
13 | mod ast_src; | ||
14 | 15 | ||
15 | use std::{ | 16 | use std::{ |
16 | env, | 17 | env, |
@@ -21,7 +22,7 @@ use walkdir::{DirEntry, WalkDir}; | |||
21 | 22 | ||
22 | use crate::{ | 23 | use crate::{ |
23 | codegen::Mode, | 24 | codegen::Mode, |
24 | not_bash::{fs2, pushd, pushenv, rm_rf}, | 25 | not_bash::{pushd, pushenv}, |
25 | }; | 26 | }; |
26 | 27 | ||
27 | pub use anyhow::{bail, Context as _, Result}; | 28 | pub use anyhow::{bail, Context as _, Result}; |
@@ -62,17 +63,6 @@ pub fn run_rustfmt(mode: Mode) -> Result<()> { | |||
62 | Ok(()) | 63 | Ok(()) |
63 | } | 64 | } |
64 | 65 | ||
65 | fn reformat(text: impl std::fmt::Display) -> Result<String> { | ||
66 | let _e = pushenv("RUSTUP_TOOLCHAIN", "stable"); | ||
67 | ensure_rustfmt()?; | ||
68 | let stdout = run!( | ||
69 | "rustfmt --config-path {} --config fn_single_line=true", project_root().join("rustfmt.toml").display(); | ||
70 | <text.to_string().as_bytes() | ||
71 | )?; | ||
72 | let preamble = "Generated file, do not edit by hand, see `xtask/src/codegen`"; | ||
73 | Ok(format!("//! {}\n\n{}\n", preamble, stdout)) | ||
74 | } | ||
75 | |||
76 | fn ensure_rustfmt() -> Result<()> { | 66 | fn ensure_rustfmt() -> Result<()> { |
77 | let out = run!("rustfmt --version")?; | 67 | let out = run!("rustfmt --version")?; |
78 | if !out.contains("stable") { | 68 | if !out.contains("stable") { |
@@ -119,42 +109,6 @@ pub fn run_fuzzer() -> Result<()> { | |||
119 | Ok(()) | 109 | Ok(()) |
120 | } | 110 | } |
121 | 111 | ||
122 | /// Cleans the `./target` dir after the build such that only | ||
123 | /// dependencies are cached on CI. | ||
124 | pub fn run_pre_cache() -> Result<()> { | ||
125 | let slow_tests_cookie = Path::new("./target/.slow_tests_cookie"); | ||
126 | if !slow_tests_cookie.exists() { | ||
127 | panic!("slow tests were skipped on CI!") | ||
128 | } | ||
129 | rm_rf(slow_tests_cookie)?; | ||
130 | |||
131 | for entry in Path::new("./target/debug").read_dir()? { | ||
132 | let entry = entry?; | ||
133 | if entry.file_type().map(|it| it.is_file()).ok() == Some(true) { | ||
134 | // Can't delete yourself on windows :-( | ||
135 | if !entry.path().ends_with("xtask.exe") { | ||
136 | rm_rf(&entry.path())? | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | |||
141 | fs2::remove_file("./target/.rustc_info.json")?; | ||
142 | let to_delete = ["hir", "heavy_test", "xtask", "ide", "rust-analyzer"]; | ||
143 | for &dir in ["./target/debug/deps", "target/debug/.fingerprint"].iter() { | ||
144 | for entry in Path::new(dir).read_dir()? { | ||
145 | let entry = entry?; | ||
146 | if to_delete.iter().any(|&it| entry.path().display().to_string().contains(it)) { | ||
147 | // Can't delete yourself on windows :-( | ||
148 | if !entry.path().ends_with("xtask.exe") { | ||
149 | rm_rf(&entry.path())? | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | |||
155 | Ok(()) | ||
156 | } | ||
157 | |||
158 | fn is_release_tag(tag: &str) -> bool { | 112 | fn is_release_tag(tag: &str) -> bool { |
159 | tag.len() == "2020-02-24".len() && tag.starts_with(|c: char| c.is_ascii_digit()) | 113 | tag.len() == "2020-02-24".len() && tag.starts_with(|c: char| c.is_ascii_digit()) |
160 | } | 114 | } |
diff --git a/xtask/src/main.rs b/xtask/src/main.rs index b69b884e5..3f4aa5497 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | use std::env; | 11 | use std::env; |
12 | 12 | ||
13 | use codegen::CodegenCmd; | ||
13 | use pico_args::Arguments; | 14 | use pico_args::Arguments; |
14 | use xtask::{ | 15 | use xtask::{ |
15 | codegen::{self, Mode}, | 16 | codegen::{self, Mode}, |
@@ -17,9 +18,10 @@ use xtask::{ | |||
17 | install::{ClientOpt, InstallCmd, Malloc, ServerOpt}, | 18 | install::{ClientOpt, InstallCmd, Malloc, ServerOpt}, |
18 | metrics::MetricsCmd, | 19 | metrics::MetricsCmd, |
19 | not_bash::pushd, | 20 | not_bash::pushd, |
21 | pre_cache::PreCacheCmd, | ||
20 | pre_commit, project_root, | 22 | pre_commit, project_root, |
21 | release::{PromoteCmd, ReleaseCmd}, | 23 | release::{PromoteCmd, ReleaseCmd}, |
22 | run_clippy, run_fuzzer, run_pre_cache, run_rustfmt, Result, | 24 | run_clippy, run_fuzzer, run_rustfmt, Result, |
23 | }; | 25 | }; |
24 | 26 | ||
25 | fn main() -> Result<()> { | 27 | fn main() -> Result<()> { |
@@ -74,13 +76,9 @@ FLAGS: | |||
74 | .run() | 76 | .run() |
75 | } | 77 | } |
76 | "codegen" => { | 78 | "codegen" => { |
79 | let features = args.contains("--features"); | ||
77 | args.finish()?; | 80 | args.finish()?; |
78 | codegen::generate_syntax(Mode::Overwrite)?; | 81 | CodegenCmd { features }.run() |
79 | codegen::generate_parser_tests(Mode::Overwrite)?; | ||
80 | codegen::generate_assists_tests(Mode::Overwrite)?; | ||
81 | codegen::generate_assists_docs(Mode::Overwrite)?; | ||
82 | codegen::generate_feature_docs(Mode::Overwrite)?; | ||
83 | Ok(()) | ||
84 | } | 82 | } |
85 | "format" => { | 83 | "format" => { |
86 | args.finish()?; | 84 | args.finish()?; |
@@ -100,7 +98,7 @@ FLAGS: | |||
100 | } | 98 | } |
101 | "pre-cache" => { | 99 | "pre-cache" => { |
102 | args.finish()?; | 100 | args.finish()?; |
103 | run_pre_cache() | 101 | PreCacheCmd.run() |
104 | } | 102 | } |
105 | "release" => { | 103 | "release" => { |
106 | let dry_run = args.contains("--dry-run"); | 104 | let dry_run = args.contains("--dry-run"); |
diff --git a/xtask/src/pre_cache.rs b/xtask/src/pre_cache.rs new file mode 100644 index 000000000..47ba6ba24 --- /dev/null +++ b/xtask/src/pre_cache.rs | |||
@@ -0,0 +1,80 @@ | |||
1 | use std::{ | ||
2 | fs::FileType, | ||
3 | path::{Path, PathBuf}, | ||
4 | }; | ||
5 | |||
6 | use anyhow::Result; | ||
7 | |||
8 | use crate::not_bash::{fs2, rm_rf}; | ||
9 | |||
10 | pub struct PreCacheCmd; | ||
11 | |||
12 | impl PreCacheCmd { | ||
13 | /// Cleans the `./target` dir after the build such that only | ||
14 | /// dependencies are cached on CI. | ||
15 | pub fn run(self) -> Result<()> { | ||
16 | let slow_tests_cookie = Path::new("./target/.slow_tests_cookie"); | ||
17 | if !slow_tests_cookie.exists() { | ||
18 | panic!("slow tests were skipped on CI!") | ||
19 | } | ||
20 | rm_rf(slow_tests_cookie)?; | ||
21 | |||
22 | for path in read_dir("./target/debug", FileType::is_file)? { | ||
23 | // Can't delete yourself on windows :-( | ||
24 | if !path.ends_with("xtask.exe") { | ||
25 | rm_rf(&path)? | ||
26 | } | ||
27 | } | ||
28 | |||
29 | fs2::remove_file("./target/.rustc_info.json")?; | ||
30 | |||
31 | let to_delete = read_dir("./crates", FileType::is_dir)? | ||
32 | .into_iter() | ||
33 | .map(|path| path.file_name().unwrap().to_string_lossy().replace('-', "_")) | ||
34 | .collect::<Vec<_>>(); | ||
35 | |||
36 | for &dir in ["./target/debug/deps", "target/debug/.fingerprint"].iter() { | ||
37 | for path in read_dir(dir, |_file_type| true)? { | ||
38 | if path.ends_with("xtask.exe") { | ||
39 | continue; | ||
40 | } | ||
41 | let file_name = path.file_name().unwrap().to_string_lossy(); | ||
42 | let (stem, _) = match rsplit_once(&file_name, '-') { | ||
43 | Some(it) => it, | ||
44 | None => { | ||
45 | rm_rf(path)?; | ||
46 | continue; | ||
47 | } | ||
48 | }; | ||
49 | let stem = stem.replace('-', "_"); | ||
50 | if to_delete.contains(&stem) { | ||
51 | rm_rf(path)?; | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | |||
56 | Ok(()) | ||
57 | } | ||
58 | } | ||
59 | fn read_dir(path: impl AsRef<Path>, cond: impl Fn(&FileType) -> bool) -> Result<Vec<PathBuf>> { | ||
60 | read_dir_impl(path.as_ref(), &cond) | ||
61 | } | ||
62 | |||
63 | fn read_dir_impl(path: &Path, cond: &dyn Fn(&FileType) -> bool) -> Result<Vec<PathBuf>> { | ||
64 | let mut res = Vec::new(); | ||
65 | for entry in path.read_dir()? { | ||
66 | let entry = entry?; | ||
67 | let file_type = entry.file_type()?; | ||
68 | if cond(&file_type) { | ||
69 | res.push(entry.path()) | ||
70 | } | ||
71 | } | ||
72 | Ok(res) | ||
73 | } | ||
74 | |||
75 | fn rsplit_once(haystack: &str, delim: char) -> Option<(&str, &str)> { | ||
76 | let mut split = haystack.rsplitn(2, delim); | ||
77 | let suffix = split.next()?; | ||
78 | let prefix = split.next()?; | ||
79 | Some((prefix, suffix)) | ||
80 | } | ||