From a1f48fae47ffe51ed754ab04a41f9dedeb4c677f Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Thu, 16 Feb 2023 12:13:42 +0100 Subject: [PATCH] Organize docs gen --- packages/cli/src/gen/docs_file.rs | 65 ++++++++++++++++ packages/cli/src/gen/mod.rs | 120 ++---------------------------- packages/cli/src/gen/wiki_dir.rs | 56 ++++++++++++++ 3 files changed, 126 insertions(+), 115 deletions(-) create mode 100644 packages/cli/src/gen/docs_file.rs create mode 100644 packages/cli/src/gen/wiki_dir.rs diff --git a/packages/cli/src/gen/docs_file.rs b/packages/cli/src/gen/docs_file.rs new file mode 100644 index 0000000..8feebf1 --- /dev/null +++ b/packages/cli/src/gen/docs_file.rs @@ -0,0 +1,65 @@ +use std::collections::HashMap; + +use anyhow::{Context, Result}; +use serde_json::{Map as JsonMap, Value as JsonValue}; + +use super::doc::{DocsFunctionParamLink, DocumentationVisitor}; + +pub fn generate_from_type_definitions(contents: &str, namespace: &str) -> Result { + let visitor = DocumentationVisitor::from_definitions(contents)?; + /* + Extract globals, functions, params, returns from the visitor + Here we will also convert the plain names into proper namespaced names according to the spec at + https://raw.githubusercontent.com/MaximumADHD/Roblox-Client-Tracker/roblox/api-docs/en-us.json + */ + let mut map = JsonMap::new(); + for (name, mut doc) in visitor.globals { + doc.keys = doc + .keys + .iter() + .map(|(key, value)| (key.clone(), format!("@{namespace}/{name}.{value}"))) + .collect::>(); + map.insert(format!("@{namespace}/{name}"), serde_json::to_value(doc)?); + } + for (name, mut doc) in visitor.functions { + doc.params = doc + .params + .iter() + .map(|param| DocsFunctionParamLink { + name: param.name.clone(), + documentation: format!( + "@{namespace}/{}.{name}/param/{}", + doc.global_name, param.documentation + ), + }) + .collect::>(); + doc.returns = doc + .returns + .iter() + .map(|ret| format!("@{namespace}/{}.{name}/return/{ret}", doc.global_name)) + .collect::>(); + map.insert( + format!("@{namespace}/{}.{name}", doc.global_name), + serde_json::to_value(doc)?, + ); + } + for (name, doc) in visitor.params { + map.insert( + format!( + "@{namespace}/{}.{}/param/{name}", + doc.global_name, doc.function_name + ), + serde_json::to_value(doc)?, + ); + } + for (name, doc) in visitor.returns { + map.insert( + format!( + "@{namespace}/{}.{}/return/{name}", + doc.global_name, doc.function_name + ), + serde_json::to_value(doc)?, + ); + } + serde_json::to_string_pretty(&JsonValue::Object(map)).context("Failed to encode docs as json") +} diff --git a/packages/cli/src/gen/mod.rs b/packages/cli/src/gen/mod.rs index a9c8ac6..c7061ab 100644 --- a/packages/cli/src/gen/mod.rs +++ b/packages/cli/src/gen/mod.rs @@ -1,120 +1,10 @@ -use std::{collections::HashMap, fmt::Write, path::PathBuf}; - -use anyhow::{Context, Result}; -use serde_json::{Map as JsonMap, Value as JsonValue}; - -use tokio::fs::{create_dir_all, write}; - mod doc; +mod docs_file; +mod wiki_dir; -const GENERATED_COMMENT_TAG: &str = "@generated with lune-cli"; +pub use docs_file::generate_from_type_definitions as generate_docs_json_from_definitions; +pub use wiki_dir::generate_from_type_definitions as generate_wiki_dir_from_definitions; -use self::doc::DocsFunctionParamLink; pub use self::doc::DocumentationVisitor; -pub fn generate_docs_json_from_definitions(contents: &str, namespace: &str) -> Result { - let visitor = DocumentationVisitor::from_definitions(contents)?; - /* - Extract globals, functions, params, returns from the visitor - Here we will also convert the plain names into proper namespaced names according to the spec at - https://raw.githubusercontent.com/MaximumADHD/Roblox-Client-Tracker/roblox/api-docs/en-us.json - */ - let mut map = JsonMap::new(); - for (name, mut doc) in visitor.globals { - doc.keys = doc - .keys - .iter() - .map(|(key, value)| (key.clone(), format!("@{namespace}/{name}.{value}"))) - .collect::>(); - map.insert(format!("@{namespace}/{name}"), serde_json::to_value(doc)?); - } - for (name, mut doc) in visitor.functions { - doc.params = doc - .params - .iter() - .map(|param| DocsFunctionParamLink { - name: param.name.clone(), - documentation: format!( - "@{namespace}/{}.{name}/param/{}", - doc.global_name, param.documentation - ), - }) - .collect::>(); - doc.returns = doc - .returns - .iter() - .map(|ret| format!("@{namespace}/{}.{name}/return/{ret}", doc.global_name)) - .collect::>(); - map.insert( - format!("@{namespace}/{}.{name}", doc.global_name), - serde_json::to_value(doc)?, - ); - } - for (name, doc) in visitor.params { - map.insert( - format!( - "@{namespace}/{}.{}/param/{name}", - doc.global_name, doc.function_name - ), - serde_json::to_value(doc)?, - ); - } - for (name, doc) in visitor.returns { - map.insert( - format!( - "@{namespace}/{}.{}/return/{name}", - doc.global_name, doc.function_name - ), - serde_json::to_value(doc)?, - ); - } - serde_json::to_string_pretty(&JsonValue::Object(map)).context("Failed to encode docs as json") -} - -pub async fn generate_wiki_dir_from_definitions(contents: &str) -> Result<()> { - // Create the wiki dir at the repo root - let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("../../") - .canonicalize() - .unwrap(); - create_dir_all(&root.join("wiki")) - .await - .context("Failed to create wiki dir")?; - let visitor = DocumentationVisitor::from_definitions(contents)?; - for global in &visitor.globals { - // Create the dir for this global - let global_dir_path = root.join("wiki").join("api-reference").join(&global.0); - create_dir_all(&global_dir_path) - .await - .context("Failed to create doc dir for global")?; - // Create the markdown docs file for this global - let mut contents = String::new(); - writeln!(contents, "\n")?; - writeln!(contents, "# **{}**\n", global.0)?; - writeln!(contents, "{}\n", global.1.documentation)?; - if !global.1.code_sample.is_empty() { - writeln!(contents, "{}", global.1.code_sample)?; - } - let funcs = visitor - .functions - .iter() - .filter(|f| f.1.global_name == global.0) - .collect::>(); - if !funcs.is_empty() { - writeln!(contents, "## Functions\n")?; - for func in funcs { - writeln!(contents, "### {}\n", func.0)?; - writeln!(contents, "{}\n", func.1.documentation)?; - if !func.1.code_sample.is_empty() { - writeln!(contents, "{}", func.1.code_sample)?; - } - } - } - // Write the file in the dir, with the same - // name as the dir to create an "index" page - write(&global_dir_path.join(format!("{}.md", &global.0)), contents) - .await - .context("Failed to create doc file for global")?; - } - Ok(()) -} +pub const GENERATED_COMMENT_TAG: &str = "@generated with lune-cli"; diff --git a/packages/cli/src/gen/wiki_dir.rs b/packages/cli/src/gen/wiki_dir.rs new file mode 100644 index 0000000..e3dbaf7 --- /dev/null +++ b/packages/cli/src/gen/wiki_dir.rs @@ -0,0 +1,56 @@ +use std::{fmt::Write, path::PathBuf}; + +use anyhow::{Context, Result}; + +use tokio::fs::{create_dir_all, write}; + +use super::doc::DocumentationVisitor; +use super::GENERATED_COMMENT_TAG; + +pub async fn generate_from_type_definitions(contents: &str) -> Result<()> { + let visitor = DocumentationVisitor::from_definitions(contents)?; + // Create the wiki dir at the repo root + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("../../") + .canonicalize() + .unwrap(); + create_dir_all(&root.join("wiki")) + .await + .context("Failed to create wiki dir")?; + for global in &visitor.globals { + // Create the dir for this global + let global_dir_path = root.join("wiki").join("api-reference").join(&global.0); + create_dir_all(&global_dir_path) + .await + .context("Failed to create doc dir for global")?; + // Create the markdown docs file for this global + let mut contents = String::new(); + writeln!(contents, "\n")?; + writeln!(contents, "# **{}**\n", global.0)?; + writeln!(contents, "{}\n", global.1.documentation)?; + if !global.1.code_sample.is_empty() { + writeln!(contents, "{}", global.1.code_sample)?; + } + let funcs = visitor + .functions + .iter() + .filter(|f| f.1.global_name == global.0) + .collect::>(); + if !funcs.is_empty() { + writeln!(contents, "## Functions\n")?; + for func in funcs { + writeln!(contents, "### {}\n", func.0)?; + writeln!(contents, "{}\n", func.1.documentation)?; + if !func.1.code_sample.is_empty() { + writeln!(contents, "{}", func.1.code_sample)?; + } + } + } + // Write the file in the dir, with the same + // name as the dir to create an "index" page + write(&global_dir_path.join(format!("{}.md", &global.0)), contents) + .await + .context("Failed to create doc file for global")?; + } + Ok(()) +}