Skip to content

Commit eae9bf5

Browse files
authored
Update dependencies and add Ruff (#34)
1 parent 09a8343 commit eae9bf5

5 files changed

Lines changed: 124 additions & 44 deletions

File tree

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
*
22
!.editorconfig
33
!entry.ts
4+
!ruff.toml
45
!stylesheet.xml
56
!svgo.config.js

Dockerfile

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM alpine:3.16.0
1+
FROM alpine:3.18.4
22

33
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
44
ENV PIP_NO_CACHE_DIR=1
@@ -13,36 +13,36 @@ RUN apk add --no-cache --virtual .build-deps \
1313
clang-extra-tools \
1414
libxslt \
1515
nodejs \
16-
openjdk11-jre-headless \
16+
openjdk17-jre-headless \
1717
py3-pip \
1818
python3 \
1919
&& pip3 install \
20-
autoflake==1.4 \
21-
black==22.3.0 \
22-
isort==5.10.1 \
20+
autoflake==1.7.8 \
21+
isort==5.12.0 \
22+
ruff==0.1.5 \
2323
&& python3 -m venv /black21-venv \
2424
&& source /black21-venv/bin/activate \
2525
&& pip3 install black==21.12b0 click==8.0.4 \
2626
&& deactivate \
2727
&& echo 'source /black21-venv/bin/activate && black "$@"' > /usr/bin/black21 \
2828
&& chmod +x /usr/bin/black21 \
2929
&& npm install -g \
30-
@prettier/plugin-xml@2.2.0 \
31-
@types/node@18.16.0 \
32-
prettier@2.8.8 \
33-
svgo@2.8.0 \
34-
typescript@5.0.4 \
30+
@prettier/plugin-xml@3.2.2 \
31+
@types/node@20.9.0 \
32+
prettier@3.1.0 \
33+
svgo@3.0.3 \
34+
typescript@5.2.2 \
3535
&& apk del .build-deps \
36-
&& wget https://github.com/google/google-java-format/releases/download/v1.15.0/google-java-format-1.15.0-all-deps.jar -O google-java-format \
37-
&& wget https://search.maven.org/remotecontent?filepath=com/facebook/ktfmt/0.35/ktfmt-0.35-jar-with-dependencies.jar -O ktfmt \
38-
&& wget https://github.com/mvdan/sh/releases/download/v3.4.3/shfmt_v3.4.3_linux_amd64 -O shfmt \
36+
&& wget https://github.com/google/google-java-format/releases/download/v1.18.1/google-java-format-1.18.1-all-deps.jar -O google-java-format \
37+
&& wget https://search.maven.org/remotecontent?filepath=com/facebook/ktfmt/0.46/ktfmt-0.46-jar-with-dependencies.jar -O ktfmt \
38+
&& wget https://github.com/mvdan/sh/releases/download/v3.7.0/shfmt_v3.7.0_linux_amd64 -O shfmt \
3939
&& chmod +x shfmt \
40-
&& wget https://releases.hashicorp.com/terraform/1.1.8/terraform_1.1.8_linux_amd64.zip -O tf.zip \
40+
&& wget https://releases.hashicorp.com/terraform/1.6.3/terraform_1.6.3_linux_amd64.zip -O tf.zip \
4141
&& unzip tf.zip \
4242
&& rm tf.zip \
43-
&& wget https://github.com/coursier/coursier/releases/download/v2.0.16/coursier -O /bin/coursier \
43+
&& wget https://github.com/coursier/coursier/releases/download/v2.1.7/coursier -O /bin/coursier \
4444
&& chmod +x /bin/coursier \
45-
&& coursier bootstrap org.scalameta:scalafmt-cli_2.13:3.5.1 \
45+
&& coursier bootstrap org.scalameta:scalafmt-cli_2.13:3.7.16 \
4646
-r sonatype:snapshots --main org.scalafmt.cli.Cli \
4747
--standalone \
4848
-o scalafmt \

README.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@
22

33
This repo currently contains a single [pre-commit](https://pre-commit.com/) hook that internally runs several code formatters in parallel.
44

5-
- [Prettier](https://github.com/prettier/prettier) v2.8.8 for CSS, HTML, JS, JSX, Markdown, Sass, TypeScript, XML, YAML
6-
- [Black](https://github.com/psf/black) v22.3.0 for Python 3, v21.12b0 for Python 2
7-
- [autoflake](https://github.com/myint/autoflake) v1.4 for Python
8-
- [isort](https://github.com/PyCQA/isort) v5.10.1 for Python
9-
- [google-java-format](https://github.com/google/google-java-format) v1.15.0 for Java
10-
- [ktfmt](https://github.com/facebookincubator/ktfmt) v0.35 for Kotlin
11-
- [scalafmt](https://scalameta.org/scalafmt/) v3.5.1 for Scala
12-
- [shfmt](https://github.com/mvdan/sh) v3.4.3 for Shell
13-
- [xsltproc](http://www.xmlsoft.org/xslt/xsltproc.html) from libxslt v10135 for XML
14-
- [terraform fmt](https://github.com/hashicorp/terraform) v1.1.8 for Terraform
15-
- [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html) v13.0.1 for Protobuf
16-
- [SVGO](https://github.com/svg/svgo) v2.8.0 for SVG
5+
- [Prettier](https://github.com/prettier/prettier) v3.1.0 for CSS, HTML, JS, JSX, Markdown, Sass, TypeScript, XML, YAML
6+
- [Ruff](https://docs.astral.sh/ruff/) v0.1.5 for Python 3
7+
- [Black](https://github.com/psf/black) v21.12b0 for Python 2
8+
- [autoflake](https://github.com/myint/autoflake) v1.7.8 for Python <!-- TODO: Upgrade to v2+, restrict to Python 2, and reenable Ruff rule F401 once our Python 3 repos that were converted from Python 2 no longer use type hint comments: https://github.com/PyCQA/autoflake/issues/222#issuecomment-1419089254 -->
9+
- [isort](https://github.com/PyCQA/isort) v5.12.0 for Python 2
10+
- [google-java-format](https://github.com/google/google-java-format) v1.18.1 for Java
11+
- [ktfmt](https://github.com/facebookincubator/ktfmt) v0.46 for Kotlin
12+
- [scalafmt](https://scalameta.org/scalafmt/) v3.7.16 for Scala
13+
- [shfmt](https://github.com/mvdan/sh) v3.7.0 for Shell
14+
- [xsltproc](http://www.xmlsoft.org/xslt/xsltproc.html) from libxslt v10138 for XML
15+
- [terraform fmt](https://github.com/hashicorp/terraform) v1.6.3 for Terraform
16+
- [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html) v16.0.6 for Protobuf
17+
- [SVGO](https://github.com/svg/svgo) v3.0.3 for SVG
1718
- Custom regex transformations (basically [sed](https://en.wikipedia.org/wiki/Sed)), for example:
1819
- Trimming trailing whitespace and newlines
1920
- Removing unnecessary `coding` pragmas and `object` base classes in Python 3

entry.ts

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
import { exec } from "child_process";
44
import { readFile, writeFile } from "fs";
55

6-
/** Maximum characters per line in Python */
7-
const PYTHON_LINE_LENGTH = 100;
8-
96
/**
107
* Path to an empty file that we can provide to linters/formatters as a config
118
* file in order to force those tools' default behavior
@@ -16,11 +13,16 @@ const EMPTY_FILE = "/emptyfile";
1613
const PRETTIER_OPTIONS = [
1714
"--arrow-parens",
1815
"avoid",
16+
// We don't enable or benefit from caching, but we must still specify a
17+
// location or else Prettier will fail with the error `EPERM: operation not
18+
// permitted, mkdir '/src/node_modules/.cache/prettier'`
19+
"--cache-location",
20+
"/tmp/prettier-cache",
1921
"--end-of-line",
2022
"auto",
2123
"--ignore-path",
2224
EMPTY_FILE,
23-
"--loglevel",
25+
"--log-level",
2426
"warn",
2527
"--no-config",
2628
"--no-editorconfig",
@@ -74,6 +76,7 @@ const enum HookName {
7476
Ktfmt = "ktfmt",
7577
PrettierJs = "Prettier (JS)",
7678
PrettierNonJs = "Prettier (non-JS)",
79+
Ruff = "Ruff",
7780
Scalafmt = "scalafmt",
7881
Sed = "sed",
7982
Shfmt = "shfmt",
@@ -99,7 +102,7 @@ interface Hook {
99102
* linter crashes are surfaced to the user and for simplicity in the case of
100103
* the many linters that exit with nonzero iff there are violations.
101104
*/
102-
action: (sources: string[], args: Args) => Promise<unknown>;
105+
action: (sources: string[], args: Args) => any;
103106
/** Source files to exclude */
104107
exclude?: RegExp;
105108
/** Source files to include */
@@ -144,18 +147,20 @@ const HOOKS: Record<HookName, LockableHook> = {
144147
}),
145148
[HookName.Black]: createLockableHook({
146149
action: async (sources, args) =>
150+
args["python-version"]?.startsWith("2") &&
147151
run(
148152
// Black 21.x was the last major version with Python 2 support. It also
149153
// had a bug that requires pinning click==8.0.4. Both packages should
150154
// be removed once we drop Python 2 support.
151155
// https://github.com/psf/black/issues/2964
152-
...(args["python-version"]?.startsWith("2")
153-
? ["black21", "--fast", "--target-version", "py27"]
154-
: ["black", "--target-version", "py310"]),
156+
"black21",
157+
"--fast",
158+
"--target-version",
159+
"py27",
155160
"--config",
156161
EMPTY_FILE,
157162
"--line-length",
158-
`${PYTHON_LINE_LENGTH}`,
163+
"100",
159164
"--quiet",
160165
...sources,
161166
),
@@ -183,7 +188,9 @@ const HOOKS: Record<HookName, LockableHook> = {
183188
// isort's automatic config file detection is broken
184189
// https://github.com/PyCQA/isort/issues/1907
185190
// https://github.com/samueljsb/qaz/pull/104
186-
action: sources => run("isort", "--settings", "/.editorconfig", ...sources),
191+
action: (sources, args) =>
192+
args["python-version"]?.startsWith("2") &&
193+
run("isort", "--settings", "/.editorconfig", ...sources),
187194
include: /\.py$/,
188195
runAfter: [HookName.Autoflake],
189196
}),
@@ -212,7 +219,14 @@ const HOOKS: Record<HookName, LockableHook> = {
212219
runAfter: [HookName.Sed],
213220
}),
214221
[HookName.PrettierJs]: createLockableHook({
215-
action: sources => run("prettier", ...PRETTIER_OPTIONS, ...sources),
222+
action: sources =>
223+
run(
224+
"prettier",
225+
...PRETTIER_OPTIONS,
226+
"--trailing-comma",
227+
"es5",
228+
...sources,
229+
),
216230
exclude: /\b(compressed|custom|min|minified|pack|prod|production)\b/,
217231
include: /\.jsx?$/,
218232
runAfter: [HookName.Sed],
@@ -222,13 +236,28 @@ const HOOKS: Record<HookName, LockableHook> = {
222236
run(
223237
"prettier",
224238
...PRETTIER_OPTIONS,
225-
"--trailing-comma",
226-
"all",
239+
"--plugin",
240+
// https://github.com/prettier/prettier/issues/15141#issuecomment-1685112479
241+
"/usr/local/lib/node_modules/@prettier/plugin-xml/src/plugin.js",
227242
...sources,
228243
),
229244
include: /\.(css|html?|markdown|md|scss|tsx?|xml|ya?ml)$/,
230245
runAfter: [HookName.Sed, HookName.Xsltproc],
231246
}),
247+
[HookName.Ruff]: createLockableHook({
248+
action: async (sources, args) => {
249+
if (args["python-version"]?.startsWith("2")) {
250+
return;
251+
}
252+
// Sometimes Ruff requires multiple passes, which is ok since it's fast
253+
for (let i = 0; i < 2; ++i) {
254+
await run("ruff", "check", "--config", "/ruff.toml", ...sources);
255+
await run("ruff", "format", "--config", "/ruff.toml", ...sources);
256+
}
257+
},
258+
include: /\.py$/,
259+
runAfter: [HookName.Autoflake],
260+
}),
232261
[HookName.Scalafmt]: createLockableHook({
233262
action: async (sources, args) =>
234263
run(
@@ -385,15 +414,25 @@ const GLOBAL_EXCLUDES = (() => {
385414

386415
/** Prefixes a string to all nonempty lines of input */
387416
const prefixLines = (() => {
417+
const LINES_TO_IGNORE = new RegExp(
418+
[
419+
// Empty lines
420+
/^\s*$/,
421+
// ktfmt spams this for every file that has no violations
422+
/\bDone formatting .+\.kts?$/,
423+
// Black 21.12b0 spams this when running on Python 2 source code
424+
/\bDEPRECATION: Python 2 support\b/,
425+
]
426+
.map(regex => regex.source)
427+
.join("|"),
428+
);
388429
const maxPrefixLength = Math.max(
389430
...Object.keys(HOOKS).map(name => name.length),
390431
);
391432
return (prefix: string, lines: string) =>
392433
lines
393434
.split("\n")
394-
.filter(line => line.trim().length)
395-
// Black 21.12b0 spams this when running on Python 2 source code
396-
.filter(line => !line.includes("DEPRECATION: Python 2 support"))
435+
.filter(line => !LINES_TO_IGNORE.test(line))
397436
.map(line => `${prefix}:`.padEnd(maxPrefixLength + 2) + line)
398437
.join("\n");
399438
})();

ruff.toml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
cache-dir = "/tmp/.cache/ruff"
2+
fix-only = true
3+
line-length = 100
4+
target-version = "py37"
5+
6+
[pydocstyle]
7+
convention = "pep257"
8+
9+
[isort]
10+
combine-as-imports = true
11+
12+
[lint]
13+
ignore = [
14+
# We disable Ruff's `unused-import` for now in favor of autoflake <2 because
15+
# the latter preserves imports that are unused in code but "used" in type
16+
# hint comments. Ruff also seems to have an unfortunate bug: it can end up
17+
# moving a `pylint: disable=unused-import` comment from one import to another
18+
"F401",
19+
# This rule inexplicably converts `elif a or isinstance(b, C) or isinstance
20+
# (b, D)` to `elif isinstance(b, (C, D))`, buggily removing condition `a`
21+
"PLR1701",
22+
]
23+
# https://docs.astral.sh/ruff/rules/
24+
select = [
25+
"B",
26+
"C4",
27+
"D",
28+
"E",
29+
"F",
30+
"I",
31+
"ISC",
32+
"PERF",
33+
"PIE",
34+
"PL",
35+
"Q",
36+
"RUF",
37+
"SIM",
38+
"UP",
39+
]

0 commit comments

Comments
 (0)