pyfltr 3.3.2__tar.gz → 3.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. {pyfltr-3.3.2 → pyfltr-3.3.4}/.github/workflows/ci.yaml +6 -6
  2. {pyfltr-3.3.2 → pyfltr-3.3.4}/.github/workflows/docs.yaml +1 -1
  3. {pyfltr-3.3.2 → pyfltr-3.3.4}/.github/workflows/release.yaml +1 -1
  4. {pyfltr-3.3.2 → pyfltr-3.3.4}/PKG-INFO +6 -6
  5. {pyfltr-3.3.2 → pyfltr-3.3.4}/README.md +4 -5
  6. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/guide/configuration-tools.md +25 -7
  7. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/guide/index.md +1 -1
  8. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/guide/recommended-nonpython.md +3 -4
  9. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/guide/recommended.md +1 -1
  10. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/guide/usage.md +1 -1
  11. {pyfltr-3.3.2 → pyfltr-3.3.4}/mise.toml +0 -1
  12. {pyfltr-3.3.2 → pyfltr-3.3.4}/mkdocs.yml +1 -1
  13. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/command.py +0 -1
  14. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/config.py +9 -2
  15. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyproject.toml +1 -0
  16. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/command_core_test.py +13 -13
  17. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/config_test.py +34 -2
  18. {pyfltr-3.3.2 → pyfltr-3.3.4}/uv.lock +288 -264
  19. {pyfltr-3.3.2 → pyfltr-3.3.4}/.claude/agents/error-parser-reviewer.md +0 -0
  20. {pyfltr-3.3.2 → pyfltr-3.3.4}/.claude/agents/tool-compat-checker.md +0 -0
  21. {pyfltr-3.3.2 → pyfltr-3.3.4}/.claude/skills/pyfltr-add-tool/SKILL.md +0 -0
  22. {pyfltr-3.3.2 → pyfltr-3.3.4}/.editorconfig +0 -0
  23. {pyfltr-3.3.2 → pyfltr-3.3.4}/.gitattributes +0 -0
  24. {pyfltr-3.3.2 → pyfltr-3.3.4}/.gitignore +0 -0
  25. {pyfltr-3.3.2 → pyfltr-3.3.4}/.gitmessage +0 -0
  26. {pyfltr-3.3.2 → pyfltr-3.3.4}/.markdownlint-cli2.yaml +0 -0
  27. {pyfltr-3.3.2 → pyfltr-3.3.4}/.npmrc +0 -0
  28. {pyfltr-3.3.2 → pyfltr-3.3.4}/.pre-commit-config.yaml +0 -0
  29. {pyfltr-3.3.2 → pyfltr-3.3.4}/.pylintrc +0 -0
  30. {pyfltr-3.3.2 → pyfltr-3.3.4}/.python-version +0 -0
  31. {pyfltr-3.3.2 → pyfltr-3.3.4}/.textlintignore +0 -0
  32. {pyfltr-3.3.2 → pyfltr-3.3.4}/.textlintrc.yaml +0 -0
  33. {pyfltr-3.3.2 → pyfltr-3.3.4}/.vscode/extensions.json +0 -0
  34. {pyfltr-3.3.2 → pyfltr-3.3.4}/.vscode/settings.json +0 -0
  35. {pyfltr-3.3.2 → pyfltr-3.3.4}/CLAUDE.md +0 -0
  36. {pyfltr-3.3.2 → pyfltr-3.3.4}/LICENSE +0 -0
  37. {pyfltr-3.3.2 → pyfltr-3.3.4}/Makefile +0 -0
  38. {pyfltr-3.3.2 → pyfltr-3.3.4}/cliff.toml +0 -0
  39. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/.markdownlint-cli2.yaml +0 -0
  40. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/development/architecture.md +0 -0
  41. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/development/archive-and-cache.md +0 -0
  42. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/development/development.md +0 -0
  43. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/development/index.md +0 -0
  44. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/development/jsonl-output.md +0 -0
  45. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/development/mcp-server.md +0 -0
  46. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/development/subcommands.md +0 -0
  47. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/guide/configuration.md +0 -0
  48. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/guide/custom-commands.md +0 -0
  49. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/guide/migration-v3.md +0 -0
  50. {pyfltr-3.3.2 → pyfltr-3.3.4}/docs/index.md +0 -0
  51. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/__init__.py +0 -0
  52. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/__main__.py +0 -0
  53. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/archive.py +0 -0
  54. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/builtin_commands.py +0 -0
  55. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/cache.py +0 -0
  56. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/cli.py +0 -0
  57. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/code_quality.py +0 -0
  58. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/error_parser.py +0 -0
  59. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/executor.py +0 -0
  60. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/formatters.py +0 -0
  61. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/github_annotations.py +0 -0
  62. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/llm_output.py +0 -0
  63. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/main.py +0 -0
  64. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/mcp_.py +0 -0
  65. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/only_failed.py +0 -0
  66. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/paths.py +0 -0
  67. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/precommit.py +0 -0
  68. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/presets.py +0 -0
  69. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/retry.py +0 -0
  70. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/rule_urls.py +0 -0
  71. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/runs.py +0 -0
  72. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/sarif_output.py +0 -0
  73. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/shell_completion.py +0 -0
  74. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/stage_runner.py +0 -0
  75. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/ui.py +0 -0
  76. {pyfltr-3.3.2 → pyfltr-3.3.4}/pyfltr/warnings_.py +0 -0
  77. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/__init__.py +0 -0
  78. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/archive_test.py +0 -0
  79. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/cache_test.py +0 -0
  80. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/cli_test.py +0 -0
  81. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/code_quality_test.py +0 -0
  82. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/command_linter_fix_test.py +0 -0
  83. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/command_prettier_test.py +0 -0
  84. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/command_ruff_format_test.py +0 -0
  85. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/command_textlint_fix_test.py +0 -0
  86. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/conftest.py +0 -0
  87. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/error_parser_test.py +0 -0
  88. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/executor_test.py +0 -0
  89. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/github_annotations_test.py +0 -0
  90. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/llm_output_test.py +0 -0
  91. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/main_test.py +0 -0
  92. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/mcp_test.py +0 -0
  93. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/only_failed_test.py +0 -0
  94. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/output_format_test.py +0 -0
  95. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/paths_test.py +0 -0
  96. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/precommit_test.py +0 -0
  97. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/retry_test.py +0 -0
  98. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/rule_urls_test.py +0 -0
  99. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/runs_test.py +0 -0
  100. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/sarif_output_test.py +0 -0
  101. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/shell_completion_test.py +0 -0
  102. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/stage_runner_test.py +0 -0
  103. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/ui_test.py +0 -0
  104. {pyfltr-3.3.2 → pyfltr-3.3.4}/tests/warnings_test.py +0 -0
@@ -37,7 +37,7 @@ jobs:
37
37
  pinact run --check
38
38
 
39
39
  - name: Install uv
40
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
40
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
41
41
  with:
42
42
  python-version: ${{ matrix.python-version }}
43
43
  enable-cache: true
@@ -48,7 +48,7 @@ jobs:
48
48
  node-version: "lts/*"
49
49
 
50
50
  - name: Setup pnpm
51
- uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v6.0.0
51
+ uses: pnpm/action-setup@078e9d416474b29c0c387560859308974f7e9c53 # v6.0.1
52
52
  with:
53
53
  version: latest
54
54
 
@@ -59,7 +59,7 @@ jobs:
59
59
  id: pnpm-store
60
60
  run: echo "STORE_PATH=$(pnpm store path)" >> "$GITHUB_OUTPUT"
61
61
 
62
- - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
62
+ - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
63
63
  with:
64
64
  path: ${{ steps.pnpm-store.outputs.STORE_PATH }}
65
65
  key: pnpm-store-${{ runner.os }}
@@ -83,7 +83,7 @@ jobs:
83
83
  - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
84
84
 
85
85
  - name: Install uv
86
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
86
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
87
87
  with:
88
88
  python-version: "3.14"
89
89
  enable-cache: true
@@ -94,7 +94,7 @@ jobs:
94
94
  node-version: "lts/*"
95
95
 
96
96
  - name: Setup pnpm
97
- uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v6.0.0
97
+ uses: pnpm/action-setup@078e9d416474b29c0c387560859308974f7e9c53 # v6.0.1
98
98
  with:
99
99
  version: latest
100
100
 
@@ -106,7 +106,7 @@ jobs:
106
106
  shell: bash
107
107
  run: echo "STORE_PATH=$(pnpm store path)" >> "$GITHUB_OUTPUT"
108
108
 
109
- - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
109
+ - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
110
110
  with:
111
111
  path: ${{ steps.pnpm-store-win.outputs.STORE_PATH }}
112
112
  key: pnpm-store-${{ runner.os }}
@@ -30,7 +30,7 @@ jobs:
30
30
  - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
31
31
 
32
32
  - name: Install uv
33
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
33
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
34
34
 
35
35
  - name: Install dependencies
36
36
  run: uv sync --all-extras --all-groups
@@ -117,7 +117,7 @@ jobs:
117
117
  fi
118
118
 
119
119
  - name: Install uv
120
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
120
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
121
121
  with:
122
122
  python-version: "3.14"
123
123
  enable-cache: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyfltr
3
- Version: 3.3.2
3
+ Version: 3.3.4
4
4
  Summary: Python Formatters, Linters, and Testers Runner.
5
5
  Project-URL: Homepage, https://github.com/ak110/pyfltr
6
6
  Author-email: "aki." <mark@aur.ll.to>
@@ -24,6 +24,7 @@ Requires-Dist: psutil>=6.0
24
24
  Requires-Dist: python-ulid>=3.0
25
25
  Requires-Dist: pyyaml>=6.0.3
26
26
  Requires-Dist: textual>=8.0.0
27
+ Requires-Dist: typos>=1.0
27
28
  Provides-Extra: python
28
29
  Requires-Dist: dill>=0.3; extra == 'python'
29
30
  Requires-Dist: mypy>=1.0; extra == 'python'
@@ -49,14 +50,13 @@ formatter・linter・testerを単一コマンドで並列実行するCLIツー
49
50
 
50
51
  ## 特徴
51
52
 
52
- - 多言語対応のformatter・linter・testerをまとめて呼び出す単一コマンド
53
+ - formatter・linter・testerをまとめて呼び出す
53
54
  - 複数ツールの並列実行による総実行時間の短縮
55
+ - LLMエージェント向けJSON Lines出力
54
56
  - 設定の集約: `pyproject.toml`に寄せた統一設定
55
57
  - 除外指定(exclude)の書式差をツール間で吸収
56
- - 自動修正系ツール(ruff format・prettierなど)を修正と失敗扱いの両立で実行
57
- - LLMエージェント向けJSON Lines出力(`pyfltr run-for-agent`・`PYFLTR_OUTPUT_FORMAT`環境変数・`--output-format=jsonl`)に対応
58
- - MCPサーバーを本体同梱(`pyfltr mcp`)。Claude Desktopなどのエージェントから直接lint実行・アーカイブ参照が行える
59
- - シェル補完スクリプト生成(`pyfltr generate-shell-completion`)に対応
58
+ - MCPサーバー
59
+ - シェル補完スクリプト生成
60
60
 
61
61
  ## インストール
62
62
 
@@ -10,14 +10,13 @@ formatter・linter・testerを単一コマンドで並列実行するCLIツー
10
10
 
11
11
  ## 特徴
12
12
 
13
- - 多言語対応のformatter・linter・testerをまとめて呼び出す単一コマンド
13
+ - formatter・linter・testerをまとめて呼び出す
14
14
  - 複数ツールの並列実行による総実行時間の短縮
15
+ - LLMエージェント向けJSON Lines出力
15
16
  - 設定の集約: `pyproject.toml`に寄せた統一設定
16
17
  - 除外指定(exclude)の書式差をツール間で吸収
17
- - 自動修正系ツール(ruff format・prettierなど)を修正と失敗扱いの両立で実行
18
- - LLMエージェント向けJSON Lines出力(`pyfltr run-for-agent`・`PYFLTR_OUTPUT_FORMAT`環境変数・`--output-format=jsonl`)に対応
19
- - MCPサーバーを本体同梱(`pyfltr mcp`)。Claude Desktopなどのエージェントから直接lint実行・アーカイブ参照が行える
20
- - シェル補完スクリプト生成(`pyfltr generate-shell-completion`)に対応
18
+ - MCPサーバー
19
+ - シェル補完スクリプト生成
21
20
 
22
21
  ## インストール
23
22
 
@@ -4,11 +4,11 @@
4
4
 
5
5
  pyfltrは対応ツールを実行方式の観点から次の3カテゴリに分けて扱う。
6
6
 
7
- - 直接実行: Python系ツール、Rust系(cargo系)、.NET系(dotnet系)など。
7
+ - 直接実行: Python系ツール、Rust系(cargo系)、.NET系(dotnet系)、typosなど。
8
8
  PATH上または`{command}-path`で指定した実行ファイルを直接呼び出す
9
9
  - js-runner経由: eslint / prettier / biome / oxlint / tsc / vitest / markdownlint-cli2 / textlintなど。
10
10
  npm / pnpm / yarn等のJavaScriptパッケージマネージャー経由で起動する
11
- - bin-runner経由: ec / shellcheck / shfmt / typos / actionlintなど。miseやPATH経由でネイティブバイナリを解決する
11
+ - bin-runner経由: ec / shellcheck / shfmt / actionlintなど。miseやPATH経由でネイティブバイナリを解決する
12
12
 
13
13
  本ページではまず全カテゴリ共通の設定を示し、続いて各カテゴリ固有の設定を説明する。
14
14
 
@@ -63,7 +63,7 @@ pass-filenames = false
63
63
 
64
64
  ## 直接実行ツール
65
65
 
66
- Python系ツール、Rust系(cargo系)、.NET系(dotnet系)、uv-sortはいずれも`{command}-path`で指定した
66
+ Python系ツール、Rust系(cargo系)、.NET系(dotnet系)、uv-sort、typosはいずれも`{command}-path`で指定した
67
67
  実行ファイルをpyfltrが直接呼び出す。
68
68
  特別な起動経路を挟まないため、miseやnpm等のランナー設定は不要。
69
69
 
@@ -169,6 +169,26 @@ dotnet-test-path = "/path/to/dotnet"
169
169
  - dotnet-build: `dotnet-build-args = ["build", "--nologo"]`
170
170
  - dotnet-test: `dotnet-test-args = ["test", "--nologo"]`
171
171
 
172
+ ### typos
173
+
174
+ `typos`はスペルチェッカー。PyPI経由でインストールされるため、`uv add pyfltr`だけで利用可能。
175
+
176
+ ```toml
177
+ [tool.pyfltr]
178
+ typos = true
179
+ ```
180
+
181
+ 既定の引数は`typos-args = ["--format", "brief"]`。
182
+ `typos-path`を変更したい場合は明示的に指定する。
183
+
184
+ ```toml
185
+ [tool.pyfltr]
186
+ typos-path = "/path/to/typos"
187
+ ```
188
+
189
+ プロジェクト固有の許可語がある場合は`[tool.typos]`セクションも追記する
190
+ (詳細は[推奨設定例](recommended.md)の「typosの許可語設定」を参照)。
191
+
172
192
  ## js-runner経由で実行するツール
173
193
 
174
194
  markdownlint-cli2 / textlint / eslint / prettier / biome / oxlint / tsc / vitestは`js-runner`設定で起動方式を切り替える。
@@ -314,13 +334,13 @@ javascript = true
314
334
 
315
335
  - oxlint: `oxlint-args = []`
316
336
  - tsc: `tsc-args = ["--noEmit"]`、`tsc-pass-filenames = false`(プロジェクト全体をチェックするためファイル引数を渡さない)
317
- - vitest: `vitest-args = ["run"]`(`run`サブコマンドが必須)
337
+ - vitest: `vitest-args = ["run", "--passWithNoTests"]`(`run`サブコマンドが必須、filter結果ゼロ時もsuccess扱い)
318
338
 
319
339
  個別に無効化したい場合のみ`{command} = false`を指定する。
320
340
 
321
341
  ## bin-runner経由で実行するツール
322
342
 
323
- ec / shellcheck / shfmt / typos / actionlintはネイティブバイナリ(Go/Rust/Haskell製等)で、
343
+ ec / shellcheck / shfmt / actionlintはネイティブバイナリ(Go/Haskell製等)で、
324
344
  `bin-runner`設定で起動方式を切り替える。
325
345
  ecはeditorconfig-checkerの略称。既定は`mise`で、[mise](https://mise.jdx.dev/)によるバージョン管理付きの実行となる。
326
346
 
@@ -389,7 +409,6 @@ miseモードでは`mise exec <tool>@<version> -- <command>`として展開さ
389
409
  ec = true
390
410
  shellcheck = true
391
411
  shfmt = true
392
- typos = true
393
412
  actionlint = true
394
413
  ```
395
414
 
@@ -398,7 +417,6 @@ actionlint = true
398
417
  - ec: `ec-args = ["-format", "gcc", "-no-color"]`
399
418
  - shellcheck: `shellcheck-args = ["-f", "gcc"]`
400
419
  - shfmt: `shfmt-check-args = ["-l"]` / `shfmt-write-args = ["-w"]`(2段階実行。共通引数は`shfmt-args`で指定)
401
- - typos: `typos-args = ["--format", "brief"]`
402
420
  - actionlint: `actionlint-args = []`
403
421
 
404
422
  `{command}-path`を明示的に設定した場合はその値が優先され、bin-runnerによる自動解決は無効化される。
@@ -53,7 +53,7 @@
53
53
  ### その他
54
54
 
55
55
  - Formatters: shfmt(既定で無効)
56
- - Linters: ec(editorconfig-checker、既定で無効)/ shellcheck(既定で無効)/ typos / actionlint
56
+ - Linters: ec(editorconfig-checker、既定で無効)/ shellcheck(既定で無効)/ typos(PyPI依存)/ actionlint
57
57
  - 統合: pre-commit(`.pre-commit-config.yaml`のhookを統合実行)
58
58
 
59
59
  プリセット指定と言語カテゴリゲートによる有効化の詳細は[設定項目](configuration.md)を参照。
@@ -3,12 +3,11 @@
3
3
  Python以外のプロジェクトでもpyfltrを活用できる。共通のポイントは以下。
4
4
 
5
5
  - `preset = "latest"`: 各時点での推奨ツール構成。
6
- ドキュメント系(markdownlint / textlint / actionlint / typos / pre-commit)はいずれの言語ゲートにも属さず常に有効化される
6
+ ドキュメント系(textlint / markdownlint / actionlint / typos / pre-commit)はいずれの言語ゲートにも属さず常に有効化される
7
7
  - 言語カテゴリゲートの詳細は[設定項目](configuration.md)を参照
8
8
  - `uvx pyfltr`: pyfltrをdev依存に含めないため、`uvx`で都度取得して実行する
9
9
  - 言語固有のツール + ドキュメント系lint(textlint / markdownlint / prettier)を組み合わせる
10
- - `bin-runner`のデフォルトは`"mise"`。actionlint / typos等のネイティブバイナリツールはmise経由で呼び出されるため、
11
- mise導入とツールのセットアップ(`mise use actionlint@latest typos@latest`等)を推奨する
10
+ - `bin-runner`のデフォルトは`"mise"`。actionlint等のネイティブバイナリツールはmise経由で呼び出されるため、mise導入を推奨する
12
11
  - タスクランナー(Makefile / mise.toml)の設定例は[推奨設定例](recommended.md)の「タスクランナー」を参照
13
12
 
14
13
  ## TypeScript/JS専用プロジェクト
@@ -52,7 +51,7 @@ extend-exclude = [
52
51
  - `js-runner = "pnpm"`: pnpmワークスペース経由でJS系ツールを呼ぶ。`textlint-packages`は無視される
53
52
  - eslintとoxlintは併用するとeslintで非対応のルールを補完できる(Rust製のため高速)
54
53
  - tsc: TypeScript型チェックも実行できる。svelte-checkなどフレームワーク固有のチェッカーと併用する場合はどちらか一方でよい
55
- - vitest: `vitest-args = ["run"]`が既定のため追加引数は不要
54
+ - vitest: `vitest-args = ["run", "--passWithNoTests"]`が既定のため追加引数は不要
56
55
  - 使わないツールは個別に`{command} = false`で無効化できる
57
56
  - svelte-checkなどフレームワーク固有のツールはカスタムコマンドで追加する
58
57
  ([カスタムコマンド例](custom-commands.md)の「svelte-check」を参照)
@@ -137,7 +137,7 @@ PEP 695型パラメーター構文(`def f[T](): ...`)を使用するプロ
137
137
  - `--frozen`: `uv run`が依存解決を再実行せず`uv.lock`をそのまま使うようにする(サプライチェーン攻撃対策)。
138
138
  - `fast`: mypy / pylint / pytestなど重いコマンドを除外した高速サブセット。
139
139
  formatterがファイルを修正しただけではフックを失敗と判定しない。pre-commitは対話的フックのため速度を優先する。
140
- - `types_or`: 必要な種別を列挙する。markdownはmarkdownlint / textlint、TOML(pyproject.toml)でuv-sort。
140
+ - `types_or`: 必要な種別を列挙する。markdownはtextlint / markdownlint、TOML(pyproject.toml)でuv-sort。
141
141
  - `require_serial: true`: pyfltr自身が内部で並列化するため、pre-commit側での多重起動を避ける。
142
142
 
143
143
  注意: pre-commitのlocal hookから`pyfltr`を呼び出した場合、pyfltrは`PRE_COMMIT=1`環境変数を検出する。
@@ -190,7 +190,7 @@ pyfltr generate-shell-completion powershell | Out-String | Invoke-Expression
190
190
  一例を以下に示す。
191
191
 
192
192
  - Python系ツール: `*.py`
193
- - markdownlint / textlint: `*.md`
193
+ - textlint / markdownlint: `*.md`
194
194
  - pytest: `*_test.py`
195
195
 
196
196
  ### `fast` / `run` / `run-for-agent` / `ci`の動作の違いと自動修正(fixステージ)
@@ -1,3 +1,2 @@
1
1
  [tools]
2
2
  actionlint = "latest"
3
- typos = "latest"
@@ -50,7 +50,7 @@ plugins:
50
50
 
51
51
  ## 対応ツール
52
52
 
53
- 対応カテゴリはPython系・Rust系(cargo系)・.NET系(dotnet系)・JS/TS系・ドキュメント系(markdownlint-cli2・textlint)・その他(ec・shellcheck・shfmt・typos・actionlint・pre-commit)。
53
+ 対応カテゴリはPython系・Rust系(cargo系)・.NET系(dotnet系)・JS/TS系・ドキュメント系(markdownlint-cli2・textlint)・その他(ec・shellcheck・shfmt・actionlint・pre-commit)。typosはpyfltr本体の依存として同梱されており追加インストール不要。
54
54
  個別ツールの網羅的な一覧と詳細は[対応ツール一覧](guide/index.md)を参照。
55
55
 
56
56
  `preset = "latest"` で各時点の推奨ツール構成を選べる。プリセットは Python / JavaScript / TypeScript / Rust / .NET / ドキュメント系を横断的に収録し、言語カテゴリキー (`python` / `javascript` / `rust` / `dotnet`) がゲートとして働く。`preset = "latest"` + `{language} = true` の組み合わせだけで当該言語の推奨ツール一式が有効化される。
@@ -149,7 +149,6 @@ _BIN_TOOL_SPEC: dict[str, BinToolSpec] = {
149
149
  "ec": BinToolSpec(bin_name="ec", mise_backend="editorconfig-checker"),
150
150
  "shellcheck": BinToolSpec(bin_name="shellcheck"),
151
151
  "shfmt": BinToolSpec(bin_name="shfmt"),
152
- "typos": BinToolSpec(bin_name="typos"),
153
152
  "actionlint": BinToolSpec(bin_name="actionlint"),
154
153
  }
155
154
 
@@ -285,7 +285,7 @@ DEFAULT_CONFIG: dict[str, typing.Any] = {
285
285
  "shellcheck-version": "latest",
286
286
  "shellcheck-fast": True,
287
287
  "typos": False,
288
- "typos-path": "",
288
+ "typos-path": "typos",
289
289
  "typos-args": ["--format", "brief"],
290
290
  "typos-version": "latest",
291
291
  "typos-fast": True,
@@ -301,7 +301,10 @@ DEFAULT_CONFIG: dict[str, typing.Any] = {
301
301
  "pytest-fast": False,
302
302
  "vitest": False,
303
303
  "vitest-path": "",
304
- "vitest-args": ["run"], # vitest は run サブコマンドが必須
304
+ # vitest は run サブコマンドが必須。また、pyfltr が targets 設定で絞ったファイル群と
305
+ # プロジェクト側の vitest include 設定が交差せず対象ゼロになるケースで rc=1 となり
306
+ # failed 扱いになるのを避けるため、--passWithNoTests を既定に含める。
307
+ "vitest-args": ["run", "--passWithNoTests"],
305
308
  "vitest-fast": False,
306
309
  "ruff-format": False,
307
310
  "ruff-format-path": "ruff",
@@ -591,6 +594,10 @@ def load_config(config_dir: pathlib.Path | None = None) -> Config:
591
594
  existing.extend(extra)
592
595
  config.commands[cmd_name] = dataclasses.replace(config.commands[cmd_name], targets=existing)
593
596
 
597
+ # typos-path の互換正規化: generate-config が出力した空文字列を "typos" へ変換する
598
+ if config.values["typos-path"] == "":
599
+ config.values["typos-path"] = "typos"
600
+
594
601
  # js-runner の値バリデーション
595
602
  js_runner = config.values["js-runner"]
596
603
  if js_runner not in JS_RUNNERS:
@@ -26,6 +26,7 @@ dependencies = [
26
26
  "python-ulid>=3.0",
27
27
  "pyyaml>=6.0.3",
28
28
  "textual>=8.0.0",
29
+ "typos>=1.0",
29
30
  ]
30
31
 
31
32
  [project.optional-dependencies]
@@ -553,9 +553,9 @@ def test_resolve_bin_commandline_mise_success(mocker) -> None:
553
553
  mocker.patch(
554
554
  "subprocess.run",
555
555
  return_value=subprocess.CompletedProcess(
556
- ["mise", "exec", "typos@latest", "--", "typos", "--version"],
556
+ ["mise", "exec", "shellcheck@latest", "--", "shellcheck", "--version"],
557
557
  returncode=0,
558
- stdout="typos 1.0.0",
558
+ stdout="shellcheck 0.9.0",
559
559
  stderr="",
560
560
  ),
561
561
  )
@@ -563,10 +563,10 @@ def test_resolve_bin_commandline_mise_success(mocker) -> None:
563
563
  config = pyfltr.config.create_default_config()
564
564
  config.values["bin-runner"] = "mise"
565
565
 
566
- path, prefix = pyfltr.command._resolve_bin_commandline("typos", config)
566
+ path, prefix = pyfltr.command._resolve_bin_commandline("shellcheck", config)
567
567
 
568
568
  assert path == "mise"
569
- assert prefix == ["exec", "typos@latest", "--", "typos"]
569
+ assert prefix == ["exec", "shellcheck@latest", "--", "shellcheck"]
570
570
 
571
571
 
572
572
  def test_resolve_bin_commandline_mise_custom_version(mocker) -> None:
@@ -647,7 +647,7 @@ def test_resolve_bin_commandline_mise_untrusted_auto_trust_success(mocker) -> No
647
647
  subprocess.CompletedProcess(
648
648
  ["mise", "exec"],
649
649
  returncode=0,
650
- stdout="typos 1.0.0",
650
+ stdout="shellcheck 0.9.0",
651
651
  stderr="",
652
652
  ),
653
653
  ],
@@ -657,10 +657,10 @@ def test_resolve_bin_commandline_mise_untrusted_auto_trust_success(mocker) -> No
657
657
  config.values["bin-runner"] = "mise"
658
658
  config.values["mise-auto-trust"] = True
659
659
 
660
- path, prefix = pyfltr.command._resolve_bin_commandline("typos", config)
660
+ path, prefix = pyfltr.command._resolve_bin_commandline("shellcheck", config)
661
661
 
662
662
  assert path == "mise"
663
- assert prefix == ["exec", "typos@latest", "--", "typos"]
663
+ assert prefix == ["exec", "shellcheck@latest", "--", "shellcheck"]
664
664
  # 事前チェック → trust → リトライの3回が実際に発生したことを確認
665
665
  assert mock_run.call_count == 3
666
666
 
@@ -683,7 +683,7 @@ def test_resolve_bin_commandline_mise_untrusted_auto_trust_disabled(mocker) -> N
683
683
  config.values["mise-auto-trust"] = False
684
684
 
685
685
  with pytest.raises(FileNotFoundError, match="not trusted"):
686
- pyfltr.command._resolve_bin_commandline("typos", config)
686
+ pyfltr.command._resolve_bin_commandline("shellcheck", config)
687
687
 
688
688
  # trust コマンドは呼ばれていないことを確認(subprocess.run の呼び出しは1回のみ)
689
689
  assert mock_run.call_count == 1
@@ -698,7 +698,7 @@ def test_resolve_bin_commandline_mise_other_error_no_retry(mocker) -> None:
698
698
  ["mise", "exec"],
699
699
  returncode=1,
700
700
  stdout="",
701
- stderr="mise ERROR plugin not found: typos",
701
+ stderr="mise ERROR plugin not found: shellcheck",
702
702
  ),
703
703
  )
704
704
 
@@ -707,7 +707,7 @@ def test_resolve_bin_commandline_mise_other_error_no_retry(mocker) -> None:
707
707
  config.values["mise-auto-trust"] = True
708
708
 
709
709
  with pytest.raises(FileNotFoundError, match="plugin not found"):
710
- pyfltr.command._resolve_bin_commandline("typos", config)
710
+ pyfltr.command._resolve_bin_commandline("shellcheck", config)
711
711
 
712
712
  # trust コマンドは呼ばれていないことを確認(subprocess.run の呼び出しは1回のみ)
713
713
  assert mock_run.call_count == 1
@@ -748,7 +748,7 @@ def test_resolve_bin_commandline_mise_untrusted_auto_trust_retry_failure(mocker)
748
748
  config.values["mise-auto-trust"] = True
749
749
 
750
750
  with pytest.raises(FileNotFoundError, match="some other failure after trust"):
751
- pyfltr.command._resolve_bin_commandline("typos", config)
751
+ pyfltr.command._resolve_bin_commandline("shellcheck", config)
752
752
 
753
753
 
754
754
  def test_resolve_bin_commandline_mise_untrusted_auto_trust_trust_failure(mocker) -> None:
@@ -779,7 +779,7 @@ def test_resolve_bin_commandline_mise_untrusted_auto_trust_trust_failure(mocker)
779
779
  config.values["mise-auto-trust"] = True
780
780
 
781
781
  with pytest.raises(FileNotFoundError, match="permission denied"):
782
- pyfltr.command._resolve_bin_commandline("typos", config)
782
+ pyfltr.command._resolve_bin_commandline("shellcheck", config)
783
783
 
784
784
 
785
785
  def test_failed_resolution_result() -> None:
@@ -841,7 +841,7 @@ def test_pass_filenames_true_includes_targets(mocker, tmp_path: pathlib.Path) ->
841
841
 
842
842
  def test_bin_tool_spec_all_tools_defined() -> None:
843
843
  """_BIN_TOOL_SPECに全bin系ツールが定義されている。"""
844
- expected_tools = {"ec", "shellcheck", "shfmt", "typos", "actionlint"}
844
+ expected_tools = {"ec", "shellcheck", "shfmt", "actionlint"}
845
845
  assert set(pyfltr.command._BIN_TOOL_SPEC.keys()) == expected_tools
846
846
 
847
847
 
@@ -349,6 +349,17 @@ fix-args = "--fix"
349
349
  pyfltr.config.load_config(config_dir=tmp_path)
350
350
 
351
351
 
352
+ def test_vitest_args_default_contains_pass_with_no_tests() -> None:
353
+ """vitest-args の既定に --passWithNoTests が含まれることのテスト。
354
+
355
+ pyfltr が targets 設定で絞ったファイル群とプロジェクト側の vitest include
356
+ 設定が交差せず対象ゼロになるケースで rc=1 → failed 扱いになるのを避けるため、
357
+ 既定引数として含める方針を固定化する。
358
+ """
359
+ config = pyfltr.config.create_default_config()
360
+ assert config["vitest-args"] == ["run", "--passWithNoTests"]
361
+
362
+
352
363
  def test_js_runner_default() -> None:
353
364
  """js-runner の既定値は pnpx (従来互換)。"""
354
365
  config = pyfltr.config.create_default_config()
@@ -982,8 +993,8 @@ path = "my-checker"
982
993
  def test_bin_tool_default_config_values() -> None:
983
994
  """bin-runner対応ツールのデフォルト設定値が正しく定義されている。"""
984
995
  config = pyfltr.config.create_default_config()
985
- # bin系ツールの有効/無効とバージョン設定を確認
986
- bin_tools = ["ec", "shellcheck", "shfmt", "typos", "actionlint"]
996
+ # bin-runner経由ツールの有効/無効とバージョン設定を確認
997
+ bin_tools = ["ec", "shellcheck", "shfmt", "actionlint"]
987
998
  for tool in bin_tools:
988
999
  assert config[tool] is False, f"{tool}は既定で無効"
989
1000
  assert config[f"{tool}-path"] == "", f"{tool}-pathは空文字"
@@ -999,6 +1010,27 @@ def test_bin_tool_default_config_values() -> None:
999
1010
  assert config["tsc-pass-filenames"] is False
1000
1011
 
1001
1012
 
1013
+ def test_typos_default_config_values() -> None:
1014
+ """typosはPyPI依存として直接実行するため、pathはコマンド名・versionは互換維持で残す。"""
1015
+ config = pyfltr.config.create_default_config()
1016
+ assert config["typos"] is False, "typosは既定で無効"
1017
+ assert config["typos-path"] == "typos", "typos-pathはコマンド名"
1018
+ # typos-versionは既存ユーザーの設定との互換維持のため定義を残す
1019
+ assert config["typos-version"] == "latest", "typos-versionはlatest(互換維持)"
1020
+ assert config["typos-fast"] is True, "typos-fastはTrue"
1021
+
1022
+
1023
+ def test_typos_path_empty_string_normalized(tmp_path: pathlib.Path) -> None:
1024
+ """load_config で typos-path = "" を読み込んだ場合に "typos" へ正規化される。"""
1025
+ pyproject_content = """
1026
+ [tool.pyfltr]
1027
+ typos-path = ""
1028
+ """
1029
+ (tmp_path / "pyproject.toml").write_text(pyproject_content)
1030
+ config = pyfltr.config.load_config(config_dir=tmp_path)
1031
+ assert config["typos-path"] == "typos"
1032
+
1033
+
1002
1034
  def test_uv_sort_in_python_commands() -> None:
1003
1035
  """uv-sortがPYTHON_COMMANDSに含まれる。"""
1004
1036
  assert "uv-sort" in pyfltr.config.PYTHON_COMMANDS