diff --git a/Cargo.lock b/Cargo.lock index 13c18a9..63ca0bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -520,7 +520,7 @@ dependencies = [ [[package]] name = "pyproject-fmt-rust" -version = "1.1.4" +version = "1.1.5" dependencies = [ "indoc", "lexical-sort", diff --git a/rust/src/helpers/array.rs b/rust/src/helpers/array.rs index 3cf4814..bc96672 100644 --- a/rust/src/helpers/array.rs +++ b/rust/src/helpers/array.rs @@ -37,6 +37,10 @@ where .filter(|x| *x == COMMA || *x == VALUE) .last() == Some(COMMA); + let multiline = array_node + .children_with_tokens() + .find(|e| e.kind() == NEWLINE) + .is_some(); let mut value_set = Vec::>::new(); let entry_set = RefCell::new(Vec::::new()); let mut key_to_pos = HashMap::::new(); @@ -67,7 +71,9 @@ where match &entry.kind() { SyntaxKind::BRACKET_START => { entries.push(entry); - entries.push(make_newline()); + if multiline { + entries.push(make_newline()); + } previous_is_bracket_open = true; } SyntaxKind::BRACKET_END => { @@ -80,7 +86,9 @@ where } VALUE => { if has_value { - entry_set.borrow_mut().push(make_newline()); + if multiline { + entry_set.borrow_mut().push(make_newline()); + } add_to_value_set(entry_value.clone()); } has_value = true; @@ -117,7 +125,7 @@ where let mut order: Vec = key_to_pos.clone().into_keys().collect(); order.string_sort_unstable(natural_lexical_cmp); - let end = entries.split_off(2); + let end = entries.split_off(if multiline { 2 } else { 1 }); for key in order { entries.extend(value_set[key_to_pos[&key]].clone()); } diff --git a/rust/src/main.rs b/rust/src/main.rs index 1920e95..93d7e3a 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -63,16 +63,16 @@ pub fn format_toml(content: &str, opt: &Settings) -> String { reorder_tables(&root_ast, &mut tables); let options = Options { - align_entries: false, // do not align by = - align_comments: true, // align inline comments - align_single_comments: true, // align comments after entries - array_trailing_comma: true, // ensure arrays finish with trailing comma - array_auto_expand: true, // arrays go to multi line for easier diffs - array_auto_collapse: false, // do not collapse for easier diffs - compact_arrays: false, // do not compact for easier diffs - compact_inline_tables: false, // do not compact for easier diffs - compact_entries: false, // do not compact for easier diffs - column_width: opt.column_width, // always expand arrays per https://github.com/tamasfe/taplo/issues/390 + align_entries: false, // do not align by = + align_comments: true, // align inline comments + align_single_comments: true, // align comments after entries + array_trailing_comma: true, // ensure arrays finish with trailing comma + array_auto_expand: true, // arrays go to multi line when too long + array_auto_collapse: false, // do not collapse for easier diffs + compact_arrays: false, // leave whitespace + compact_inline_tables: false, // leave whitespace + compact_entries: false, // leave whitespace + column_width: opt.column_width, indent_tables: false, indent_entries: false, inline_table_expand: true, @@ -316,4 +316,47 @@ mod tests { let second = format_toml(got.as_str(), &settings); assert_eq!(second, got); } + + /// Test that the column width is respected, + /// and that arrays are neither exploded nor collapsed without reason + #[rstest] + fn test_column_width() { + let start = indoc! {r#" + [build-system] + build-backend = "backend" + requires = ["c>=1.5", "d == 2" ] + + [project] + name = "beta" + dependencies = [ + "e>=1.5", + ] + "#}; + let settings = Settings { + column_width: 80, + indent: 4, + keep_full_version: false, + max_supported_python: (3, 12), + min_supported_python: (3, 12), + }; + let got = format_toml(start, &settings); + let expected = indoc! {r#" + [build-system] + build-backend = "backend" + requires = [ "c>=1.5", "d==2" ] + + [project] + name = "beta" + classifiers = [ + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.12", + ] + dependencies = [ + "e>=1.5", + ] + "#}; + assert_eq!(got, expected); + let second = format_toml(got.as_str(), &settings); + assert_eq!(second, got); + } } diff --git a/tests/test_main.py b/tests/test_main.py index 468bdee..8216701 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -2,26 +2,73 @@ from textwrap import dedent -from pyproject_fmt_rust import Settings, format_toml +import pytest +from pyproject_fmt_rust import Settings, format_toml -def test_format_toml() -> None: - txt = """ - [project] - keywords = [ - "A", - ] - classifiers = [ - "Programming Language :: Python :: 3 :: Only", - ] - dynamic = [ - "B", - ] - dependencies = [ - "requests>=2.0", - ] - """ +@pytest.mark.parametrize( + ("start", "expected"), + [ + pytest.param( + """ + [project] + keywords = [ + "A", + ] + classifiers = [ + "Programming Language :: Python :: 3 :: Only", + ] + dynamic = [ + "B", + ] + dependencies = [ + "requests>=2.0", + ] + """, + """\ + [project] + keywords = [ + "A", + ] + classifiers = [ + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + ] + dynamic = [ + "B", + ] + dependencies = [ + "requests>=2.0", + ] + """, + id="expanded", + ), + pytest.param( + """ + [project] + keywords = ["A"] + classifiers = ["Programming Language :: Python :: 3 :: Only"] + dynamic = ["B"] + dependencies = ["requests>=2.0"] + """, + """\ + [project] + keywords = [ "A" ] + classifiers = [ + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + ] + dynamic = [ "B" ] + dependencies = [ "requests>=2.0" ] + """, + id="collapsed", + ), + ], +) +def test_format_toml(start: str, expected: str) -> None: settings = Settings( column_width=120, indent=4, @@ -29,23 +76,5 @@ def test_format_toml() -> None: min_supported_python=(3, 7), max_supported_python=(3, 8), ) - res = format_toml(dedent(txt), settings) - - expected = """\ - [project] - keywords = [ - "A", - ] - classifiers = [ - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - ] - dynamic = [ - "B", - ] - dependencies = [ - "requests>=2.0", - ] - """ + res = format_toml(dedent(start), settings) assert res == dedent(expected)