From e5bc0486b58f24dc4a1309e2e14f71bf72ad7248 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 30 Jan 2025 20:22:10 -0500 Subject: [PATCH] Add `schema_generator` for generating JSON schemas (#23991) This PR adds a `schema_generator` crate that can be used to generate our various JSON schemas for publishing elsewhere. Currently it does the simplest thing possible and just prints the JSON schema to stdout. We can make this a but more robust later. I also removed the schema-printing facilities from the `theme_importer`, as they don't really make sense there. Release Notes: - N/A --- Cargo.lock | 14 ++++++- Cargo.toml | 1 + crates/schema_generator/Cargo.toml | 18 +++++++++ crates/schema_generator/LICENSE-GPL | 1 + crates/schema_generator/src/main.rs | 26 ++++++++++++ crates/theme_importer/Cargo.toml | 1 - crates/theme_importer/src/main.rs | 61 ++++++++--------------------- 7 files changed, 76 insertions(+), 46 deletions(-) create mode 100644 crates/schema_generator/Cargo.toml create mode 120000 crates/schema_generator/LICENSE-GPL create mode 100644 crates/schema_generator/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index f7a49645d1ffe280cf40373154f29206061f471d..e0ccab3a983f25421bd9f416d37b504297889fdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11438,6 +11438,19 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "schema_generator" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "env_logger 0.11.6", + "schemars", + "serde", + "serde_json", + "theme", +] + [[package]] name = "schemars" version = "0.8.21" @@ -13278,7 +13291,6 @@ dependencies = [ "log", "palette", "rust-embed", - "schemars", "serde", "serde_json", "serde_json_lenient", diff --git a/Cargo.toml b/Cargo.toml index 727197b756afce37473a764f025b414cd1d4b8c2..412da3b320a5c27974940941f8d229e40da92c1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -108,6 +108,7 @@ members = [ "crates/rich_text", "crates/rope", "crates/rpc", + "crates/schema_generator", "crates/search", "crates/semantic_index", "crates/semantic_version", diff --git a/crates/schema_generator/Cargo.toml b/crates/schema_generator/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..865f76f4af917606af5d61d173950493fdde07c7 --- /dev/null +++ b/crates/schema_generator/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "schema_generator" +version = "0.1.0" +publish.workspace = true +edition.workspace = true +license = "GPL-3.0-or-later" + +[lints] +workspace = true + +[dependencies] +anyhow.workspace = true +clap = { workspace = true, features = ["derive"] } +env_logger.workspace = true +schemars = { workspace = true, features = ["indexmap2"] } +serde.workspace = true +serde_json.workspace = true +theme.workspace = true diff --git a/crates/schema_generator/LICENSE-GPL b/crates/schema_generator/LICENSE-GPL new file mode 120000 index 0000000000000000000000000000000000000000..89e542f750cd3860a0598eff0dc34b56d7336dc4 --- /dev/null +++ b/crates/schema_generator/LICENSE-GPL @@ -0,0 +1 @@ +../../LICENSE-GPL \ No newline at end of file diff --git a/crates/schema_generator/src/main.rs b/crates/schema_generator/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..2109dbd807c3a1cb327c0d644b9bb43912fdb8df --- /dev/null +++ b/crates/schema_generator/src/main.rs @@ -0,0 +1,26 @@ +use anyhow::Result; +use clap::Parser; +use schemars::schema_for; +use theme::{IconThemeFamilyContent, ThemeFamilyContent}; + +#[derive(Parser, Debug)] +struct Args {} + +fn main() -> Result<()> { + env_logger::init(); + + let _args = Args::parse(); + + let theme_family_schema = schema_for!(ThemeFamilyContent); + println!("Theme Schema:"); + println!("{}", serde_json::to_string_pretty(&theme_family_schema)?); + + let icon_theme_family_schema = schema_for!(IconThemeFamilyContent); + println!("Icon Theme Schema:"); + println!( + "{}", + serde_json::to_string_pretty(&icon_theme_family_schema)? + ); + + Ok(()) +} diff --git a/crates/theme_importer/Cargo.toml b/crates/theme_importer/Cargo.toml index 1323b6345fdf854ea0f42b7dba8fa39d06c87d81..a78ca1d5eaeb596f97df27f779bf763a3a400a86 100644 --- a/crates/theme_importer/Cargo.toml +++ b/crates/theme_importer/Cargo.toml @@ -16,7 +16,6 @@ indexmap.workspace = true log.workspace = true palette.workspace = true rust-embed.workspace = true -schemars = { workspace = true, features = ["indexmap2"] } serde.workspace = true serde_json.workspace = true serde_json_lenient.workspace = true diff --git a/crates/theme_importer/src/main.rs b/crates/theme_importer/src/main.rs index d8e98b5d626471f54a7d4bccdb34906e2baef65a..c2ceee4cfcc0318ce1ab0efda4784f7930631737 100644 --- a/crates/theme_importer/src/main.rs +++ b/crates/theme_importer/src/main.rs @@ -7,14 +7,13 @@ use std::io::Write; use std::path::PathBuf; use anyhow::{Context as _, Result}; -use clap::{Parser, Subcommand}; +use clap::Parser; use indexmap::IndexMap; use log::LevelFilter; -use schemars::schema_for; use serde::Deserialize; use simplelog::ColorChoice; use simplelog::{TermLogger, TerminalMode}; -use theme::{Appearance, AppearanceContent, ThemeFamilyContent}; +use theme::{Appearance, AppearanceContent}; use crate::vscode::VsCodeTheme; use crate::vscode::VsCodeThemeConverter; @@ -71,53 +70,25 @@ pub struct ThemeMetadata { #[derive(Parser)] #[command(author, version, about, long_about = None)] struct Args { - #[command(subcommand)] - command: Command, -} + /// The path to the theme to import. + theme_path: PathBuf, + + /// Whether to warn when values are missing from the theme. + #[arg(long)] + warn_on_missing: bool, -#[derive(PartialEq, Subcommand)] -enum Command { - /// Prints the JSON schema for a theme. - PrintSchema, - /// Converts a VSCode theme to Zed format [default] - Convert { - /// The path to the theme to import. - theme_path: PathBuf, - - /// Whether to warn when values are missing from the theme. - #[arg(long)] - warn_on_missing: bool, - - /// The path to write the output to. - #[arg(long, short)] - output: Option, - }, + /// The path to write the output to. + #[arg(long, short)] + output: Option, } fn main() -> Result<()> { let args = Args::parse(); - match args.command { - Command::PrintSchema => { - let theme_family_schema = schema_for!(ThemeFamilyContent); - println!( - "{}", - serde_json::to_string_pretty(&theme_family_schema).unwrap() - ); - Ok(()) - } - Command::Convert { - theme_path, - warn_on_missing, - output, - } => convert(theme_path, output, warn_on_missing), - } -} - -fn convert(theme_file_path: PathBuf, output: Option, warn_on_missing: bool) -> Result<()> { let log_config = { let mut config = simplelog::ConfigBuilder::new(); - if !warn_on_missing { + + if !args.warn_on_missing { config.add_filter_ignore_str("theme_printer"); } @@ -132,11 +103,13 @@ fn convert(theme_file_path: PathBuf, output: Option, warn_on_missing: b ) .expect("could not initialize logger"); + let theme_file_path = args.theme_path; + let theme_file = match File::open(&theme_file_path) { Ok(file) => file, Err(err) => { log::info!("Failed to open file at path: {:?}", theme_file_path); - return Err(err.into()); + return Err(err)?; } }; @@ -159,7 +132,7 @@ fn convert(theme_file_path: PathBuf, output: Option, warn_on_missing: b ); let theme_json = serde_json::to_string_pretty(&theme).unwrap(); - if let Some(output) = output { + if let Some(output) = args.output { let mut file = File::create(output)?; file.write_all(theme_json.as_bytes())?; } else {