other: move schema_gen script to scripts folder (#2183)

This commit is contained in:
Clement Tsang
2026-08-06 03:54:45 -04:00
committed by GitHub
parent 836ec5bf7f
commit a27a42f9f2
12 changed files with 13 additions and 16 deletions
+1 -1
View File
@@ -6,4 +6,4 @@ cd "$(dirname "$0")";
cd ../..
mkdir -p schema/v$1
cargo run --manifest-path tools/schema_gen/Cargo.toml -- $1 > schema/v$1/bottom.json
cargo run --manifest-path scripts/schema_gen/Cargo.toml -- $1 > schema/v$1/bottom.json
+1 -1
View File
@@ -5,4 +5,4 @@ set -e
cd "$(dirname "$0")";
cd ../..
cargo run --manifest-path tools/schema_gen/Cargo.toml > schema/nightly/bottom.json
cargo run --manifest-path scripts/schema_gen/Cargo.toml > schema/nightly/bottom.json
+1
View File
@@ -0,0 +1 @@
target/
+1875
View File
File diff suppressed because it is too large Load Diff
+27
View File
@@ -0,0 +1,27 @@
[package]
name = "schema_gen"
version = "0.1.0"
edition = "2024"
publish = false
[dependencies]
anyhow = "1.0.101"
bottom = { path = "../../", features = ["generate_schema"] }
clap = { version = "4.5.57", features = ["derive"] }
itertools = "0.15.0"
schemars = "1.2.1"
serde_json = "1.0.149"
strum = { version = "0.27.2", features = ["derive"] }
[lints.rust]
rust_2018_idioms = "deny"
[lints.rustdoc]
broken_intra_doc_links = "deny"
private_intra_doc_links = "deny"
[lints.clippy]
todo = "deny"
unimplemented = "deny"
missing_safety_doc = "deny"
unwrap_used = "deny"
+3
View File
@@ -0,0 +1,3 @@
# schema_gen
This is just a tool to automatically generate [JSON Schema](https://json-schema.org/) for bottom's config.
+103
View File
@@ -0,0 +1,103 @@
#![expect(
clippy::unwrap_used,
reason = "this is just used to generate jsonschema files"
)]
use bottom::{options::config, widgets};
use clap::Parser;
use itertools::Itertools;
use serde_json::Value;
use strum::VariantArray;
#[derive(Parser)]
struct SchemaOptions {
/// The version of the schema.
version: Option<String>,
}
macro_rules! generate_column_schemas {
($struct_name:literal, $variants:expr, $schema:expr) => {
match $schema
.as_object_mut()
.unwrap()
.get_mut("$defs")
.unwrap()
.get_mut($struct_name)
.unwrap()
{
Value::Object(original) => {
let enums = original.get_mut("enum").unwrap();
*enums = $variants
.iter()
.flat_map(|variant| variant.get_schema_names())
.flat_map(|variant| [variant.to_string(), variant.to_lowercase()])
.sorted() // Remember that dedup only works if it's sorted...
.dedup()
.map(|variant| serde_json::Value::String(variant)) // Have to do it after as it doesn't implement partialeq/eq
.collect();
Ok(())
}
_ => Err(anyhow::anyhow!("missing proc columns definition")),
}
};
}
fn generate_schema(schema_options: SchemaOptions) -> anyhow::Result<()> {
let mut schema = schemars::schema_for!(config::Config);
{
// TODO: Maybe make this case insensitive? See https://stackoverflow.com/a/68639341
generate_column_schemas!("ProcColumn", widgets::ProcColumn::VARIANTS, schema)?;
generate_column_schemas!(
"DiskWidgetColumn",
widgets::DiskWidgetColumn::VARIANTS,
schema
)?;
generate_column_schemas!(
"TempWidgetColumn",
widgets::TempWidgetColumn::VARIANTS,
schema
)?;
}
let version = schema_options.version.unwrap_or("nightly".to_string());
schema.insert(
"$id".into(),
format!("https://github.com/ClementTsang/bottom/blob/main/schema/{version}/bottom.json")
.into(),
);
schema.insert(
"description".into(),
format!(
"https://bottom.pages.dev/{}/configuration/config-file/",
if version == "nightly" {
"nightly"
} else {
version.as_str()
}
)
.into(),
);
let description_version = if version == "nightly" {
"nightly".to_string()
} else {
format!("v{version}")
};
schema.insert(
"title".into(),
format!("Schema for bottom's config file ({description_version})").into(),
);
println!("{}", serde_json::to_string_pretty(&schema).unwrap());
Ok(())
}
fn main() -> anyhow::Result<()> {
let schema_options = SchemaOptions::parse();
generate_schema(schema_options)?;
Ok(())
}