Use inline table for dependencies in lockfile (#4581)
Use indented inline tables for `distribution.dependencies`, `distribution.optional-dependencies` and `distribution.dev-dependencies`. The new style is more concise (see examples below) and it makes the association between a distribution and its dependencies clearer (previously, they were both individual `[[...]]` blocks separated by newlines). The style is optimized for small, meaningful diffs by placing each dependency on a single line with a final trailing comma. Whenever a dependency is added, removed or changed, there should be a one line diff in `distribution.dependencies`. The final trailing comma ensures that adding a dependency doesn't change the line ahead. Part of #3611 ## Examples ### Simple workspace package Before: ```toml [[distribution]] name = "bird-feeder" version = "1.0.0" source = "editable+packages/bird-feeder" [[distribution.dependencies]] name = "anyio" [[distribution.dependencies]] name = "seeds" ``` After: ```toml [[distribution]] name = "bird-feeder" version = "1.0.0" source = "editable+packages/bird-feeder" dependencies = [ { name = "anyio" }, { name = "seeds" }, ] ``` ### Flask Before: ```toml [[distribution]] name = "flask" version = "3.0.2" source = "registry+https://pypi.org/simple" sdist = { url = "https://files.pythonhosted.org/packages/3f/e0/a89e8120faea1edbfca1a9b171cff7f2bf62ec860bbafcb2c2387c0317be/flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d", size = 675248 } wheels = [{ url = "https://files.pythonhosted.org/packages/93/a6/aa98bfe0eb9b8b15d36cdfd03c8ca86a03968a87f27ce224fb4f766acb23/flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e", size = 101300 }] [[distribution.dependencies]] name = "blinker" [[distribution.dependencies]] name = "click" [[distribution.dependencies]] name = "itsdangerous" [[distribution.dependencies]] name = "jinja2" [[distribution.dependencies]] name = "werkzeug" [distribution.optional-dependencies] [[distribution.optional-dependencies.dotenv]] name = "python-dotenv" ``` After: ```toml [[distribution]] name = "flask" version = "3.0.2" source = "registry+https://pypi.org/simple" sdist = { url = "https://files.pythonhosted.org/packages/3f/e0/a89e8120faea1edbfca1a9b171cff7f2bf62ec860bbafcb2c2387c0317be/flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d", size = 675248 } dependencies = [ { name = "blinker" }, { name = "click" }, { name = "itsdangerous" }, { name = "jinja2" }, { name = "werkzeug" }, ] wheels = [{ url = "https://files.pythonhosted.org/packages/93/a6/aa98bfe0eb9b8b15d36cdfd03c8ca86a03968a87f27ce224fb4f766acb23/flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e", size = 101300 }] [distribution.optional-dependencies] dotenv = [ { name = "python-dotenv" }, ] ``` ### Forking Before: ```toml [[distribution]] name = "project" version = "0.1.0" source = "editable+." [[distribution.dependencies]] name = "package-a" version = "4.3.0" source = "registry+https://astral-sh.github.io/packse/0.3.29/simple-html/" marker = "sys_platform == 'darwin'" [[distribution.dependencies]] name = "package-a" version = "4.4.0" source = "registry+https://astral-sh.github.io/packse/0.3.29/simple-html/" marker = "sys_platform == 'linux'" [[distribution.dependencies]] name = "package-b" marker = "sys_platform == 'linux'" [[distribution.dependencies]] name = "package-c" marker = "sys_platform == 'darwin'" ``` After: ```toml [[distribution]] name = "project" version = "0.1.0" source = "editable+." dependencies = [ { name = "package-a", version = "4.3.0", source = "registry+https://astral-sh.github.io/packse/0.3.29/simple-html/", marker = "sys_platform == 'darwin'" }, { name = "package-a", version = "4.4.0", source = "registry+https://astral-sh.github.io/packse/0.3.29/simple-html/", marker = "sys_platform == 'linux'" }, { name = "package-b", marker = "sys_platform == 'linux'" }, { name = "package-c", marker = "sys_platform == 'darwin'" }, ] ```
This commit is contained in:
@@ -415,22 +415,22 @@ impl Lock {
|
||||
}
|
||||
|
||||
if !dist.dependencies.is_empty() {
|
||||
let deps = dist
|
||||
.dependencies
|
||||
.iter()
|
||||
.map(|dep| dep.to_toml(&dist_count_by_name))
|
||||
.collect::<ArrayOfTables>();
|
||||
table.insert("dependencies", Item::ArrayOfTables(deps));
|
||||
let deps = each_element_on_its_line_array(
|
||||
dist.dependencies
|
||||
.iter()
|
||||
.map(|dep| dep.to_toml(&dist_count_by_name).into_inline_table()),
|
||||
);
|
||||
table.insert("dependencies", value(deps));
|
||||
}
|
||||
|
||||
if !dist.optional_dependencies.is_empty() {
|
||||
let mut optional_deps = Table::new();
|
||||
for (extra, deps) in &dist.optional_dependencies {
|
||||
let deps = deps
|
||||
.iter()
|
||||
.map(|dep| dep.to_toml(&dist_count_by_name))
|
||||
.collect::<ArrayOfTables>();
|
||||
optional_deps.insert(extra.as_ref(), Item::ArrayOfTables(deps));
|
||||
let deps = each_element_on_its_line_array(
|
||||
deps.iter()
|
||||
.map(|dep| dep.to_toml(&dist_count_by_name).into_inline_table()),
|
||||
);
|
||||
optional_deps.insert(extra.as_ref(), value(deps));
|
||||
}
|
||||
table.insert("optional-dependencies", Item::Table(optional_deps));
|
||||
}
|
||||
@@ -438,11 +438,11 @@ impl Lock {
|
||||
if !dist.dev_dependencies.is_empty() {
|
||||
let mut dev_dependencies = Table::new();
|
||||
for (extra, deps) in &dist.dev_dependencies {
|
||||
let deps = deps
|
||||
.iter()
|
||||
.map(|dep| dep.to_toml(&dist_count_by_name))
|
||||
.collect::<ArrayOfTables>();
|
||||
dev_dependencies.insert(extra.as_ref(), Item::ArrayOfTables(deps));
|
||||
let deps = each_element_on_its_line_array(
|
||||
deps.iter()
|
||||
.map(|dep| dep.to_toml(&dist_count_by_name).into_inline_table()),
|
||||
);
|
||||
dev_dependencies.insert(extra.as_ref(), value(deps));
|
||||
}
|
||||
table.insert("dev-dependencies", Item::Table(dev_dependencies));
|
||||
}
|
||||
@@ -2139,6 +2139,32 @@ impl std::fmt::Display for HashParseError {
|
||||
}
|
||||
}
|
||||
|
||||
/// Format an array so that each element is on its own line and has a trailing comma.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```toml
|
||||
/// dependencies = [
|
||||
/// { name = "idna" },
|
||||
/// { name = "sniffio" },
|
||||
/// ]
|
||||
/// ```
|
||||
fn each_element_on_its_line_array(elements: impl Iterator<Item = InlineTable>) -> Array {
|
||||
let mut array = elements
|
||||
.map(|mut inline_table| {
|
||||
// Each dependency is on its own line and indented.
|
||||
inline_table.decor_mut().set_prefix("\n ");
|
||||
inline_table
|
||||
})
|
||||
.collect::<Array>();
|
||||
// With a trailing comma, inserting another entry doesn't change the preceding line,
|
||||
// reducing the diff noise.
|
||||
array.set_trailing_comma(true);
|
||||
// The line break between the last element's comma and the closing square bracket.
|
||||
array.set_trailing("\n");
|
||||
array
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user