mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +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)?,
|
||||
}
|
||||
|
|
151
docs/settings.md
Normal file
151
docs/settings.md
Normal file
|
@ -0,0 +1,151 @@
|
|||
### Global
|
||||
##### [`index-url`](#index-url) {: #index-url }
|
||||
|
||||
The URL of the Python package index (by default: <https://pypi.org/simple>).
|
||||
|
||||
Accepts either a repository compliant with PEP 503 (the simple repository API), or a local
|
||||
directory laid out in the same format.
|
||||
|
||||
The index provided by this setting is given lower priority than any indexes specified via
|
||||
[`extra_index_url`](#extra-index-url).
|
||||
|
||||
**Default value**: `https://pypi.org/simple`
|
||||
|
||||
**Type**: `str`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.uv]
|
||||
index-url = "https://pypi.org/simple"
|
||||
```
|
||||
=== "uv.toml"
|
||||
|
||||
```toml
|
||||
|
||||
index-url = "https://pypi.org/simple"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
##### [`managed`](#managed) {: #managed }
|
||||
|
||||
Whether the project is managed by `uv`. If `false`, `uv` will ignore the project when
|
||||
`uv run` is invoked.
|
||||
|
||||
**Default value**: `true`
|
||||
|
||||
**Type**: `bool`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.uv]
|
||||
managed = false
|
||||
```
|
||||
=== "uv.toml"
|
||||
|
||||
```toml
|
||||
|
||||
managed = false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### `pip`
|
||||
|
||||
A `[tool.uv.pip]` section.
|
||||
|
||||
##### [`no-header`](#pip_no-header) {: #pip_no-header }
|
||||
<span id="no-header"></span>
|
||||
|
||||
Exclude the comment header at the top of output file generated by `uv pip compile`.
|
||||
|
||||
**Default value**: `false`
|
||||
|
||||
**Type**: `bool`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.uv.pip]
|
||||
no-header = true
|
||||
```
|
||||
=== "uv.toml"
|
||||
|
||||
```toml
|
||||
[pip]
|
||||
no-header = true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### `workspace`
|
||||
|
||||
##### [`exclude`](#workspace_exclude) {: #workspace_exclude }
|
||||
<span id="exclude"></span>
|
||||
|
||||
Packages to exclude as workspace members. If a package matches both `members` and
|
||||
`exclude`, it will be excluded.
|
||||
|
||||
Supports both globs and explicit paths.
|
||||
|
||||
For more information on the glob syntax, refer to the [`glob` documentation](https://docs.rs/glob/latest/glob/struct.Pattern.html).
|
||||
|
||||
**Default value**: `[]`
|
||||
|
||||
**Type**: `list[str]`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.uv.workspace]
|
||||
exclude = ["member1", "path/to/member2", "libs/*"]
|
||||
```
|
||||
=== "uv.toml"
|
||||
|
||||
```toml
|
||||
[workspace]
|
||||
exclude = ["member1", "path/to/member2", "libs/*"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
##### [`members`](#workspace_members) {: #workspace_members }
|
||||
<span id="members"></span>
|
||||
|
||||
Packages to include as workspace members.
|
||||
|
||||
Supports both globs and explicit paths.
|
||||
|
||||
For more information on the glob syntax, refer to the [`glob` documentation](https://docs.rs/glob/latest/glob/struct.Pattern.html).
|
||||
|
||||
**Default value**: `[]`
|
||||
|
||||
**Type**: `list[str]`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.uv.workspace]
|
||||
members = ["member1", "path/to/member2", "libs/*"]
|
||||
```
|
||||
=== "uv.toml"
|
||||
|
||||
```toml
|
||||
[workspace]
|
||||
members = ["member1", "path/to/member2", "libs/*"]
|
||||
```
|
||||
|
||||
---
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue