mirror of
https://github.com/ClementTsang/bottom.git
synced 2026-08-24 12:26:54 +00:00
other: move schema_gen script to scripts folder (#2183)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
target/
|
||||
Generated
+1875
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
@@ -0,0 +1,3 @@
|
||||
# schema_gen
|
||||
|
||||
This is just a tool to automatically generate [JSON Schema](https://json-schema.org/) for bottom's config.
|
||||
@@ -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(())
|
||||
}
|
||||
Reference in New Issue
Block a user