Skip to content

Commit

Permalink
docs: separate project from configuration settings (#7053)
Browse files Browse the repository at this point in the history
<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

Part of #7007.

Settings documentation reference currently doesn't separate "project
metadata" and "configuration" options, implying that it's possible to
set things like `dev-dependencies` in `uv.toml` while it's not. This is
an attempt at better separating those options, by having 2 different
sections:
- `Project metadata`, that holds configuration that can only be set in
`pyproject.toml`
- `Configuration`, that holds configuration that can be set both in
`pyproject.toml` and `uv.toml`

Here are some screenshots to show what this looks like (note that I
don't have code highlighting in the right navigation, which makes them
clunky, as first item is always bigger because of the missing "span" --
I think that's because it's an `mkdocs-material` insider feature, since
I have the same thing on `main` branch):

- Right side navigation:

<img width="241" alt="Screenshot 2024-09-05 at 01 19 50"
src="https://github.com/user-attachments/assets/012f64a4-8d34-4e34-a506-8d02dc1fbf98">

<img width="223" alt="Screenshot 2024-09-05 at 01 20 01"
src="https://github.com/user-attachments/assets/0b0fb71d-c9c3-4ee3-8f6e-cf35180b1a99">

- An option from "Project metadata" section that only applies to
`pyproject.toml`:

<img width="788" alt="Screenshot 2024-09-05 at 01 20 11"
src="https://github.com/user-attachments/assets/64349fbb-8623-4b81-a475-d6ff38c658f1">

- An option from "Configuration" section that applies both to
`pyproject.toml` and `uv.toml`:

<img width="787" alt="Screenshot 2024-09-05 at 01 20 33"
src="https://github.com/user-attachments/assets/732e43d3-cc64-4f5a-8929-23a5555d4c53">

## Test Plan

Local run of the documentation.

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
  • Loading branch information
mkniewallner and charliermarsh committed Sep 14, 2024
1 parent 54f171c commit 211fa91
Show file tree
Hide file tree
Showing 2 changed files with 304 additions and 322 deletions.
88 changes: 69 additions & 19 deletions crates/uv-dev/src/generate_options_reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,29 @@ pub(crate) fn main(args: &Args) -> Result<()> {
Ok(())
}

enum OptionType {
Configuration,
ProjectMetadata,
}

fn generate() -> String {
let mut output = String::new();

generate_set(
&mut output,
Set::Global(CombinedOptions::metadata()),
Set::Global {
set: WorkspaceOptions::metadata(),
option_type: OptionType::ProjectMetadata,
},
&mut Vec::new(),
);

generate_set(
&mut output,
Set::Global {
set: SettingsOptions::metadata(),
option_type: OptionType::Configuration,
},
&mut Vec::new(),
);

Expand All @@ -107,16 +124,20 @@ fn generate() -> String {

fn generate_set(output: &mut String, set: Set, parents: &mut Vec<Set>) {
match &set {
Set::Global(_) => {
output.push_str("## Global\n");
Set::Global { option_type, .. } => {
let header = match option_type {
OptionType::Configuration => "## Configuration\n",
OptionType::ProjectMetadata => "## Project metadata\n",
};
output.push_str(header);
}
Set::Named { name, .. } => {
let title = parents
.iter()
.filter_map(|set| set.name())
.chain(std::iter::once(name.as_str()))
.join(".");
writeln!(output, "## `{title}`\n").unwrap();
writeln!(output, "### `{title}`\n").unwrap();

if let Some(documentation) = set.metadata().documentation() {
output.push_str(documentation);
Expand Down Expand Up @@ -158,28 +179,34 @@ fn generate_set(output: &mut String, set: Set, parents: &mut Vec<Set>) {
}

enum Set {
Global(OptionSet),
Named { name: String, set: OptionSet },
Global {
option_type: OptionType,
set: OptionSet,
},
Named {
name: String,
set: OptionSet,
},
}

impl Set {
fn name(&self) -> Option<&str> {
match self {
Set::Global(_) => None,
Set::Global { .. } => None,
Set::Named { name, .. } => Some(name),
}
}

fn metadata(&self) -> &OptionSet {
match self {
Set::Global(set) => set,
Set::Global { set, .. } => set,
Set::Named { set, .. } => set,
}
}
}

fn emit_field(output: &mut String, name: &str, field: &OptionField, parents: &[Set]) {
let header_level = if parents.is_empty() { "###" } else { "####" };
let header_level = if parents.len() > 1 { "####" } else { "###" };
let parents_anchor = parents.iter().filter_map(|parent| parent.name()).join("_");

if parents_anchor.is_empty() {
Expand Down Expand Up @@ -233,16 +260,35 @@ fn emit_field(output: &mut String, name: &str, field: &OptionField, parents: &[S
}
output.push('\n');
output.push_str("**Example usage**:\n\n");
output.push_str(&format_tab(
"pyproject.toml",
&format_header(field.scope, parents, ConfigurationFile::PyprojectToml),
field.example,
));
output.push_str(&format_tab(
"uv.toml",
&format_header(field.scope, parents, ConfigurationFile::UvToml),
field.example,
));

match parents[0] {
Set::Global {
option_type: OptionType::ProjectMetadata,
..
} => {
output.push_str(&format_code(
"pyproject.toml",
&format_header(field.scope, parents, ConfigurationFile::PyprojectToml),
field.example,
));
}
Set::Global {
option_type: OptionType::Configuration,
..
} => {
output.push_str(&format_tab(
"pyproject.toml",
&format_header(field.scope, parents, ConfigurationFile::PyprojectToml),
field.example,
));
output.push_str(&format_tab(
"uv.toml",
&format_header(field.scope, parents, ConfigurationFile::UvToml),
field.example,
));
}
_ => {}
}
output.push('\n');
}

Expand All @@ -255,6 +301,10 @@ fn format_tab(tab_name: &str, header: &str, content: &str) -> String {
)
}

fn format_code(file_name: &str, header: &str, content: &str) -> String {
format!("```toml title=\"{file_name}\"\n{header}\n{content}\n```\n")
}

/// Format the TOML header for the example usage for a given option.
///
/// For example: `[tool.uv.pip]`.
Expand Down
Loading

0 comments on commit 211fa91

Please sign in to comment.