Skip to content

Commit

Permalink
Add JSON schema generation as a hidden CLI command
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanPlasse committed Mar 24, 2024
1 parent 2b7128b commit 9b4d0f9
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 25 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ wild = { version = "2.1.0", optional = true }

# JSON schema
schemars = { version = "0.8.16", optional = true }
pretty_assertions = { version = "1.3.0", optional = true }

[dev-dependencies]
expect-test = "1.4.1"
Expand Down Expand Up @@ -161,7 +162,7 @@ upload = [
"dep:dirs",
]

schemars = ["dep:schemars"]
schemars = ["dep:schemars", "dep:pretty_assertions"]

# keyring doesn't support *BSD so it's not enabled in `full` by default
password-storage = ["upload", "keyring"]
Expand Down
24 changes: 0 additions & 24 deletions src/bin/generate_json_schema.rs

This file was deleted.

63 changes: 63 additions & 0 deletions src/generate_json_schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#![cfg(feature = "schemars")]
use std::fs;
use std::path::PathBuf;

use anyhow::{bail, Result};
use pretty_assertions::StrComparison;
use schemars::schema_for;

use crate::pyproject_toml::ToolMaturin;

#[derive(Debug, Copy, Clone, PartialEq, Eq, clap::ValueEnum, Default)]
/// The mode to use when generating the JSON schema.
pub enum Mode {
/// Write the JSON schema to the file.
#[default]
Write,
/// Check if the JSON schema is up-to-date.
Check,
/// Print the JSON schema to stdout.
DryRun,
}

/// Generate the JSON schema for the `pyproject.toml` file.
#[derive(Debug, clap::Parser)]
pub struct GenerateJsonSchemaOptions {
/// The mode to use when generating the JSON schema.
#[arg(long, default_value_t, value_enum)]
pub mode: Mode,
}

/// Generate the JSON schema for the `pyproject.toml` file.
pub fn generate_json_schema(args: GenerateJsonSchemaOptions) -> Result<()> {
let schema = schema_for!(ToolMaturin);
let schema_string = serde_json::to_string_pretty(&schema).unwrap();
let filename = "maturin.schema.json";
let schema_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(filename);

match args.mode {
Mode::DryRun => {
println!("{schema_string}");
}
Mode::Check => {
let current = fs::read_to_string(schema_path)?;
if current == schema_string {
println!("Up-to-date: {filename}");
} else {
let comparison = StrComparison::new(&current, &schema_string);
bail!("{filename} changed, please run `cargo run --features schemars -- generate-json-schema`:\n{comparison}",);
}
}
Mode::Write => {
let current = fs::read_to_string(&schema_path)?;
if current == schema_string {
println!("Up-to-date: {filename}");
} else {
println!("Updating: {filename}");
fs::write(schema_path, schema_string.as_bytes())?;
}
}
}

Ok(())
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub use crate::build_options::{BuildOptions, CargoOptions};
pub use crate::cargo_toml::CargoToml;
pub use crate::compile::{compile, BuildArtifact};
pub use crate::develop::{develop, DevelopOptions};
#[cfg(feature = "schemars")]
pub use crate::generate_json_schema::{generate_json_schema, GenerateJsonSchemaOptions, Mode};
pub use crate::metadata::{Metadata23, WheelMetadata};
pub use crate::module_writer::{
write_dist_info, ModuleWriter, PathWriter, SDistWriter, WheelWriter,
Expand All @@ -51,6 +53,7 @@ pub mod ci;
mod compile;
mod cross_compile;
mod develop;
mod generate_json_schema;
mod metadata;
mod module_writer;
#[cfg(feature = "scaffolding")]
Expand Down
8 changes: 8 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use maturin::{
develop, write_dist_info, BridgeModel, BuildOptions, CargoOptions, DevelopOptions, PathWriter,
PlatformTag, PythonInterpreter, Target,
};
#[cfg(feature = "schemars")]
use maturin::{generate_json_schema, GenerateJsonSchemaOptions};
#[cfg(feature = "upload")]
use maturin::{upload_ui, PublishOpt};
use std::env;
Expand Down Expand Up @@ -141,6 +143,10 @@ enum Opt {
#[cfg(feature = "zig")]
#[command(subcommand, hide = true)]
Zig(Zig),
/// Generate the JSON schema for the `pyproject.toml` file.
#[cfg(feature = "schemars")]
#[command(name = "generate-json-schema", hide = true)]
GenerateJsonSchema(GenerateJsonSchemaOptions),
}

/// Backend for the PEP 517 integration. Not for human consumption
Expand Down Expand Up @@ -425,6 +431,8 @@ fn run() -> Result<()> {
.execute()
.context("Failed to run zig linker wrapper")?;
}
#[cfg(feature = "schemars")]
Opt::GenerateJsonSchema(args) => generate_json_schema(args)?,
}

Ok(())
Expand Down

0 comments on commit 9b4d0f9

Please sign in to comment.