diff --git a/Cargo.lock b/Cargo.lock index 6042f69..ce48f1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -676,6 +676,12 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e4afd9ad95555081e109fe1d21f2a30c691b5f0919c67dfa690a2e1eb6bd51c" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "h2" version = "0.3.16" @@ -831,6 +837,26 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "include_dir" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +dependencies = [ + "glob", + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "indexmap" version = "1.9.2" @@ -1010,6 +1036,7 @@ dependencies = [ "console", "full_moon", "futures-util", + "include_dir", "lazy_static", "lune", "regex", diff --git a/packages/cli/Cargo.toml b/packages/cli/Cargo.toml index b759388..5d18043 100644 --- a/packages/cli/Cargo.toml +++ b/packages/cli/Cargo.toml @@ -34,4 +34,5 @@ anyhow = "1.0" clap = { version = "4.1", features = ["derive"] } full_moon = { version = "0.17", features = ["roblox"] } +include_dir = { version = "0.7.3", features = ["glob"] } regex = { version = "1.7", default-features = false, features = ["std"] } diff --git a/packages/cli/src/cli.rs b/packages/cli/src/cli.rs index 851f521..6083eab 100644 --- a/packages/cli/src/cli.rs +++ b/packages/cli/src/cli.rs @@ -3,6 +3,7 @@ use std::process::ExitCode; use anyhow::{Context, Result}; use clap::{CommandFactory, Parser}; +use include_dir::{include_dir, Dir}; use lune::Lune; use tokio::{ fs::{read as read_to_vec, write}, @@ -12,7 +13,8 @@ use tokio::{ use crate::{ gen::{ generate_docs_json_from_definitions, generate_luau_defs_from_definitions, - generate_selene_defs_from_definitions, generate_wiki_dir_from_definitions, + generate_selene_defs_from_definitions, generate_typedefs_file_from_dir, + generate_wiki_dir_from_definitions, }, utils::{ files::{discover_script_file_path_including_lune_dirs, strip_shebang}, @@ -24,7 +26,7 @@ pub(crate) const FILE_NAME_SELENE_TYPES: &str = "lune.yml"; pub(crate) const FILE_NAME_LUAU_TYPES: &str = "luneTypes.d.luau"; pub(crate) const FILE_NAME_DOCS: &str = "luneDocs.json"; -pub(crate) const FILE_CONTENTS_LUAU_TYPES: &str = include_str!("../../../docs/luneTypes.d.luau"); +pub(crate) static TYPEDEFS_DIR: Dir<'_> = include_dir!("docs/typedefs"); /// A Luau script runner #[derive(Parser, Debug, Default, Clone)] @@ -121,26 +123,27 @@ impl Cli { || self.generate_docs_file || self.generate_gitbook_dir; if generate_file_requested { + let definitions = generate_typedefs_file_from_dir(&TYPEDEFS_DIR); if self.generate_luau_types { generate_and_save_file(FILE_NAME_LUAU_TYPES, "Luau type definitions", || { - generate_luau_defs_from_definitions(FILE_CONTENTS_LUAU_TYPES) + generate_luau_defs_from_definitions(&definitions) }) .await?; } if self.generate_selene_types { generate_and_save_file(FILE_NAME_SELENE_TYPES, "Selene type definitions", || { - generate_selene_defs_from_definitions(FILE_CONTENTS_LUAU_TYPES) + generate_selene_defs_from_definitions(&definitions) }) .await?; } if self.generate_docs_file { generate_and_save_file(FILE_NAME_DOCS, "Luau LSP documentation", || { - generate_docs_json_from_definitions(FILE_CONTENTS_LUAU_TYPES, "roblox/global") + generate_docs_json_from_definitions(&definitions, "roblox/global") }) .await?; } if self.generate_gitbook_dir { - generate_wiki_dir_from_definitions(FILE_CONTENTS_LUAU_TYPES).await?; + generate_wiki_dir_from_definitions(&definitions).await?; } } if self.script_path.is_none() { diff --git a/packages/cli/src/gen/mod.rs b/packages/cli/src/gen/mod.rs index 79d5309..4758374 100644 --- a/packages/cli/src/gen/mod.rs +++ b/packages/cli/src/gen/mod.rs @@ -1,3 +1,6 @@ +use include_dir::Dir; +use regex::Regex; + mod docs_file; mod luau_defs; mod selene_defs; @@ -9,3 +12,42 @@ pub use docs_file::generate_from_type_definitions as generate_docs_json_from_def pub use luau_defs::generate_from_type_definitions as generate_luau_defs_from_definitions; pub use selene_defs::generate_from_type_definitions as generate_selene_defs_from_definitions; pub use wiki_dir::generate_from_type_definitions as generate_wiki_dir_from_definitions; + +pub fn generate_typedefs_file_from_dir(dir: &Dir<'_>) -> String { + let mut result = String::new(); + + for entry in dir.find("*.luau").unwrap() { + let entry_file = entry.as_file().unwrap(); + let entry_name = entry_file.path().file_name().unwrap().to_string_lossy(); + + if entry_name.contains("Globals") { + continue; + } + + let typedef_name = entry_name.trim_end_matches(".luau"); + let typedef_contents = entry_file.contents_utf8().unwrap().to_string().replace( + &format!("export type {typedef_name} = "), + &format!("declare {}: ", typedef_name.to_ascii_lowercase()), + ); + + if !result.is_empty() { + result.push_str(&"\n".repeat(10)); + } + + result.push_str(&typedef_contents); + } + + let globals_contents = dir + .get_file("Globals.luau") + .unwrap() + .contents_utf8() + .unwrap(); + + let regex_export_to_declare = Regex::new(r#"export type (\w+) = "#).unwrap(); + let regexed_globals = regex_export_to_declare.replace_all(globals_contents, "declare $1: "); + + result.push_str(&"\n".repeat(10)); + result.push_str(®exed_globals); + + result +}