aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-05-31 00:54:54 +0100
committerAleksey Kladov <[email protected]>2020-05-31 00:54:54 +0100
commitc8f27a4a886413a15a2a6af4a87b39b901c873a8 (patch)
treeae4f7c31fa30581ef09b3c29d2673dee922e5845 /xtask
parent383247a9ae8202f20ce6f01d1429c1cd2a11d516 (diff)
Generate features docs from source
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/codegen.rs5
-rw-r--r--xtask/src/codegen/gen_feature_docs.rs72
-rw-r--r--xtask/src/main.rs1
-rw-r--r--xtask/tests/tidy.rs7
4 files changed, 83 insertions, 2 deletions
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs
index 2e8fd3494..3e2a66979 100644
--- a/xtask/src/codegen.rs
+++ b/xtask/src/codegen.rs
@@ -8,14 +8,15 @@
8mod gen_syntax; 8mod gen_syntax;
9mod gen_parser_tests; 9mod gen_parser_tests;
10mod gen_assists_docs; 10mod gen_assists_docs;
11mod gen_feature_docs;
11 12
12use std::{mem, path::Path}; 13use std::{mem, path::Path};
13 14
14use crate::{not_bash::fs2, Result}; 15use crate::{not_bash::fs2, Result};
15 16
16pub use self::{ 17pub use self::{
17 gen_assists_docs::generate_assists_docs, gen_parser_tests::generate_parser_tests, 18 gen_assists_docs::generate_assists_docs, gen_feature_docs::generate_feature_docs,
18 gen_syntax::generate_syntax, 19 gen_parser_tests::generate_parser_tests, gen_syntax::generate_syntax,
19}; 20};
20 21
21const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar"; 22const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar";
diff --git a/xtask/src/codegen/gen_feature_docs.rs b/xtask/src/codegen/gen_feature_docs.rs
new file mode 100644
index 000000000..583185648
--- /dev/null
+++ b/xtask/src/codegen/gen_feature_docs.rs
@@ -0,0 +1,72 @@
1//! Generates `assists.md` documentation.
2
3use std::{fmt, fs, path::PathBuf};
4
5use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, Mode},
7 project_root, rust_files, Result,
8};
9
10pub fn generate_feature_docs(mode: Mode) -> Result<()> {
11 let features = Feature::collect()?;
12 let contents = features.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
13
14 let dst = project_root().join("docs/user/generated_features.adoc");
15 codegen::update(&dst, &contents, mode)?;
16 Ok(())
17}
18
19#[derive(Debug)]
20struct Feature {
21 id: String,
22 path: PathBuf,
23 doc: String,
24}
25
26impl Feature {
27 fn collect() -> Result<Vec<Feature>> {
28 let mut res = Vec::new();
29 for path in rust_files(&project_root()) {
30 collect_file(&mut res, path)?;
31 }
32 res.sort_by(|lhs, rhs| lhs.id.cmp(&rhs.id));
33 return Ok(res);
34
35 fn collect_file(acc: &mut Vec<Feature>, path: PathBuf) -> Result<()> {
36 let text = fs::read_to_string(&path)?;
37 let comment_blocks = extract_comment_blocks_with_empty_lines("Feature", &text);
38
39 for block in comment_blocks {
40 let id = block.id;
41 assert!(
42 id.split_ascii_whitespace().all(|it| it.starts_with(char::is_uppercase)),
43 "bad feature: {}",
44 id
45 );
46 let doc = block.contents.join("\n");
47 acc.push(Feature { id, path: path.clone(), doc })
48 }
49
50 Ok(())
51 }
52 }
53}
54
55impl fmt::Display for Feature {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 writeln!(f, "=== {}", self.id)?;
58 let path = self.path.strip_prefix(&project_root()).unwrap();
59 let name = self.path.file_name().unwrap();
60
61 //FIXME: generate line number as well
62 writeln!(
63 f,
64 "**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/{}[{}]",
65 path.display(),
66 name.to_str().unwrap(),
67 )?;
68
69 writeln!(f, "\n{}", self.doc)?;
70 Ok(())
71 }
72}
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index dff3ce4a1..9d7cdd114 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -75,6 +75,7 @@ FLAGS:
75 codegen::generate_syntax(Mode::Overwrite)?; 75 codegen::generate_syntax(Mode::Overwrite)?;
76 codegen::generate_parser_tests(Mode::Overwrite)?; 76 codegen::generate_parser_tests(Mode::Overwrite)?;
77 codegen::generate_assists_docs(Mode::Overwrite)?; 77 codegen::generate_assists_docs(Mode::Overwrite)?;
78 codegen::generate_feature_docs(Mode::Overwrite)?;
78 Ok(()) 79 Ok(())
79 } 80 }
80 "format" => { 81 "format" => {
diff --git a/xtask/tests/tidy.rs b/xtask/tests/tidy.rs
index 2e9fcf07c..06ff45d99 100644
--- a/xtask/tests/tidy.rs
+++ b/xtask/tests/tidy.rs
@@ -31,6 +31,13 @@ fn generated_assists_are_fresh() {
31} 31}
32 32
33#[test] 33#[test]
34fn generated_features_are_fresh() {
35 if let Err(error) = codegen::generate_feature_docs(Mode::Verify) {
36 panic!("{}. Please update features by running `cargo xtask codegen`", error);
37 }
38}
39
40#[test]
34fn check_code_formatting() { 41fn check_code_formatting() {
35 if let Err(error) = run_rustfmt(Mode::Verify) { 42 if let Err(error) = run_rustfmt(Mode::Verify) {
36 panic!("{}. Please format the code by running `cargo format`", error); 43 panic!("{}. Please format the code by running `cargo format`", error);