use crate::config;
use anyhow::Context;
use schemars::schema_for;
use std::fs;
use std::path::Path;
const FOLDER: &str = ".schema";
const FILE: &str = "latest.json";
pub fn generate_schema_to_disk() -> anyhow::Result<()> {
let file_path = Path::new(FOLDER).join(FILE);
let json = generate_schema_json().context("can't generate schema")?;
fs::create_dir_all(FOLDER).with_context(|| format!("can't create folder {FOLDER:?}"))?;
fs::write(&file_path, json).with_context(|| format!("can't write schema in {file_path:?}"))?;
Ok(())
}
fn generate_schema_json() -> anyhow::Result<String> {
const SCHEMA_TOKEN: &str = r##"schema#","##;
const ID: &str = r##""$id": "https://github.com/MarcoIeni/release-plz/"##;
let schema = schema_for!(config::Config);
let mut json =
serde_json::to_string_pretty(&schema).context("can't convert schema to string")?;
json = json.replace(
SCHEMA_TOKEN,
&format!("{}\n {}{}/{}\",", SCHEMA_TOKEN, ID, FOLDER, FILE),
);
Ok(json)
}
#[cfg(test)]
mod tests {
use crate::generate_schema::{generate_schema_json, FILE, FOLDER};
use pretty_assertions::assert_eq;
use std::path::Path;
use std::{env, fs};
#[test]
fn schema_is_up_to_date() {
let output = std::process::Command::new(env!("CARGO"))
.arg("locate-project")
.arg("--workspace")
.arg("--message-format=plain")
.output()
.unwrap()
.stdout;
let workspace_path = Path::new(std::str::from_utf8(&output).unwrap().trim())
.parent()
.unwrap();
let file_path = workspace_path.join(FOLDER).join(FILE);
let existing_json: String = fs::read_to_string(file_path).unwrap();
let new_json = generate_schema_json().unwrap();
assert_eq!(
existing_json.replace("\r\n", "\n"),
new_json.replace("\r\n", "\n"),
"(Hint: if change is intentional run `cargo run -- generate-schema` to update schema.)"
);
}
}