mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Add JSON Schema support (#3046)
## Summary This PR adds JSON Schema support. The setup mirrors Ruff's own.
This commit is contained in:
parent
7c5b13c412
commit
7fb2bf816f
31 changed files with 818 additions and 26 deletions
|
@ -33,6 +33,7 @@ uv-normalize = { workspace = true }
|
|||
uv-resolver = { workspace = true }
|
||||
uv-toolchain = { workspace = true }
|
||||
uv-types = { workspace = true }
|
||||
uv-workspace = { workspace = true, features = ["schemars"] }
|
||||
|
||||
# Any dependencies that are exclusively used in `uv-dev` should be listed as non-workspace
|
||||
# dependencies, to ensure that we're forced to think twice before including them in other crates.
|
||||
|
@ -47,8 +48,10 @@ itertools = { workspace = true }
|
|||
owo-colors = { workspace = true }
|
||||
petgraph = { workspace = true }
|
||||
poloto = { version = "19.1.2" }
|
||||
pretty_assertions = { version = "1.4.0" }
|
||||
resvg = { version = "0.29.0" }
|
||||
rustc-hash = { workspace = true }
|
||||
schemars = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tagu = { version = "0.1.6" }
|
||||
|
|
99
crates/uv-dev/src/generate_json_schema.rs
Normal file
99
crates/uv-dev/src/generate_json_schema.rs
Normal file
|
@ -0,0 +1,99 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use anstream::println;
|
||||
use anyhow::{bail, Result};
|
||||
use pretty_assertions::StrComparison;
|
||||
use schemars::schema_for;
|
||||
|
||||
use uv_workspace::Options;
|
||||
|
||||
use crate::ROOT_DIR;
|
||||
|
||||
#[derive(clap::Args)]
|
||||
pub(crate) struct GenerateJsonSchemaArgs {
|
||||
/// Write the generated table to stdout (rather than to `uv.schema.json`).
|
||||
#[arg(long, default_value_t, value_enum)]
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, clap::ValueEnum, Default)]
|
||||
enum Mode {
|
||||
/// Update the content in the `configuration.md`.
|
||||
#[default]
|
||||
Write,
|
||||
|
||||
/// Don't write to the file, check if the file is up-to-date and error if not.
|
||||
Check,
|
||||
|
||||
/// Write the generated help to stdout.
|
||||
DryRun,
|
||||
}
|
||||
|
||||
pub(crate) fn main(args: &GenerateJsonSchemaArgs) -> Result<()> {
|
||||
let schema = schema_for!(Options);
|
||||
let schema_string = serde_json::to_string_pretty(&schema).unwrap();
|
||||
let filename = "uv.schema.json";
|
||||
let schema_path = PathBuf::from(ROOT_DIR).join(filename);
|
||||
|
||||
match args.mode {
|
||||
Mode::DryRun => {
|
||||
println!("{schema_string}");
|
||||
}
|
||||
Mode::Check => match fs_err::read_to_string(schema_path) {
|
||||
Ok(current) => {
|
||||
if current == schema_string {
|
||||
println!("Up-to-date: {filename}");
|
||||
} else {
|
||||
let comparison = StrComparison::new(¤t, &schema_string);
|
||||
bail!("{filename} changed, please run `cargo dev generate-json-schema`:\n{comparison}");
|
||||
}
|
||||
}
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||
bail!("{filename} not found, please run `cargo dev generate-json-schema`");
|
||||
}
|
||||
Err(err) => {
|
||||
bail!("{filename} changed, please run `cargo dev generate-json-schema`:\n{err}");
|
||||
}
|
||||
},
|
||||
Mode::Write => match fs_err::read_to_string(&schema_path) {
|
||||
Ok(current) => {
|
||||
if current == schema_string {
|
||||
println!("Up-to-date: {filename}");
|
||||
} else {
|
||||
println!("Updating: {filename}");
|
||||
fs_err::write(schema_path, schema_string.as_bytes())?;
|
||||
}
|
||||
}
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||
println!("Updating: {filename}");
|
||||
fs_err::write(schema_path, schema_string.as_bytes())?;
|
||||
}
|
||||
Err(err) => {
|
||||
bail!("{filename} changed, please run `cargo dev generate-json-schema`:\n{err}");
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::env;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::generate_json_schema::Mode;
|
||||
|
||||
use super::{main, GenerateJsonSchemaArgs};
|
||||
|
||||
#[test]
|
||||
fn test_generate_json_schema() -> Result<()> {
|
||||
let mode = if env::var("UV_UPDATE_SCHEMA").as_deref() == Ok("1") {
|
||||
Mode::Write
|
||||
} else {
|
||||
Mode::Check
|
||||
};
|
||||
main(&GenerateJsonSchemaArgs { mode })
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ use crate::build::{build, BuildArgs};
|
|||
use crate::clear_compile::ClearCompileArgs;
|
||||
use crate::compile::CompileArgs;
|
||||
use crate::fetch_python::FetchPythonArgs;
|
||||
use crate::generate_json_schema::GenerateJsonSchemaArgs;
|
||||
use crate::render_benchmarks::RenderBenchmarksArgs;
|
||||
use crate::resolve_cli::ResolveCliArgs;
|
||||
use crate::wheel_metadata::WheelMetadataArgs;
|
||||
|
@ -46,11 +47,14 @@ mod build;
|
|||
mod clear_compile;
|
||||
mod compile;
|
||||
mod fetch_python;
|
||||
mod generate_json_schema;
|
||||
mod render_benchmarks;
|
||||
mod resolve_cli;
|
||||
mod resolve_many;
|
||||
mod wheel_metadata;
|
||||
|
||||
const ROOT_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../");
|
||||
|
||||
#[derive(Parser)]
|
||||
enum Cli {
|
||||
/// Build a source distribution into a wheel
|
||||
|
@ -76,6 +80,8 @@ enum Cli {
|
|||
ClearCompile(ClearCompileArgs),
|
||||
/// Fetch Python versions for testing
|
||||
FetchPython(FetchPythonArgs),
|
||||
/// Generate JSON schema for the TOML configuration file.
|
||||
GenerateJSONSchema(GenerateJsonSchemaArgs),
|
||||
}
|
||||
|
||||
#[instrument] // Anchor span to check for overhead
|
||||
|
@ -97,6 +103,7 @@ async fn run() -> Result<()> {
|
|||
Cli::Compile(args) => compile::compile(args).await?,
|
||||
Cli::ClearCompile(args) => clear_compile::clear_compile(&args)?,
|
||||
Cli::FetchPython(args) => fetch_python::fetch_python(args).await?,
|
||||
Cli::GenerateJSONSchema(args) => generate_json_schema::main(&args)?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue