mirror of
https://github.com/astral-sh/uv.git
synced 2025-09-26 12:09:12 +00:00
Add a generate-all
step and auto-generate settings.md
(#5080)
## Summary Ensures that `generate-all` generates both the JSON Schema and the `settings.md` API reference.
This commit is contained in:
parent
6275b54d51
commit
41cd4bee58
7 changed files with 287 additions and 25 deletions
|
@ -4,9 +4,9 @@ use std::path::PathBuf;
|
|||
use anyhow::{Context, Result};
|
||||
use clap::Parser;
|
||||
use fs_err as fs;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use distribution_types::IndexLocations;
|
||||
use rustc_hash::FxHashMap;
|
||||
use uv_build::{SourceBuild, SourceBuildContext};
|
||||
use uv_cache::{Cache, CacheArgs};
|
||||
use uv_client::RegistryClientBuilder;
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::path::PathBuf;
|
|||
|
||||
use clap::Parser;
|
||||
use tracing::info;
|
||||
|
||||
use uv_cache::{Cache, CacheArgs};
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment, PythonRequest};
|
||||
|
||||
|
|
30
crates/uv-dev/src/generate_all.rs
Normal file
30
crates/uv-dev/src/generate_all.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
//! Run all code and documentation generation steps.
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::{generate_json_schema, generate_options_reference};
|
||||
|
||||
#[derive(clap::Args)]
|
||||
pub(crate) struct Args {
|
||||
#[arg(long, default_value_t, value_enum)]
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, clap::ValueEnum, Default)]
|
||||
pub(crate) 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: &Args) -> Result<()> {
|
||||
generate_json_schema::main(&generate_json_schema::Args { mode: args.mode })?;
|
||||
generate_options_reference::main(&generate_options_reference::Args { mode: args.mode })?;
|
||||
Ok(())
|
||||
}
|
|
@ -9,6 +9,7 @@ use serde::Deserialize;
|
|||
use uv_distribution::pyproject::ToolUv as WorkspaceOptions;
|
||||
use uv_settings::Options as SettingsOptions;
|
||||
|
||||
use crate::generate_all::Mode;
|
||||
use crate::ROOT_DIR;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
|
@ -25,26 +26,13 @@ struct CombinedOptions {
|
|||
}
|
||||
|
||||
#[derive(clap::Args)]
|
||||
pub(crate) struct GenerateJsonSchemaArgs {
|
||||
/// Write the generated table to stdout (rather than to `uv.schema.json`).
|
||||
pub(crate) struct Args {
|
||||
/// Write the generated output to stdout (rather than to `uv.schema.json`).
|
||||
#[arg(long, default_value_t, value_enum)]
|
||||
mode: Mode,
|
||||
pub(crate) 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<()> {
|
||||
pub(crate) fn main(args: &Args) -> Result<()> {
|
||||
let schema = schema_for!(CombinedOptions);
|
||||
let schema_string = serde_json::to_string_pretty(&schema).unwrap();
|
||||
let filename = "uv.schema.json";
|
||||
|
@ -98,9 +86,9 @@ mod tests {
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::generate_json_schema::Mode;
|
||||
use crate::generate_all::Mode;
|
||||
|
||||
use super::{main, GenerateJsonSchemaArgs};
|
||||
use super::{main, Args};
|
||||
|
||||
#[test]
|
||||
fn test_generate_json_schema() -> Result<()> {
|
||||
|
@ -109,6 +97,6 @@ mod tests {
|
|||
} else {
|
||||
Mode::Check
|
||||
};
|
||||
main(&GenerateJsonSchemaArgs { mode })
|
||||
main(&Args { mode })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,12 @@
|
|||
//!
|
||||
//! Based on: <https://github.com/astral-sh/ruff/blob/dc8db1afb08704ad6a788c497068b01edf8b460d/crates/ruff_dev/src/generate_options.rs>
|
||||
use std::fmt::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anstream::println;
|
||||
use anyhow::{bail, Result};
|
||||
use itertools::Itertools;
|
||||
use pretty_assertions::StrComparison;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
|
@ -12,6 +16,9 @@ use uv_macros::OptionsMetadata;
|
|||
use uv_options_metadata::{OptionField, OptionSet, OptionsMetadata, Visit};
|
||||
use uv_settings::Options as SettingsOptions;
|
||||
|
||||
use crate::generate_all::Mode;
|
||||
use crate::ROOT_DIR;
|
||||
|
||||
#[derive(Deserialize, JsonSchema, OptionsMetadata)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[allow(dead_code)]
|
||||
|
@ -25,7 +32,65 @@ struct CombinedOptions {
|
|||
workspace: WorkspaceOptions,
|
||||
}
|
||||
|
||||
pub(crate) fn generate() -> String {
|
||||
#[derive(clap::Args)]
|
||||
pub(crate) struct Args {
|
||||
/// Write the generated output to stdout (rather than to `settings.md`).
|
||||
#[arg(long, default_value_t, value_enum)]
|
||||
pub(crate) mode: Mode,
|
||||
}
|
||||
|
||||
pub(crate) fn main(args: &Args) -> Result<()> {
|
||||
let reference_string = generate();
|
||||
let filename = "settings.md";
|
||||
let reference_path = PathBuf::from(ROOT_DIR).join("docs").join(filename);
|
||||
|
||||
match args.mode {
|
||||
Mode::DryRun => {
|
||||
println!("{reference_string}");
|
||||
}
|
||||
Mode::Check => match fs_err::read_to_string(reference_path) {
|
||||
Ok(current) => {
|
||||
if current == reference_string {
|
||||
println!("Up-to-date: {filename}");
|
||||
} else {
|
||||
let comparison = StrComparison::new(¤t, &reference_string);
|
||||
bail!("{filename} changed, please run `cargo dev generate-options-reference`:\n{comparison}");
|
||||
}
|
||||
}
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||
bail!("{filename} not found, please run `cargo dev generate-options-reference`");
|
||||
}
|
||||
Err(err) => {
|
||||
bail!(
|
||||
"{filename} changed, please run `cargo dev generate-options-reference`:\n{err}"
|
||||
);
|
||||
}
|
||||
},
|
||||
Mode::Write => {
|
||||
match fs_err::read_to_string(&reference_path) {
|
||||
Ok(current) => {
|
||||
if current == reference_string {
|
||||
println!("Up-to-date: {filename}");
|
||||
} else {
|
||||
println!("Updating: {filename}");
|
||||
fs_err::write(reference_path, reference_string.as_bytes())?;
|
||||
}
|
||||
}
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||
println!("Updating: {filename}");
|
||||
fs_err::write(reference_path, reference_string.as_bytes())?;
|
||||
}
|
||||
Err(err) => {
|
||||
bail!("{filename} changed, please run `cargo dev generate-options-reference`:\n{err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate() -> String {
|
||||
let mut output = String::new();
|
||||
|
||||
generate_set(
|
||||
|
@ -219,3 +284,24 @@ impl Visit for CollectOptionsVisitor {
|
|||
self.fields.push((name.to_owned(), field));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::env;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::generate_all::Mode;
|
||||
|
||||
use super::{main, Args};
|
||||
|
||||
#[test]
|
||||
fn test_generate_options_reference() -> Result<()> {
|
||||
let mode = if env::var("UV_UPDATE_SCHEMA").as_deref() == Ok("1") {
|
||||
Mode::Write
|
||||
} else {
|
||||
Mode::Check
|
||||
};
|
||||
main(&Args { mode })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@ use tracing_subscriber::{EnvFilter, Layer};
|
|||
use crate::build::{build, BuildArgs};
|
||||
use crate::clear_compile::ClearCompileArgs;
|
||||
use crate::compile::CompileArgs;
|
||||
use crate::generate_json_schema::GenerateJsonSchemaArgs;
|
||||
use crate::generate_all::Args as GenerateAllArgs;
|
||||
use crate::generate_json_schema::Args as GenerateJsonSchemaArgs;
|
||||
use crate::generate_options_reference::Args as GenerateOptionsReferenceArgs;
|
||||
#[cfg(feature = "render")]
|
||||
use crate::render_benchmarks::RenderBenchmarksArgs;
|
||||
use crate::wheel_metadata::WheelMetadataArgs;
|
||||
|
@ -43,6 +45,7 @@ static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
|
|||
mod build;
|
||||
mod clear_compile;
|
||||
mod compile;
|
||||
mod generate_all;
|
||||
mod generate_json_schema;
|
||||
mod generate_options_reference;
|
||||
mod render_benchmarks;
|
||||
|
@ -60,10 +63,12 @@ enum Cli {
|
|||
Compile(CompileArgs),
|
||||
/// Remove all `.pyc` in the tree.
|
||||
ClearCompile(ClearCompileArgs),
|
||||
/// Run all code and documentation generation steps.
|
||||
GenerateAll(GenerateAllArgs),
|
||||
/// Generate JSON schema for the TOML configuration file.
|
||||
GenerateJSONSchema(GenerateJsonSchemaArgs),
|
||||
/// Generate the options reference for the documentation.
|
||||
GenerateOptionsReference,
|
||||
GenerateOptionsReference(GenerateOptionsReferenceArgs),
|
||||
#[cfg(feature = "render")]
|
||||
/// Render the benchmarks.
|
||||
RenderBenchmarks(RenderBenchmarksArgs),
|
||||
|
@ -80,8 +85,9 @@ async fn run() -> Result<()> {
|
|||
Cli::WheelMetadata(args) => wheel_metadata::wheel_metadata(args).await?,
|
||||
Cli::Compile(args) => compile::compile(args).await?,
|
||||
Cli::ClearCompile(args) => clear_compile::clear_compile(&args)?,
|
||||
Cli::GenerateAll(args) => generate_all::main(&args)?,
|
||||
Cli::GenerateJSONSchema(args) => generate_json_schema::main(&args)?,
|
||||
Cli::GenerateOptionsReference => println!("{}", generate_options_reference::generate()),
|
||||
Cli::GenerateOptionsReference(args) => generate_options_reference::main(&args)?,
|
||||
#[cfg(feature = "render")]
|
||||
Cli::RenderBenchmarks(args) => render_benchmarks::render_benchmarks(&args)?,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue