use std::{
env, fs,
path::{Path, PathBuf},
};
use dora_core::manifest::NodeManifest;
use dora_message::descriptor::Descriptor;
use schemars::schema_for;
fn workspace_root(manifest_dir: &Path) -> Option<PathBuf> {
let root = manifest_dir.parent()?.parent()?;
let cargo_toml = fs::read_to_string(root.join("Cargo.toml")).ok()?;
cargo_toml
.contains("[workspace]")
.then(|| root.to_path_buf())
}
fn main() {
let schema = schema_for!(Descriptor);
let raw_schema =
serde_json::to_string_pretty(&schema).expect("Could not serialize schema to json");
let raw_schema = raw_schema.replace(
"\"additionalProperties\": false",
"\"additionalProperties\": true",
);
let raw_schema = raw_schema.replace(
"\"python\": {
\"$ref\": \"#/definitions/PythonSource\"
}",
"",
);
let raw_schema = raw_schema.replace(
"{
\"$ref\": \"#/definitions/Input\"
}",
"true",
);
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is not set");
let manifest_dir = Path::new(&manifest_dir);
let new_file_path = manifest_dir.join("dora-schema.json");
fs::write(new_file_path, &raw_schema).expect("Could not write schema to file");
if let Some(root) = workspace_root(manifest_dir) {
fs::write(root.join("dora-schema.json"), &raw_schema)
.expect("Could not write schema to workspace root");
}
let node_schema = schema_for!(NodeManifest);
let raw_node_schema = serde_json::to_string_pretty(&node_schema)
.expect("Could not serialize node manifest schema to json");
let node_schema_path = manifest_dir.join("dora-node-schema.json");
fs::write(node_schema_path, raw_node_schema)
.expect("Could not write node manifest schema to file");
}
#[cfg(test)]
mod tests {
use super::workspace_root;
use std::{fs, path::Path};
#[test]
fn root_schema_matches_crate_copy() {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let Ok(root_copy) = fs::read_to_string(manifest_dir.join("../../dora-schema.json")) else {
return;
};
assert!(
workspace_root(manifest_dir).is_some(),
"the repo-root `dora-schema.json` exists, but `workspace_root` did \
not recognize the workspace, so `generate_schema` would skip it"
);
let crate_copy = fs::read_to_string(manifest_dir.join("dora-schema.json"))
.expect("libraries/core/dora-schema.json is missing");
assert!(
root_copy == crate_copy,
"the repo-root `dora-schema.json` drifted from \
`libraries/core/dora-schema.json`; run \
`cargo run -p dora-core --bin generate_schema` to rewrite both"
);
}
#[test]
fn workspace_root_rejects_a_plain_package_parent() {
let dir = tempfile::tempdir().unwrap();
let manifest_dir = dir.path().join("libraries/core");
fs::create_dir_all(&manifest_dir).unwrap();
fs::write(
dir.path().join("Cargo.toml"),
"[package]\nname = \"other\"\n",
)
.unwrap();
assert_eq!(workspace_root(&manifest_dir), None);
fs::write(dir.path().join("Cargo.toml"), "[workspace]\nmembers = []\n").unwrap();
assert_eq!(workspace_root(&manifest_dir).as_deref(), Some(dir.path()));
}
}