format_code / lint_code for Python, backed by ruff (com.blockether/ruff).
ruff runs IN-PROCESS: the Rust ruff_python_formatter / ruff_linter crates are
linked as a cdylib and called over the FFM API. There is no ruff binary to
install, no subprocess, no virtualenv, and no PATH lookup — the same code path
works from the native image. Configuration is RUFF'S OWN discovery: for every
source, ruff walks up from the file to the nearest .ruff.toml / ruff.toml /
pyproject.toml with a [tool.ruff] table and honours it whole — extend,
per-file-ignores, target-version, formatter options — so a run here and a
ruff CLI run agree. With no config anywhere the tool still runs on ruff's
defaults and SAYS SO in a hint.
Both handlers accept the SAME argument shapes as the Clojure pack: a code string, {"code"}, {"path"}, {"paths"}, or nothing (whole project).
`format_code` / `lint_code` for Python, backed by ruff (com.blockether/ruff).
ruff runs IN-PROCESS: the Rust ruff_python_formatter / ruff_linter crates are
linked as a cdylib and called over the FFM API. There is no `ruff` binary to
install, no subprocess, no virtualenv, and no PATH lookup — the same code path
works from the native image. Configuration is RUFF'S OWN discovery: for every
source, ruff walks up from the file to the nearest `.ruff.toml` / `ruff.toml` /
`pyproject.toml` with a `[tool.ruff]` table and honours it whole — `extend`,
`per-file-ignores`, `target-version`, formatter options — so a run here and a
`ruff` CLI run agree. With no config anywhere the tool still runs on ruff's
defaults and SAYS SO in a `hint`.
Both handlers accept the SAME argument shapes as the Clojure pack:
a code string, {"code"}, {"path"}, {"paths"}, or nothing (whole project).(config-finder)config-for, memoised per directory for ONE tool call: a project walk asks
once per directory instead of once per file, and a config edited between calls
is still picked up.
`config-for`, memoised per directory for ONE tool call: a project walk asks once per directory instead of once per file, and a config edited between calls is still picked up.
(config-for p)The ruff configuration file governing p (a file or a directory), or nil when
the tree has none. Discovery is RUFF'S OWN — .ruff.toml, ruff.toml, then a
pyproject.toml carrying a [tool.ruff] table, walking ancestors — so vis
sees exactly the file the ruff CLI would use, extend chains and all.
The ruff configuration file governing `p` (a file or a directory), or nil when the tree has none. Discovery is RUFF'S OWN — `.ruff.toml`, `ruff.toml`, then a `pyproject.toml` carrying a `[tool.ruff]` table, walking ancestors — so vis sees exactly the file the `ruff` CLI would use, `extend` chains and all.
(discover-python-source-paths root)Default targets when neither path nor paths is given: the conventional
source roots that exist (src, the workspace root's top-level packages,
tests), falling back to the whole workspace root.
Default targets when neither `path` nor `paths` is given: the conventional source roots that exist (`src`, the workspace root's top-level packages, `tests`), falling back to the whole workspace root.
(expand-python-files root targets)Absolute paths of every Python source file under targets (files kept as-is,
DIRECTORIES walked recursively, skip-dirs pruned). Sorted + distinct.
Absolute paths of every Python source file under `targets` (files kept as-is, DIRECTORIES walked recursively, `skip-dirs` pruned). Sorted + distinct.
What to tell the caller when the project pins nothing: ruff still ran, with ITS defaults, and the fix is a config file rather than a tool flag.
What to tell the caller when the project pins nothing: ruff still ran, with ITS defaults, and the fix is a config file rather than a tool flag.
(py-format-fn arg)(py-format-fn env arg)Format Python source with ruff via the language facade (format_code).
Accepts:
ruff.toml / [tool.ruff]), discovered by ruff itself per file; config
pins one explicitly and line_length overrides it. Syntactically invalid
Python is left VERBATIM rather than failing the call, so a formatter run never
destroys a half-written file.Format Python source with ruff via the language facade (`format_code`).
Accepts:
- a raw code string / {"code": ...} -> report changed? + char delta (NO text)
- {"path": "src/foo.py"} -> format that file IN PLACE
- {"paths": ["src" "tests"]} -> format those paths IN PLACE; a
DIRECTORY is walked RECURSIVELY (every .py/.pyi under it, minus venv /
cache / build dirs)
- nothing / {} -> format the project's source roots
Rule set and wrap width come from the project's ruff configuration file
(`ruff.toml` / `[tool.ruff]`), discovered by ruff itself per file; `config`
pins one explicitly and `line_length` overrides it. Syntactically invalid
Python is left VERBATIM rather than failing the call, so a formatter run never
destroys a half-written file.(py-lint-fn arg)(py-lint-fn env arg)Lint Python with ruff via the language facade (lint_code). Accepts:
path and paths are UNIONED; a target that resolves to nothing is an
ERROR, not a silent clean. The RULE SET is the project's ruff configuration
file, discovered by ruff itself (.ruff.toml / ruff.toml / [tool.ruff] in
pyproject.toml, nearest ancestor wins) and reported back as config; with
no such file the run falls back to ruff's defaults (E4, E7, E9, F) and returns
a hint telling the caller to add one. config pins a file explicitly and
select / ignore (a string, or a list of selectors like ["F" "B" "E501"])
override it. Findings carry the ruff code as type, is_fixable, and a
level derived from the code: syntax/pyflakes fatals are errors, conventions
(W/C/N/D/I/UP…) info, the rest warnings.Lint Python with ruff via the language facade (`lint_code`). Accepts:
- a raw code string / {"code": ...} -> lint the snippet
- {"path": "src/foo.py"} -> lint that file
- {"paths": ["src" "tests"]} -> lint those paths (dirs recursive)
- nothing / {} -> lint the project's source roots
`path` and `paths` are UNIONED; a target that resolves to nothing is an
ERROR, not a silent `clean`. The RULE SET is the project's ruff configuration
file, discovered by ruff itself (`.ruff.toml` / `ruff.toml` / `[tool.ruff]` in
`pyproject.toml`, nearest ancestor wins) and reported back as `config`; with
no such file the run falls back to ruff's defaults (E4, E7, E9, F) and returns
a `hint` telling the caller to add one. `config` pins a file explicitly and
`select` / `ignore` (a string, or a list of selectors like ["F" "B" "E501"])
override it. Findings carry the ruff code as `type`, `is_fixable`, and a
`level` derived from the code: syntax/pyflakes fatals are errors, conventions
(W/C/N/D/I/UP…) info, the rest warnings.(relativize-path root p)p written relative to root when it lives under it, else left absolute.
`p` written relative to `root` when it lives under it, else left absolute.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |