Skip to content

Commit fa75c4d

Browse files
authored
Merge pull request #4 from dev-five-git/add-schema-url
Add schema url
2 parents 0222359 + 3849529 commit fa75c4d

2 files changed

Lines changed: 50 additions & 8 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"changes":{"crates/vespertide-cli/Cargo.toml":"Patch","crates/vespertide/Cargo.toml":"Patch","crates/vespertide-query/Cargo.toml":"Patch","crates/vespertide-core/Cargo.toml":"Patch","crates/vespertide-macro/Cargo.toml":"Patch","crates/vespertide-planner/Cargo.toml":"Patch","crates/vespertide-config/Cargo.toml":"Patch"},"note":"Add schema url","date":"2025-12-10T16:14:12.908628500Z"}

crates/vespertide-cli/src/commands/revision.rs

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ use std::fs;
33
use anyhow::{Context, Result};
44
use chrono::Utc;
55
use colored::Colorize;
6+
use serde_json::Value;
7+
use vespertide_config::FileFormat;
8+
use vespertide_core::MigrationPlan;
69
use vespertide_planner::plan_next_migration;
710

811
use crate::utils::{
@@ -46,14 +49,11 @@ pub fn cmd_revision(message: String) -> Result<()> {
4649
);
4750
let path = migrations_dir.join(&filename);
4851

49-
let text = match format {
50-
vespertide_config::FileFormat::Json => {
51-
serde_json::to_string_pretty(&plan).context("serialize migration plan")?
52-
}
53-
_ => serde_yaml::to_string(&plan).context("serialize migration plan")?,
54-
};
55-
56-
fs::write(&path, text).with_context(|| format!("write migration file: {}", path.display()))?;
52+
let schema_url = schema_url_for(format);
53+
match format {
54+
FileFormat::Json => write_json_with_schema(&path, &plan, &schema_url)?,
55+
FileFormat::Yaml | FileFormat::Yml => write_yaml(&path, &plan, &schema_url)?,
56+
}
5757

5858
println!(
5959
"{} {}",
@@ -77,6 +77,47 @@ pub fn cmd_revision(message: String) -> Result<()> {
7777
Ok(())
7878
}
7979

80+
fn schema_url_for(format: FileFormat) -> String {
81+
// If not set, default to public raw GitHub schema location.
82+
// Users can override via VESP_SCHEMA_BASE_URL.
83+
let base = std::env::var("VESP_SCHEMA_BASE_URL").ok();
84+
let base = base.as_deref().unwrap_or(
85+
"https://raw.githubusercontent.com/dev-five-git/vespertide/refs/heads/main/schemas",
86+
);
87+
let base = base.trim_end_matches('/');
88+
match format {
89+
FileFormat::Json => format!("{}/migration.schema.json", base),
90+
FileFormat::Yaml | FileFormat::Yml => format!("{}/migration.schema.json", base),
91+
}
92+
}
93+
94+
fn write_json_with_schema(
95+
path: &std::path::Path,
96+
plan: &MigrationPlan,
97+
schema_url: &str,
98+
) -> Result<()> {
99+
let mut value = serde_json::to_value(plan).context("serialize migration plan to json")?;
100+
if let Value::Object(ref mut map) = value {
101+
map.insert("$schema".to_string(), Value::String(schema_url.to_string()));
102+
}
103+
let text = serde_json::to_string_pretty(&value).context("stringify json with schema")?;
104+
fs::write(path, text).with_context(|| format!("write file: {}", path.display()))?;
105+
Ok(())
106+
}
107+
108+
fn write_yaml(path: &std::path::Path, plan: &MigrationPlan, schema_url: &str) -> Result<()> {
109+
let mut value = serde_yaml::to_value(plan).context("serialize migration plan to yaml value")?;
110+
if let serde_yaml::Value::Mapping(ref mut map) = value {
111+
map.insert(
112+
serde_yaml::Value::String("$schema".to_string()),
113+
serde_yaml::Value::String(schema_url.to_string()),
114+
);
115+
}
116+
let text = serde_yaml::to_string(&value).context("serialize yaml with schema")?;
117+
fs::write(path, text).with_context(|| format!("write file: {}", path.display()))?;
118+
Ok(())
119+
}
120+
80121
#[cfg(test)]
81122
mod tests {
82123
use super::*;

0 commit comments

Comments
 (0)