From 1c01b3c934c4d990f17f38b24b22bc153bd36373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Gon=C3=A7alves?= <43336371+carlosmiei@users.noreply.github.com> Date: Fri, 24 Feb 2023 18:55:33 +0000 Subject: [PATCH] fix(docs): broken links inside Configuration.md (#3205) --- crates/ruff_dev/src/generate_rules_table.rs | 3 +- docs/configuration.md | 30 +++++++++---------- docs/faq.md | 4 +-- scripts/add_rule.py | 8 ++++-- scripts/generate_known_standard_library.py | 8 ++++-- scripts/generate_mkdocs.py | 32 ++++++++++++++++++--- scripts/pyproject.toml | 16 ++++------- 7 files changed, 63 insertions(+), 38 deletions(-) diff --git a/crates/ruff_dev/src/generate_rules_table.rs b/crates/ruff_dev/src/generate_rules_table.rs index 65d2cc880e..17f2603002 100644 --- a/crates/ruff_dev/src/generate_rules_table.rs +++ b/crates/ruff_dev/src/generate_rules_table.rs @@ -5,7 +5,6 @@ use ruff::registry::{Linter, Rule, RuleNamespace, UpstreamCategory}; use strum::IntoEnumIterator; const FIX_SYMBOL: &str = "🛠"; -const URL_PREFIX: &str = "/docs/rules"; fn generate_table(table_out: &mut String, rules: impl IntoIterator, linter: &Linter) { table_out.push_str("| Code | Name | Message | Fix |"); @@ -27,7 +26,7 @@ fn generate_table(table_out: &mut String, rules: impl IntoIterator, linter.code_for_rule(&rule).unwrap(), rule.explanation() .is_some() - .then_some(format_args!("[{rule_name}]({URL_PREFIX}/{rule_name}/)",)) + .then_some(format_args!("[{rule_name}](rules/{rule_name}.md)")) .unwrap_or(format_args!("{rule_name}")), rule.message_formats()[0].replace('|', r"\|"), fix_token diff --git a/docs/configuration.md b/docs/configuration.md index 54b3111f34..37df3b1740 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -3,7 +3,7 @@ Ruff can be configured through a `pyproject.toml` file, a `ruff.toml` file, or the command line. For a complete enumeration of the available configuration options, see -[_Settings_](/docs/settings/). +[_Settings_](settings.md). ## Using `pyproject.toml` @@ -92,7 +92,7 @@ docstring-quotes = "double" ``` For a complete enumeration of the available configuration options, see -[_Settings_](/docs/settings/). +[_Settings_](settings.md). Ruff mirrors Flake8's rule code system, in which each rule code consists of a one-to-three letter prefix, followed by three digits (e.g., `F401`). The prefix indicates that "source" of the rule @@ -113,7 +113,7 @@ If you're wondering how to configure Ruff, here are some **recommended guideline you might consider expanding to `select = ["E", "F", "B"]` to enable the popular flake8-bugbear extension. * By default, Ruff's autofix is aggressive. If you find that it's too aggressive for your liking, - consider turning off autofix for specific rules or categories (see the [_FAQ_](/docs/faq/#ruff-tried-to-fix-something-but-it-broke-my-code-what-should-i-do)). + consider turning off autofix for specific rules or categories (see [_FAQ_](faq.md#ruff-tried-to-fix-something--but-it-broke-my-code)). ## Using `ruff.toml` @@ -140,7 +140,7 @@ unfixable = ["B"] ``` For a complete enumeration of the available configuration options, see -[_Settings_](/docs/settings/). +[_Settings_](settings.md). ## Command-line interface @@ -292,7 +292,7 @@ There are a few exceptions to these rules: Unlike [ESLint](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#cascading-and-hierarchy), Ruff does not merge settings across configuration files; instead, the "closest" configuration file is used, and any parent configuration files are ignored. In lieu of this implicit cascade, Ruff -supports an [`extend`](/docs/settings#extend) field, which allows you to inherit the settings from another +supports an [`extend`](settings.md#extend) field, which allows you to inherit the settings from another `pyproject.toml` file, like so: ```toml @@ -308,22 +308,22 @@ and `pyproject.toml` file, it will defer to the `ruff.toml`. ## Python file discovery When passed a path on the command-line, Ruff will automatically discover all Python files in that -path, taking into account the [`exclude`](/docs/settings#exclude) and -[`extend-exclude`](/docs/settings#extend-exclude) settings in each directory's +path, taking into account the [`exclude`](settings.md#exclude) and +[`extend-exclude`](settings.md#extend-exclude) settings in each directory's `pyproject.toml` file. By default, Ruff will also skip any files that are omitted via `.ignore`, `.gitignore`, -`.git/info/exclude`, and global `gitignore` files (see: [`respect-gitignore`](/docs/settings#respect-gitignore)). +`.git/info/exclude`, and global `gitignore` files (see: [`respect-gitignore`](settings.md#respect-gitignore)). Files that are passed to `ruff` directly are always linted, regardless of the above criteria. For example, `ruff check /path/to/excluded/file.py` will always lint `file.py`. ## Rule selection -The set of enabled rules is controlled via the [`select`](/docs/settings#select) and -[`ignore`](/docs/settings#ignore) settings, along with the -[`extend-select`](/docs/settings#extend-select) and -[`extend-ignore`](/docs/settings#extend-ignore) modifiers. +The set of enabled rules is controlled via the [`select`](settings.md#select) and +[`ignore`](settings.md#ignore) settings, along with the +[`extend-select`](settings.md#extend-select) and +[`extend-ignore`](settings.md#extend-ignore) modifiers. To resolve the enabled rule set, Ruff may need to reconcile `select` and `ignore` from a variety of sources, including the current `pyproject.toml`, any inherited `pyproject.toml` files, and the @@ -349,8 +349,8 @@ with the exception of `F401`. ## Error suppression -To omit a lint rule entirely, add it to the "ignore" list via [`ignore`](/docs/settings#ignore) -or [`extend-ignore`](/docs/settings#extend-ignore), either on the command-line +To omit a lint rule entirely, add it to the "ignore" list via [`ignore`](settings.md#ignore) +or [`extend-ignore`](settings.md#extend-ignore), either on the command-line or in your `pyproject.toml` file. To ignore a violation inline, Ruff uses a `noqa` system similar to @@ -391,7 +391,7 @@ like so: # ruff: noqa: F841 ``` -Or see the [`per-file-ignores`](/docs/settings#per-file-ignores) configuration +Or see the [`per-file-ignores`](settings.md#per-file-ignores) configuration setting, which enables the same functionality via a `pyproject.toml` file. Note that Ruff will also respect Flake8's `# flake8: noqa` directive, and will treat it as diff --git a/docs/faq.md b/docs/faq.md index 1b73fd3725..23e4611f21 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -203,7 +203,7 @@ and in how Ruff and isort treat inline comments in some cases (see: [#1381](http Like isort, Ruff's import sorting is compatible with Black. Ruff does not yet support all of isort's configuration options, though it does support many of -them. You can find the supported settings in the [API reference](/docs/settings/#isort). +them. You can find the supported settings in the [API reference](settings.md#isort). For example, you can set `known-first-party` like so: ```toml @@ -319,7 +319,7 @@ have _complete_ certainty when making changes to code, even for the seemingly tr In the future, Ruff will support enabling autofix behavior based on the safety of the patch. In the meantime, if you find that the autofix is too aggressive, you can disable it on a per-rule or -per-category basis using the [`unfixable`](/docs/settings/#unfixable) mechanic. +per-category basis using the [`unfixable`](settings.md#unfixable) mechanic. For example, to disable autofix for some possibly-unsafe rules, you could add the following to your `pyproject.toml`: diff --git a/scripts/add_rule.py b/scripts/add_rule.py index e7cdddd563..b1d9c3ee08 100755 --- a/scripts/add_rule.py +++ b/scripts/add_rule.py @@ -46,7 +46,8 @@ def main(*, name: str, code: str, linter: str) -> None: if line.strip() == "fn rules(rule_code: Rule, path: &Path) -> Result<()> {": indent = get_indent(line) fp.write( - f'{indent}#[test_case(Rule::{name}, Path::new("{code}.py"); "{code}")]', + f'{indent}#[test_case(Rule::{name}, Path::new("{code}.py"); ' + f'"{code}")]', ) fp.write("\n") @@ -150,7 +151,10 @@ pub fn {rule_name_snake}(checker: &mut Checker) {{}} if __name__ == "__main__": parser = argparse.ArgumentParser( description="Generate boilerplate for a new rule.", - epilog="python scripts/add_rule.py --name PreferListBuiltin --code PIE807 --linter flake8-pie", + epilog=( + "python scripts/add_rule.py " + "--name PreferListBuiltin --code PIE807 --linter flake8-pie" + ), ) parser.add_argument( "--name", diff --git a/scripts/generate_known_standard_library.py b/scripts/generate_known_standard_library.py index 88039d7c90..1489939ab9 100644 --- a/scripts/generate_known_standard_library.py +++ b/scripts/generate_known_standard_library.py @@ -1,4 +1,7 @@ -"""Vendored from [scripts/mkstdlibs.py in PyCQA/isort](https://github.com/PyCQA/isort/blob/e321a670d0fefdea0e04ed9d8d696434cf49bdec/scripts/mkstdlibs.py). +"""Vendored from scripts/mkstdlibs.py in PyCQA/isort. + +Source: + https://github.com/PyCQA/isort/blob/e321a670d0fefdea0e04ed9d8d696434cf49bdec/scripts/mkstdlibs.py Only the generation of the file has been modified for use in this project. """ @@ -40,14 +43,13 @@ use rustc_hash::{FxHashMap, FxHashSet}; pub static KNOWN_STANDARD_LIBRARY: Lazy>> = Lazy::new(|| { FxHashMap::from_iter([ -""", +""", # noqa: E501 ) for major, minor in VERSIONS: version = f"{major}.{minor}" url = URL.format(version) invdata = fetch_inventory(FakeApp(), "", url) - # Any modules we want to enforce across Python versions stdlib can be included in set init modules = { "_ast", "posixpath", diff --git a/scripts/generate_mkdocs.py b/scripts/generate_mkdocs.py index 814392aa83..bc342e4791 100644 --- a/scripts/generate_mkdocs.py +++ b/scripts/generate_mkdocs.py @@ -1,5 +1,6 @@ """Generate an MkDocs-compatible `docs` and `mkdocs.yml` from the README.md.""" import argparse +import re import shutil import subprocess from pathlib import Path @@ -33,9 +34,28 @@ FATHOM_SCRIPT: str = ( "" ) +LINK_REWRITES: dict[str, str] = { + "https://beta.ruff.rs/docs/": "index.md", + "https://beta.ruff.rs/docs/configuration/": "configuration.md", + "https://beta.ruff.rs/docs/configuration/#pyprojecttoml-discovery": ( + "configuration.md#pyprojecttoml-discovery" + ), + "https://beta.ruff.rs/docs/contributing/": "contributing.md", + "https://beta.ruff.rs/docs/editor-integrations/": "editor-integrations.md", + "https://beta.ruff.rs/docs/faq/": "faq.md", + "https://beta.ruff.rs/docs/faq/#how-does-ruff-compare-to-flake8": ( + "faq.md#how-does-ruff-compare-to-flake8" + ), + "https://beta.ruff.rs/docs/installation/": "installation.md", + "https://beta.ruff.rs/docs/rules/": "rules.md", + "https://beta.ruff.rs/docs/rules/#error-e": "rules.md#error-e", + "https://beta.ruff.rs/docs/settings/": "settings.md", + "https://beta.ruff.rs/docs/usage/": "usage.md", +} + def clean_file_content(content: str, title: str) -> str: - """Add missing title, fix the headers depth, and remove trailing empty lines.""" + """Add missing title, fix the header depth, and remove trailing empty lines.""" lines = content.splitlines() if lines[0].startswith("# "): return content @@ -62,14 +82,17 @@ def clean_file_content(content: str, title: str) -> str: def main() -> None: """Generate an MkDocs-compatible `docs` and `mkdocs.yml`.""" - subprocess.run(["cargo", "dev", "generate-docs"], check=True) with Path("README.md").open(encoding="utf8") as fp: content = fp.read() - # Convert any inter-documentation links to relative links. - content = content.replace("https://beta.ruff.rs", "") + # Rewrite links to the documentation. + for src, dst in LINK_REWRITES.items(): + content = content.replace(f"({src})", f"({dst})") + if m := re.search(r"\(https://beta.ruff.rs/docs/.*\)", content): + msg = f"Unexpected absolute link to documentation: {m.group(0)}" + raise ValueError(msg) Path("docs").mkdir(parents=True, exist_ok=True) @@ -107,6 +130,7 @@ def main() -> None: ["cargo", "dev", "generate-rules-table"], encoding="utf-8", ) + f.write(clean_file_content(file_content, title)) # Add the nav section to mkdocs.yml. diff --git a/scripts/pyproject.toml b/scripts/pyproject.toml index e3a7b600ff..9b408fcc87 100644 --- a/scripts/pyproject.toml +++ b/scripts/pyproject.toml @@ -3,19 +3,15 @@ name = "scripts" version = "0.0.1" dependencies = ["sphinx"] +[tool.black] +line-length = 88 + [tool.ruff] +line-length = 88 select = ["ALL"] ignore = [ - "E501", # line-too-long - "INP001", # implicit-namespace-package - "PL", # pylint - "S101", # assert-used - "EM", # errmgs - "D202", # no-blank-line-after-function -] -unfixable = [ - "F841", # unused-variable - "RUF100", # unused-noqa + "PL", # pylint + "S", # bandit ] [tool.ruff.pydocstyle]