mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
Try to automatically add typedefs to vscode settings or print them out
This commit is contained in:
parent
85bbcaabaa
commit
f7d82f08b0
4 changed files with 87 additions and 15 deletions
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
@ -2,8 +2,6 @@
|
||||||
// Luau - disable Roblox features, enable Lune typedefs & requires
|
// Luau - disable Roblox features, enable Lune typedefs & requires
|
||||||
"luau-lsp.sourcemap.enabled": false,
|
"luau-lsp.sourcemap.enabled": false,
|
||||||
"luau-lsp.types.roblox": false,
|
"luau-lsp.types.roblox": false,
|
||||||
"luau-lsp.types.definitionFiles": ["luneTypes.d.luau"],
|
|
||||||
"luau-lsp.types.documentationFiles": ["luneDocs.json"],
|
|
||||||
"luau-lsp.require.mode": "relativeToFile",
|
"luau-lsp.require.mode": "relativeToFile",
|
||||||
// Luau - ignore type defs file in docs dir and dev scripts we use
|
// Luau - ignore type defs file in docs dir and dev scripts we use
|
||||||
"luau-lsp.ignoreGlobs": [
|
"luau-lsp.ignoreGlobs": [
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
use std::process::ExitCode;
|
use std::{
|
||||||
|
borrow::BorrowMut,
|
||||||
|
collections::HashMap,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
process::ExitCode,
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use clap::{CommandFactory, Parser};
|
use clap::{CommandFactory, Parser};
|
||||||
|
use serde_json::Value as JsonValue;
|
||||||
|
|
||||||
use include_dir::{include_dir, Dir};
|
use include_dir::{include_dir, Dir};
|
||||||
use lune::Lune;
|
use lune::Lune;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
fs::read as read_to_vec,
|
fs::{self, read as read_to_vec},
|
||||||
io::{stdin, AsyncReadExt},
|
io::{stdin, AsyncReadExt},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,6 +87,7 @@ impl Cli {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
pub async fn run(self) -> Result<ExitCode> {
|
pub async fn run(self) -> Result<ExitCode> {
|
||||||
// List files in `lune` and `.lune` directories, if wanted
|
// List files in `lune` and `.lune` directories, if wanted
|
||||||
// This will also exit early and not run anything else
|
// This will also exit early and not run anything else
|
||||||
|
@ -124,7 +131,43 @@ impl Cli {
|
||||||
return Ok(ExitCode::FAILURE);
|
return Ok(ExitCode::FAILURE);
|
||||||
}
|
}
|
||||||
if self.setup {
|
if self.setup {
|
||||||
|
let generated_paths =
|
||||||
generate_typedef_files_from_definitions(&TYPEDEFS_DIR).await?;
|
generate_typedef_files_from_definitions(&TYPEDEFS_DIR).await?;
|
||||||
|
let settings_json_path = PathBuf::from(".vscode/settings.json");
|
||||||
|
let message = match fs::metadata(&settings_json_path).await {
|
||||||
|
Ok(meta) if meta.is_file() => {
|
||||||
|
if try_add_generated_typedefs_vscode(&settings_json_path, &generated_paths).await.is_err() {
|
||||||
|
"These files can be added to your LSP settings for autocomplete and documentation."
|
||||||
|
} else {
|
||||||
|
"These files have now been added to your workspace LSP settings for Visual Studio Code."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => "These files can be added to your LSP settings for autocomplete and documentation.",
|
||||||
|
};
|
||||||
|
// HACK: We should probably just be serializing this hashmap to print it out, but
|
||||||
|
// that does not guarantee sorting and the sorted version is much easier to read
|
||||||
|
let mut sorted_names = generated_paths
|
||||||
|
.keys()
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
sorted_names.sort_unstable();
|
||||||
|
println!(
|
||||||
|
"Typedefs have been generated in the following locations:\n{{\n{}\n}}\n{message}",
|
||||||
|
sorted_names
|
||||||
|
.iter()
|
||||||
|
.map(|name| {
|
||||||
|
let path = generated_paths.get(name).unwrap();
|
||||||
|
format!(
|
||||||
|
" \"@lune/{}\": \"{}\",",
|
||||||
|
name,
|
||||||
|
path.canonicalize().unwrap().display()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n")
|
||||||
|
.strip_suffix(',')
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.script_path.is_none() {
|
if self.script_path.is_none() {
|
||||||
|
@ -172,3 +215,29 @@ impl Cli {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn try_add_generated_typedefs_vscode(
|
||||||
|
settings_json_path: &Path,
|
||||||
|
generated_paths: &HashMap<String, PathBuf>,
|
||||||
|
) -> Result<()> {
|
||||||
|
// FUTURE: Use a jsonc or json5 to read this file instead since it may contain comments and fail
|
||||||
|
let settings_json_contents = fs::read(settings_json_path).await?;
|
||||||
|
let mut settings_changed: bool = false;
|
||||||
|
let mut settings_json: JsonValue = serde_json::from_slice(&settings_json_contents)?;
|
||||||
|
if let JsonValue::Object(settings) = settings_json.borrow_mut() {
|
||||||
|
if let Some(JsonValue::Object(aliases)) = settings.get_mut("luau-lsp.require.fileAliases") {
|
||||||
|
for (name, path) in generated_paths {
|
||||||
|
settings_changed = true;
|
||||||
|
aliases.insert(
|
||||||
|
format!("@lune/{name}"),
|
||||||
|
JsonValue::String(path.canonicalize().unwrap().to_string_lossy().to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if settings_changed {
|
||||||
|
let settings_json_new = serde_json::to_vec_pretty(&settings_json)?;
|
||||||
|
fs::write(settings_json_path, settings_json_new).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, path::PathBuf};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use include_dir::Dir;
|
use include_dir::Dir;
|
||||||
|
@ -15,7 +15,9 @@ pub async fn generate_gitbook_dir_from_definitions(dir: &Dir<'_>) -> Result<()>
|
||||||
gitbook_dir::generate_from_type_definitions(definitions).await
|
gitbook_dir::generate_from_type_definitions(definitions).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn generate_typedef_files_from_definitions(dir: &Dir<'_>) -> Result<()> {
|
pub async fn generate_typedef_files_from_definitions(
|
||||||
|
dir: &Dir<'_>,
|
||||||
|
) -> Result<HashMap<String, PathBuf>> {
|
||||||
let definitions = read_typedefs_dir(dir)?;
|
let definitions = read_typedefs_dir(dir)?;
|
||||||
typedef_files::generate_from_type_definitions(definitions).await
|
typedef_files::generate_from_type_definitions(definitions).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{collections::HashMap, fmt::Write};
|
use std::{collections::HashMap, fmt::Write, path::PathBuf};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use directories::UserDirs;
|
use directories::UserDirs;
|
||||||
|
@ -13,7 +13,7 @@ const GENERATED_COMMENT_TAG: &str = "--!strict";
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub async fn generate_from_type_definitions(
|
pub async fn generate_from_type_definitions(
|
||||||
api_reference: HashMap<String, DefinitionsTree>,
|
api_reference: HashMap<String, DefinitionsTree>,
|
||||||
) -> Result<()> {
|
) -> Result<HashMap<String, PathBuf>> {
|
||||||
let mut dirs_to_write = Vec::new();
|
let mut dirs_to_write = Vec::new();
|
||||||
let mut files_to_write = Vec::new();
|
let mut files_to_write = Vec::new();
|
||||||
// Create the typedefs dir in the users cache dir
|
// Create the typedefs dir in the users cache dir
|
||||||
|
@ -21,7 +21,7 @@ pub async fn generate_from_type_definitions(
|
||||||
.context("Failed to find user home directory")?
|
.context("Failed to find user home directory")?
|
||||||
.home_dir()
|
.home_dir()
|
||||||
.join(".lune")
|
.join(".lune")
|
||||||
.join("typedefs")
|
.join(".typedefs")
|
||||||
.join(env!("CARGO_PKG_VERSION"));
|
.join(env!("CARGO_PKG_VERSION"));
|
||||||
dirs_to_write.push(cache_dir.clone());
|
dirs_to_write.push(cache_dir.clone());
|
||||||
// Make typedef files
|
// Make typedef files
|
||||||
|
@ -36,8 +36,8 @@ pub async fn generate_from_type_definitions(
|
||||||
category_name.to_lowercase(),
|
category_name.to_lowercase(),
|
||||||
env!("CARGO_PKG_VERSION")
|
env!("CARGO_PKG_VERSION")
|
||||||
)?;
|
)?;
|
||||||
write_tree(&mut contents, category_name, category_tree)?;
|
write_tree(&mut contents, category_name.to_string(), category_tree)?;
|
||||||
files_to_write.push((path, contents));
|
files_to_write.push((category_name.to_lowercase(), path, contents));
|
||||||
}
|
}
|
||||||
// Write all dirs and files only when we know generation was successful
|
// Write all dirs and files only when we know generation was successful
|
||||||
let futs_dirs = dirs_to_write
|
let futs_dirs = dirs_to_write
|
||||||
|
@ -45,12 +45,15 @@ pub async fn generate_from_type_definitions(
|
||||||
.map(create_dir_all)
|
.map(create_dir_all)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let futs_files = files_to_write
|
let futs_files = files_to_write
|
||||||
.drain(..)
|
.iter()
|
||||||
.map(|(path, contents)| write(path, contents))
|
.map(|(_, path, contents)| write(path, contents))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
try_join_all(futs_dirs).await?;
|
try_join_all(futs_dirs).await?;
|
||||||
try_join_all(futs_files).await?;
|
try_join_all(futs_files).await?;
|
||||||
Ok(())
|
Ok(files_to_write
|
||||||
|
.drain(..)
|
||||||
|
.map(|(name, path, _)| (name, path))
|
||||||
|
.collect::<HashMap<_, _>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_return_table_item(item: &DefinitionsItem) -> Result<String> {
|
fn make_return_table_item(item: &DefinitionsItem) -> Result<String> {
|
||||||
|
|
Loading…
Reference in a new issue