From 6892f567bbe1d3094309db42c4c8d401b43028db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Tue, 14 May 2024 10:16:08 -0700 Subject: [PATCH] Format the ruff table (#14) --- rust/src/build_system.rs | 6 +- rust/src/data/ruff-order.expected.toml | 198 +++++++++++++++++++++ rust/src/data/ruff-order.start.toml | 114 ++++++++++++ rust/src/helpers/table.rs | 38 ++-- rust/src/main.rs | 8 +- rust/src/project.rs | 6 +- rust/src/ruff.rs | 235 +++++++++++++++++++++++++ 7 files changed, 578 insertions(+), 27 deletions(-) create mode 100644 rust/src/data/ruff-order.expected.toml create mode 100644 rust/src/data/ruff-order.start.toml create mode 100644 rust/src/ruff.rs diff --git a/rust/src/build_system.rs b/rust/src/build_system.rs index 52a09ad..4407bc5 100644 --- a/rust/src/build_system.rs +++ b/rust/src/build_system.rs @@ -2,7 +2,7 @@ use crate::helpers::array::{sort, transform}; use crate::helpers::pep508::{format_requirement, get_canonic_requirement_name}; use crate::helpers::table::{for_entries, reorder_table_keys, Tables}; -pub fn fix_build(tables: &mut Tables, keep_full_version: bool) { +pub fn fix(tables: &mut Tables, keep_full_version: bool) { let table_element = tables.get(&String::from("build-system")); if table_element.is_none() { return; @@ -29,14 +29,14 @@ mod tests { use taplo::parser::parse; use taplo::syntax::SyntaxElement; - use crate::build_system::fix_build; + use crate::build_system::fix; use crate::helpers::table::Tables; fn evaluate(start: &str, keep_full_version: bool) -> String { let root_ast = parse(start).into_syntax().clone_for_update(); let count = root_ast.children_with_tokens().count(); let mut tables = Tables::from_ast(&root_ast); - fix_build(&mut tables, keep_full_version); + fix(&mut tables, keep_full_version); let entries = tables .table_set .iter() diff --git a/rust/src/data/ruff-order.expected.toml b/rust/src/data/ruff-order.expected.toml new file mode 100644 index 0000000..c9f45ab --- /dev/null +++ b/rust/src/data/ruff-order.expected.toml @@ -0,0 +1,198 @@ +[tool.ruff] +required-version = ">=0.0.193" +extend = "../pyproject.toml" +target-version = "py37" +line-length = 120 +indent-width = 2 +tab-size = 2 +builtins = [ + "ALPHA", + "Bar", +] +namespace-packages = [ + "ALPHA", + "Bar", +] +src = [ + "ALPHA", + "Bar", +] +include = [ + "ALPHA", + "Bar", +] +extend-include = [ + "ALPHA", + "Bar", +] +exclude = [ + "ALPHA", + "Bar", +] +extend-exclude = [ + "ALPHA", + "Bar", +] +force-exclude = true +respect-gitignore = false +preview = true +fix = true +unsafe-fixes = true +fix-only = true +show-fixes = true +show-source = true +output-format = "grouped" +cache-dir = "~/a" +format.preview = true +format.indent-style = "tab" +format.quote-style = "single" +format.line-ending = "lf" +format.skip-magic-trailing-comma = true +format.docstring-code-line-length = 60 +format.exclude = [ + "ALPHA", + "Bar", +] +format.docstring-code-format = true +format.extra = true +format.more = true +lint.select = [ + "ALPHA", + "Bar", +] +lint.extend-select = [ + "ALPHA", + "Bar", +] +lint.explicit-preview-rules = true +lint.exclude = [ + "ALPHA", + "Bar", +] +lint.extend-ignore = [ + "ALPHA", + "Bar", +] +lint.per-file-ignores.'Magic.py' = [ + "ALPHA", + "Bar", +] +lint.per-file-ignores."alpha.py" = [ + "ALPHA", + "Bar", +] +lint.extend-per-file-ignores.'Magic.py' = [ + "ALPHA", + "Bar", +] +lint.extend-per-file-ignores."alpha.py" = [ + "ALPHA", + "Bar", +] +lint.fixable = [ + "ALPHA", + "Bar", +] +lint.extend-fixable = [ + "ALPHA", + "Bar", +] +lint.unfixable = [ + "ALPHA", + "Bar", +] +lint.extend-safe-fixes = [ + "ALPHA", + "Bar", +] +lint.extend-unsafe-fixes = [ + "ALPHA", + "Bar", +] +lint.typing-modules = [ + "ALPHA", + "Bar", +] +lint.allowed-confusables = [ + "−", + "∗", + "ρ", +] +lint.dummy-variable-rgx = "^_$" +lint.external = [ + "ALPHA", + "Bar", +] +lint.task-tags = [ + "ALPHA", + "Bar", +] +lint.flake8-annotations.suppress-none-returning = true +lint.flake8-bandit.hardcoded-tmp-directory = [ + "ALPHA", + "Bar", +] +lint.flake8-boolean-trap.extend-allowed-calls = [ + "ALPHA", + "Bar", +] +lint.flake8-bugbear.extend-immutable-calls = [ + "ALPHA", + "Bar", +] +lint.flake8-builtins.builtins-ignorelist = [ + "ALPHA", + "Bar", +] +lint.flake8-comprehensions.allow-dict-calls-with-keyword-arguments = true +lint.flake8-copyright.author = "Ruff" +lint.flake8-copyright.notice-rgx = "(?i)Copyright \\(C\\) \\d{4}" +lint.flake8-errmsg.max-string-length = 20 +lint.flake8-gettext.extend-function-names = [ + "ALPHA", + "Bar", +] +lint.flake8-implicit-str-concat.allow-multiline = false +lint.flake8-import-conventions.aliases.altair = "alt" +lint.flake8-import-conventions.aliases.numpy = "np" +lint.flake8-pytest-style.parametrize-names-type = "list" +lint.flake8-pytest-style.raises-extend-require-match-for = [ + "ALPHA", + "Bar", +] +lint.flake8-quotes.docstring-quotes = "single" +lint.flake8-self.extend-ignore-names = [ + "ALPHA", + "Bar", +] +lint.flake8-tidy-imports.banned-module-level-imports = [ + "ALPHA", + "Bar", +] +lint.flake8-type-checking.exempt-modules = [ + "ALPHA", + "Bar", +] +lint.flake8-unused-arguments.ignore-variadic-names = true +lint.isort.section-order = [ + "Bar", + "ALPHA", +] +lint.mccabe.max-complexity = 5 +lint.pep8-naming.classmethod-decorators = [ + "ALPHA", + "Bar", +] +lint.pycodestyle.max-line-length = 100 +lint.pydocstyle.convention = "google" +lint.pyflakes.extend-generics = [ + "ALPHA", + "Bar", +] +lint.pylint.allow-dunder-method-names = [ + "ALPHA", + "Bar", +] +lint.pyupgrade.keep-runtime-typing = true +lint.extra.ok = 1 +lint.more.ok = 1 diff --git a/rust/src/data/ruff-order.start.toml b/rust/src/data/ruff-order.start.toml new file mode 100644 index 0000000..6d68fc0 --- /dev/null +++ b/rust/src/data/ruff-order.start.toml @@ -0,0 +1,114 @@ +[tool.ruff] +builtins = ['Bar', 'ALPHA'] +cache-dir = '~/a' +exclude = ['Bar', 'ALPHA'] +extend = '../pyproject.toml' +extend-exclude = ['Bar', 'ALPHA'] +extend-include = ['Bar', 'ALPHA'] +fix = true +fix-only = true +force-exclude = true +include = ['Bar', 'ALPHA'] +indent-width = 2 +line-length = 120 +namespace-packages = ['Bar', 'ALPHA'] +output-format = 'grouped' +preview = true +required-version = '>=0.0.193' +respect-gitignore = false +show-fixes = true +show-source = true +src = ['Bar', 'ALPHA'] +tab-size = 2 +target-version = 'py37' +unsafe-fixes = true +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 60 +exclude = ['Bar', 'ALPHA'] +indent-style = 'tab' +line-ending = 'lf' +preview = true +more = true +extra = true +quote-style = 'single' +skip-magic-trailing-comma = true +[tool.ruff.lint] +allowed-confusables = ['−', 'ρ', '∗'] +dummy-variable-rgx = '^_$' +exclude = ['Bar', 'ALPHA'] +explicit-preview-rules = true +extend-fixable = ['Bar', 'ALPHA'] +extend-ignore = ['Bar', 'ALPHA'] +extend-safe-fixes = ['Bar', 'ALPHA'] +extend-select = ['Bar', 'ALPHA'] +extend-unsafe-fixes = ['Bar', 'ALPHA'] +external = ['Bar', 'ALPHA'] +fixable = ['Bar', 'ALPHA'] +select = ['Bar', 'ALPHA'] +task-tags = ['Bar', 'ALPHA'] +typing-modules = ['Bar', 'ALPHA'] +unfixable = ['Bar', 'ALPHA'] +[tool.ruff.lint.extend-per-file-ignores] +'Magic.py' = ['Bar', 'ALPHA'] +"alpha.py" = ['Bar', 'ALPHA'] +[tool.ruff.lint.per-file-ignores] +'Magic.py' = ['Bar', 'ALPHA'] +"alpha.py" = ['Bar', 'ALPHA'] +[tool.ruff.lint.flake8-annotations] +suppress-none-returning = true +[tool.ruff.lint.flake8-bandit] +hardcoded-tmp-directory = ['Bar', 'ALPHA'] +[tool.ruff.lint.flake8-boolean-trap] +extend-allowed-calls = ['Bar', 'ALPHA'] +[tool.ruff.lint.flake8-bugbear] +extend-immutable-calls = ['Bar', 'ALPHA'] +[tool.ruff.lint.flake8-builtins] +builtins-ignorelist = ['Bar', 'ALPHA'] +[tool.ruff.lint.flake8-comprehensions] +allow-dict-calls-with-keyword-arguments = true +[tool.ruff.lint.flake8-copyright] +author = 'Ruff' +notice-rgx = '(?i)Copyright \\(C\\) \\d{4}' +[tool.ruff.lint.flake8-errmsg] +max-string-length = 20 +[tool.ruff.lint.flake8-gettext] +extend-function-names = ['Bar', 'ALPHA'] +[tool.ruff.lint.flake8-implicit-str-concat] +allow-multiline = false +[tool.ruff.lint.flake8-import-conventions.aliases] +altair = "alt" +numpy = "np" +[tool.ruff.lint.flake8-pytest-style] +parametrize-names-type = 'list' +raises-extend-require-match-for = ['Bar', 'ALPHA'] +[tool.ruff.lint.flake8-quotes] +docstring-quotes = 'single' +[tool.ruff.lint.flake8-self] +extend-ignore-names = ['Bar', 'ALPHA'] +[tool.ruff.lint.flake8-tidy-imports] +banned-module-level-imports = ['Bar', 'ALPHA'] +[tool.ruff.lint.flake8-type-checking] +exempt-modules = ['Bar', 'ALPHA'] +[tool.ruff.lint.flake8-unused-arguments] +ignore-variadic-names = true +[tool.ruff.lint.isort] +section-order = ['Bar', 'ALPHA'] +[tool.ruff.lint.mccabe] +max-complexity = 5 +[tool.ruff.lint.pep8-naming] +classmethod-decorators = ['Bar', 'ALPHA'] +[tool.ruff.lint.pycodestyle] +max-line-length = 100 +[tool.ruff.lint.pydocstyle] +convention = 'google' +[tool.ruff.lint.pyflakes] +extend-generics = ['Bar', 'ALPHA'] +[tool.ruff.lint.pylint] +allow-dunder-method-names = ['Bar', 'ALPHA'] +[tool.ruff.lint.more] +ok = 1 +[tool.ruff.lint.extra] +ok = 1 +[tool.ruff.lint.pyupgrade] +keep-runtime-typing = true diff --git a/rust/src/helpers/table.rs b/rust/src/helpers/table.rs index 2e609b3..dff9ed9 100644 --- a/rust/src/helpers/table.rs +++ b/rust/src/helpers/table.rs @@ -119,28 +119,32 @@ fn get_key(k: &str) -> String { } pub fn reorder_table_keys(table: &mut RefMut>, order: &[&str]) { - let size = table.len(); - let (key_to_pos, key_set) = load_keys(table); - let mut to_insert = Vec::::new(); - let mut handled = HashSet::::new(); - for key in order { - let mut parts = key_to_pos - .keys() - .filter(|k| { - key == k || (k.starts_with(key) && k.len() > key.len() && k.chars().nth(key.len()).unwrap() == '.') + let (size, mut to_insert) = (table.len(), Vec::::new()); + let (key_to_position, key_set) = load_keys(table); + let mut handled_positions = HashSet::::new(); + for current_key in order { + let mut matching_keys = key_to_position + .iter() + .filter(|(checked_key, position)| { + !handled_positions.contains(position) + && (current_key == checked_key + || (checked_key.starts_with(current_key) + && checked_key.len() > current_key.len() + && checked_key.chars().nth(current_key.len()).unwrap() == '.')) }) + .map(|(key, _)| key) .clone() .collect::>(); - parts.sort_by_key(|s| s.to_lowercase().replace('"', "")); - for element in parts { - let pos = key_to_pos[element]; - to_insert.extend(key_set[pos].clone()); - handled.insert(pos); + matching_keys.sort_by_key(|key| key.to_lowercase().replace('"', "")); + for key in matching_keys { + let position = key_to_position[key]; + to_insert.extend(key_set[position].clone()); + handled_positions.insert(position); } } - for (at, entry) in key_set.into_iter().enumerate() { - if !handled.contains(&at) { - to_insert.extend(entry); + for (position, entries) in key_set.into_iter().enumerate() { + if !handled_positions.contains(&position) { + to_insert.extend(entries); } } table.splice(0..size, to_insert); diff --git a/rust/src/main.rs b/rust/src/main.rs index d316006..38b845c 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -5,16 +5,15 @@ use pyo3::{pyclass, pyfunction, pymethods, pymodule, wrap_pyfunction, Bound, PyR use taplo::formatter::{format_syntax, Options}; use taplo::parser::parse; -use crate::build_system::fix_build; use crate::global::reorder_tables; use crate::helpers::table::Tables; -use crate::project::fix_project_table; mod build_system; mod project; mod global; mod helpers; +mod ruff; #[pyclass(frozen, get_all)] pub struct Settings { @@ -53,13 +52,14 @@ pub fn format_toml(content: &str, opt: &Settings) -> String { let root_ast = parse(content).into_syntax().clone_for_update(); let mut tables = Tables::from_ast(&root_ast); - fix_build(&mut tables, opt.keep_full_version); - fix_project_table( + build_system::fix(&mut tables, opt.keep_full_version); + project::fix( &mut tables, opt.keep_full_version, opt.max_supported_python, opt.min_supported_python, ); + ruff::fix(&mut tables); reorder_tables(&root_ast, &mut tables); let options = Options { diff --git a/rust/src/project.rs b/rust/src/project.rs index 6ea0d02..a4e93c4 100644 --- a/rust/src/project.rs +++ b/rust/src/project.rs @@ -11,7 +11,7 @@ use crate::helpers::pep508::{format_requirement, get_canonic_requirement_name}; use crate::helpers::string::{load_text, update_content}; use crate::helpers::table::{collapse_sub_tables, for_entries, reorder_table_keys, Tables}; -pub fn fix_project_table( +pub fn fix( tables: &mut Tables, keep_full_version: bool, max_supported_python: (u8, u8), @@ -376,13 +376,13 @@ mod tests { use taplo::syntax::SyntaxElement; use crate::helpers::table::Tables; - use crate::project::fix_project_table; + use crate::project::fix; fn evaluate(start: &str, keep_full_version: bool, max_supported_python: (u8, u8)) -> String { let root_ast = parse(start).into_syntax().clone_for_update(); let count = root_ast.children_with_tokens().count(); let mut tables = Tables::from_ast(&root_ast); - fix_project_table(&mut tables, keep_full_version, max_supported_python, (3, 8)); + fix(&mut tables, keep_full_version, max_supported_python, (3, 8)); let entries = tables .table_set .iter() diff --git a/rust/src/ruff.rs b/rust/src/ruff.rs new file mode 100644 index 0000000..42f1c01 --- /dev/null +++ b/rust/src/ruff.rs @@ -0,0 +1,235 @@ +use crate::helpers::array::{sort, transform}; +use crate::helpers::string::update_content; +use crate::helpers::table::{collapse_sub_tables, for_entries, reorder_table_keys, Tables}; + +#[allow(clippy::too_many_lines)] +pub fn fix(tables: &mut Tables) { + collapse_sub_tables(tables, "tool.ruff"); + let table_element = tables.get(&String::from("tool.ruff")); + if table_element.is_none() { + return; + } + let table = &mut table_element.unwrap().borrow_mut(); + for_entries(table, &mut |key, entry| match key.as_str() { + "target-version" + | "cache-dir" + | "extend" + | "required-version" + | "output-format" + | "format.indent-style" + | "format.line-ending" + | "format.quote-style" + | "lint.dummy-variable-rgx" + | "lint.flake8-copyright.author" + | "lint.flake8-copyright.notice-rgx" + | "lint.flake8-pytest-style.parametrize-names-type" + | "lint.flake8-pytest-style.parametrize-values-row-type" + | "lint.flake8-pytest-style.parametrize-values-type" + | "lint.flake8-quotes.docstring-quotes" + | "lint.flake8-quotes.multiline-quotes" + | "lint.flake8-quotes.inline-quotes" + | "lint.flake8-tidy-imports.ban-relative-imports" + | "lint.isort.known-first-party" + | "lint.isort.known-third-party" + | "lint.isort.relative-imports-order" + | "lint.pydocstyle.convention" => { + update_content(entry, |s| String::from(s)); + } + "exclude" + | "extend-exclude" + | "builtins" + | "include" + | "extend-include" + | "namespace-packages" + | "src" + | "format.exclude" + | "lint.allowed-confusables" + | "lint.exclude" + | "lint.extend-fixable" + | "lint.extend-ignore" + | "lint.extend-safe-fixes" + | "lint.extend-select" + | "lint.extend-unsafe-fixes" + | "lint.external" + | "lint.fixable" + | "lint.ignore" + | "lint.logger-objects" + | "lint.select" + | "lint.task-tags" + | "lint.typing-modules" + | "lint.unfixable" + | "lint.flake8-bandit.hardcoded-tmp-directory" + | "lint.flake8-bandit.hardcoded-tmp-directory-extend" + | "lint.flake8-boolean-trap.extend-allowed-calls" + | "lint.flake8-bugbear.extend-immutable-calls" + | "lint.flake8-builtins.builtins-ignorelist" + | "lint.flake8-gettext.extend-function-names" + | "lint.flake8-gettext.function-names" + | "lint.flake8-import-conventions.banned-from" + | "lint.flake8-pytest-style.raises-extend-require-match-for" + | "lint.flake8-pytest-style.raises-require-match-for" + | "lint.flake8-self.extend-ignore-names" + | "lint.flake8-self.ignore-names" + | "lint.flake8-tidy-imports.banned-module-level-imports" + | "lint.flake8-type-checking.exempt-modules" + | "lint.flake8-type-checking.runtime-evaluated-base-classes" + | "lint.flake8-type-checking.runtime-evaluated-decorators" + | "lint.isort.constants" + | "lint.isort.default-section" + | "lint.isort.extra-standard-library" + | "lint.isort.forced-separate" + | "lint.isort.no-lines-before" + | "lint.isort.required-imports" + | "lint.isort.single-line-exclusions" + | "lint.isort.variables" + | "lint.pep8-naming.classmethod-decorators" + | "lint.pep8-naming.extend-ignore-names" + | "lint.pep8-naming.ignore-names" + | "lint.pep8-naming.staticmethod-decorators" + | "lint.pydocstyle.ignore-decorators" + | "lint.pydocstyle.property-decorators" + | "lint.pyflakes.extend-generics" + | "lint.pylint.allow-dunder-method-names" + | "lint.pylint.allow-magic-value-types" => { + transform(entry, &|s| String::from(s)); + sort(entry, str::to_lowercase); + } + "lint.isort.section-order" => { + transform(entry, &|s| String::from(s)); + } + _ => { + if key.starts_with("lint.extend-per-file-ignores.") || key.starts_with("lint.per-file-ignores.") { + transform(entry, &|s| String::from(s)); + sort(entry, str::to_lowercase); + } + } + }); + reorder_table_keys( + table, + &[ + "", + "required-version", + "extend", + "target-version", + "line-length", + "indent-width", + "tab-size", + "builtins", + "namespace-packages", + "src", + "include", + "extend-include", + "exclude", + "extend-exclude", + "force-exclude", + "respect-gitignore", + "preview", + "fix", + "unsafe-fixes", + "fix-only", + "show-fixes", + "show-source", + "output-format", + "cache-dir", + "format.preview", + "format.indent-style", + "format.quote-style", + "format.line-ending", + "format.skip-magic-trailing-comma", + "format.docstring-code-line-length", + "format.docstring-code-format ", + "format.exclude", + "format", + "lint.select", + "lint.extend-select", + "lint.explicit-preview-rules", + "lint.exclude", + "lint.extend-ignore", + "lint.per-file-ignores", + "lint.extend-per-file-ignores", + "lint.fixable", + "lint.extend-fixable", + "lint.unfixable", + "lint.extend-safe-fixes", + "lint.extend-unsafe-fixes", + "lint.typing-modules", + "lint.allowed-confusables", + "lint.dummy-variable-rgx", + "lint.external", + "lint.task-tags", + "lint.flake8-annotations", + "lint.flake8-bandit", + "lint.flake8-boolean-trap", + "lint.flake8-bugbear", + "lint.flake8-builtins", + "lint.flake8-comprehensions", + "lint.flake8-copyright", + "lint.flake8-errmsg", + "lint.flake8-gettext", + "lint.flake8-implicit-str-concat", + "lint.flake8-import-conventions", + "lint.flake8-pytest-style", + "lint.flake8-quotes", + "lint.flake8-self", + "lint.flake8-tidy-imports", + "lint.flake8-type-checking", + "lint.flake8-unused-arguments", + "lint.isort", + "lint.mccabe", + "lint.pep8-naming", + "lint.pycodestyle", + "lint.pydocstyle", + "lint.pyflakes", + "lint.pylint", + "lint.pyupgrade", + "lint", + ], + ); +} + +#[cfg(test)] +mod tests { + use std::fs::read_to_string; + use std::path::{Path, PathBuf}; + + use rstest::{fixture, rstest}; + use taplo::formatter::{format_syntax, Options}; + use taplo::parser::parse; + use taplo::syntax::SyntaxElement; + + use crate::helpers::table::Tables; + use crate::ruff::fix; + + fn evaluate(start: &str) -> String { + let root_ast = parse(start).into_syntax().clone_for_update(); + let count = root_ast.children_with_tokens().count(); + let mut tables = Tables::from_ast(&root_ast); + fix(&mut tables); + let entries = tables + .table_set + .iter() + .flat_map(|e| e.borrow().clone()) + .collect::>(); + root_ast.splice_children(0..count, entries); + let opt = Options { + column_width: 1, + ..Options::default() + }; + format_syntax(root_ast, opt) + } + #[fixture] + fn data() -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("rust") + .join("src") + .join("data") + } + + #[rstest] + fn test_order_ruff(data: PathBuf) { + let start = read_to_string(data.join("ruff-order.start.toml")).unwrap(); + let got = evaluate(start.as_str()); + let expected = read_to_string(data.join("ruff-order.expected.toml")).unwrap(); + assert_eq!(got, expected); + } +}