lintro-add
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAdding a New Tool to Lintro
为Lintro添加新工具
Lintro is a unified CLI for code linting/formatting with a plugin architecture:
tools are defined in (via ),
parsed by , tested in , with sample violation
files in .
lintro/tools/definitions/<tool>.py@register_toollintro/parsers/<tool>/tests/unit/test_samples/tools/Lintro是一款采用插件架构的代码检查/格式化统一CLI工具:工具定义在中(通过装饰器),由解析,在中进行测试,示例违规文件存放于。
lintro/tools/definitions/<tool>.py@register_toollintro/parsers/<tool>/tests/unit/test_samples/tools/Related Skills
相关技能
- : Python coding standards (type hints, docstrings, trailing commas)
stand-py - : pytest best practices (no classes, use fixtures, parametrize)
test - : semantic commit format when committing changes
commit
- :Python编码规范(类型提示、文档字符串、尾随逗号)
stand-py - :pytest最佳实践(不使用类、使用fixture、参数化)
test - :提交变更时遵循语义化提交格式
commit
How to Implement: Copy a Reference, Don't Write From Scratch
实现方式:参考现有实现,不要从零编写
Do NOT write plugin/parser/test code from a template. Pick the closest existing
implementation, read all of its files (definition, issue class, parser, parser
, sample violation file, parser tests, plugin tests), and mirror
that structure exactly for the new tool:
__init__.py- Simple tool (no fix): ,
lintro/tools/definitions/actionlint.pyhadolint.py - Tool with fix support: ,
lintro/tools/definitions/ruff.pyblack.py - Security scanner: ,
lintro/tools/definitions/bandit.pysemgrep.py - Shell tools: ,
lintro/tools/definitions/shellcheck.pyshfmt.py
The parser lives in and its tests in
and — copy the pattern
from the same reference tool so imports, mocking, and naming stay consistent.
lintro/parsers/<reference-tool>/tests/unit/parsers/tests/unit/tools/<reference-tool>/请勿从模板编写插件/解析器/测试代码。选择最接近的现有实现,阅读其所有文件(定义、问题类、解析器、解析器、示例违规文件、解析器测试、插件测试),并完全镜像该结构来实现新工具:
__init__.py- 无修复功能的简单工具:、
lintro/tools/definitions/actionlint.pyhadolint.py - 支持修复功能的工具:、
lintro/tools/definitions/ruff.pyblack.py - 安全扫描工具:、
lintro/tools/definitions/bandit.pysemgrep.py - Shell工具:、
lintro/tools/definitions/shellcheck.pyshfmt.py
解析器位于,其测试文件在和中——复制同一参考工具的模式,确保导入、模拟和命名保持一致。
lintro/parsers/<reference-tool>/tests/unit/parsers/tests/unit/tools/<reference-tool>/Quick Reference
快速参考
New files (paths)
新增文件(路径)
text
lintro/parsers/<tool>/__init__.py
lintro/parsers/<tool>/<tool>_issue.py
lintro/parsers/<tool>/<tool>_parser.py
lintro/tools/definitions/<tool>.py
test_samples/tools/<category>/<tool>/<tool>_violations.<ext>
tests/unit/parsers/test_<tool>_parser.py
tests/unit/tools/<tool>/__init__.py
tests/unit/tools/<tool>/test_<tool>_plugin.pytext
lintro/parsers/<tool>/__init__.py
lintro/parsers/<tool>/<tool>_issue.py
lintro/parsers/<tool>/<tool>_parser.py
lintro/tools/definitions/<tool>.py
test_samples/tools/<category>/<tool>/<tool>_violations.<ext>
tests/unit/parsers/test_<tool>_parser.py
tests/unit/tools/<tool>/__init__.py
tests/unit/tools/<tool>/test_<tool>_plugin.pyUpdated files (paths)
需要更新的文件(路径)
text
lintro/enums/tool_name.py # Add to ToolName enum (alphabetical)
lintro/tools/core/version_parsing.py # Add to TOOLS_WITH_SIMPLE_VERSION_PATTERN
lintro/tools/core/version_checking.py # Add install hints in get_install_hints()
lintro/_tool_versions.py # Add version (external tools only)
lintro/tools/manifest.json # Add tool entry (version MUST match _tool_versions.py)
lintro/cli_utils/commands/doctor.py # Add to TOOL_COMMANDS for health check
package.json # Add version for npm tools (must match _tool_versions.py)
renovate.json # Add custom managers for BOTH _tool_versions.py AND manifest.json
pyproject.toml # Add parser package + [tool.lintro.versions] entry
Dockerfile # Add to verification steps (root AND non-root blocks)
Dockerfile.tools # Add to verification step (tool --version)
scripts/utils/install-tools.sh # Add installation command (external tools)
scripts/ci/homebrew/templates/lintro.rb.template # Add depends_on + update caveats (if Homebrew-installable)For every updated file, find an existing tool's entry in that file and add the new
tool the same way (alphabetical order where the file is ordered).
text
lintro/enums/tool_name.py # 按字母顺序添加至ToolName枚举
lintro/tools/core/version_parsing.py # 添加至TOOLS_WITH_SIMPLE_VERSION_PATTERN
lintro/tools/core/version_checking.py # 在get_install_hints()中添加安装提示
lintro/_tool_versions.py # 添加版本号(仅限外部工具)
lintro/tools/manifest.json # 添加工具条目(版本必须与_tool_versions.py匹配)
lintro/cli_utils/commands/doctor.py # 添加至TOOL_COMMANDS以支持健康检查
package.json # 为npm工具添加版本号(必须与_tool_versions.py匹配)
renovate.json # 为_tool_versions.py和manifest.json添加自定义管理器
pyproject.toml # 添加解析器包 + [tool.lintro.versions]条目
Dockerfile # 添加至验证步骤(root和非root代码块)
Dockerfile.tools # 添加至验证步骤(tool --version)
scripts/utils/install-tools.sh # 添加安装命令(仅限外部工具)
scripts/ci/homebrew/templates/lintro.rb.template # 添加depends_on + 更新说明(如果支持Homebrew安装)对于每个需要更新的文件,找到现有工具的条目,以相同方式添加新工具(文件按顺序排列时需保持字母顺序)。
Version Consistency (CRITICAL for external tools)
版本一致性(外部工具至关重要)
For external tools (not bundled Python packages), versions must be consistent across:
- — source of truth for install-tools.sh
lintro/_tool_versions.py - — must match
lintro/tools/manifest.jsonfor binary/cargo/rustup tools_tool_versions.py - — for npm tools, must match
package.json_tool_versions.py - Plugin — in the tool definition, should match or be <=
min_version_tool_versions.py - — must have custom regex managers updating BOTH
renovate.jsonAND_tool_versions.py(copy an existing tool's pair of entries and adjust the package name and datasource)manifest.json
CI enforces manifest/version sync with the manifest generator run in
mode (the generate-with---check pattern from — no separate verify
script). PRs fail if versions drift between these files. Run the generator
with locally before pushing.
--checkstand-ci--check对于外部工具(非捆绑Python包),版本必须在以下文件中保持一致:
- —— install-tools.sh的版本数据源
lintro/_tool_versions.py - —— 对于二进制/cargo/rustup工具,必须与
lintro/tools/manifest.json匹配_tool_versions.py - —— 对于npm工具,必须与
package.json匹配_tool_versions.py - 插件—— 在工具定义中,应等于或小于
min_version中的版本_tool_versions.py - —— 必须包含自定义正则管理器,同时更新
renovate.json和_tool_versions.py(复制现有工具的条目对,调整包名和数据源)manifest.json
CI会通过模式运行的清单生成器来强制清单与版本同步(采用的generate-with---check模式,无需单独的验证脚本)。如果这些文件之间版本不一致,PR将失败。推送前请在本地运行带参数的生成器。
--checkstand-ci--checkHomebrew Formula (for Homebrew-installable tools)
Homebrew公式(支持Homebrew安装的工具)
- Add to
depends_on "<tool>"and list the tool in the caveats under the appropriate category.scripts/ci/homebrew/templates/lintro.rb.template - Bundled Python tools (ruff, black, mypy, bandit, yamllint) are excluded from the
Homebrew venv via ; they install as separate Homebrew formulae and are discovered via PATH (
generate_resources.py --exclude), NOTshutil.which.python -minPythonBundledBuilderhandles this automatically.command_builders.py
- 在中添加
scripts/ci/homebrew/templates/lintro.rb.template,并在对应分类的说明中列出该工具。depends_on "<tool>" - 捆绑的Python工具(ruff、black、mypy、bandit、yamllint)通过排除在Homebrew虚拟环境之外;它们作为独立的Homebrew公式安装,并通过PATH(
generate_resources.py --exclude)被发现,而非shutil.which。python -m中的command_builders.py会自动处理此逻辑。PythonBundledBuilder
ToolType Options
ToolType选项
python
ToolType.LINTER # Code quality checker
ToolType.FORMATTER # Code formatter
ToolType.TYPE_CHECKER # Type checking (mypy)
ToolType.DOCUMENTATION # Doc checker (darglint)
ToolType.SECURITY # Security scanner (bandit, semgrep, gitleaks)
ToolType.INFRASTRUCTURE # IaC linter (hadolint, actionlint)
ToolType.TEST_RUNNER # Test framework (pytest)Can be combined:
ToolType.LINTER | ToolType.FORMATTERpython
ToolType.LINTER # 代码质量检查器
ToolType.FORMATTER # 代码格式化工具
ToolType.TYPE_CHECKER # 类型检查工具(如mypy)
ToolType.DOCUMENTATION # 文档检查工具(如darglint)
ToolType.SECURITY # 安全扫描工具(如bandit、semgrep、gitleaks)
ToolType.INFRASTRUCTURE # IaC检查工具(如hadolint、actionlint)
ToolType.TEST_RUNNER # 测试框架(如pytest)可组合使用:
ToolType.LINTER | ToolType.FORMATTERCommon Gotchas
常见注意事项
- Version command variations: some tools use instead of
version(e.g.,--version). Check the tool's CLI.gitleaks version - ToolResult invariant for fix operations:
.
initial_issues_count = fixed_issues_count + remaining_issues_count - Test mocking: mock the version check with
and subprocess calls with
patch("lintro.plugins.execution_preparation.verify_tool_version", return_value=None)— copy the patterns from a reference tool's plugin tests.patch.object(plugin, "_run_subprocess", ...) - File discovery: handles filtering by
_prepare_execution(); usefile_patternsfor the filtered list.ctx.rel_files - Subprocess safety: always use list args, never ; add
shell=Trueon the subprocess import.# nosec B404 - Return early: if is True, return
ctx.should_skip.ctx.early_result - Parser function naming: must be
.
parse_<tool>_output(output: str | None) -> list[<Tool>Issue] - Issue class: must inherit from ; use
BaseIssuefor custom field name mappings.DISPLAY_FIELD_MAP
- 版本命令差异:部分工具使用而非
version(例如--version)。请检查工具的CLI文档。gitleaks version - 修复操作的ToolResult不变量:。
initial_issues_count = fixed_issues_count + remaining_issues_count - 测试模拟:使用模拟版本检查,使用
patch("lintro.plugins.execution_preparation.verify_tool_version", return_value=None)模拟子进程调用——复制参考工具插件测试中的模式。patch.object(plugin, "_run_subprocess", ...) - 文件发现:会根据
_prepare_execution()处理过滤;使用file_patterns获取过滤后的文件列表。ctx.rel_files - 子进程安全:始终使用列表参数,切勿使用;在子进程导入时添加
shell=True。# nosec B404 - 提前返回:如果为True,返回
ctx.should_skip。ctx.early_result - 解析器函数命名:必须为格式。
parse_<tool>_output(output: str | None) -> list[<Tool>Issue] - 问题类:必须继承自;使用
BaseIssue自定义字段名称映射。DISPLAY_FIELD_MAP
Deprecated Patterns to Avoid
需避免的已弃用模式
- Do NOT create tool-specific formatters (use the unified formatter)
- Do NOT modify (deleted — registry is automatic)
lintro/tools/tool_enum.py - Do NOT modify (deleted — use BaseToolPlugin)
lintro/tools/core/tool_base.py
- 请勿创建工具专属格式化器(使用统一格式化器)
- 请勿修改(已删除——注册为自动机制)
lintro/tools/tool_enum.py - 请勿修改(已删除——使用BaseToolPlugin)
lintro/tools/core/tool_base.py
Verification Checklist
验证清单
- shows the new tool
uv run lintro tools - runs without error — single-tool runs are normally banned by the
uv run lintro check --tools <tool> .skill; this is the explicit sanctioned exception for verifying a tool under development. Still finish with a fulllint.uv run lintro chk - shows the tool with correct version (no "No cmd defined")
uv run lintro doctor - Tool detects violations in the sample file
- Parser unit tests pass:
pytest tests/unit/parsers/test_<tool>_parser.py -v - Plugin unit tests pass:
pytest tests/unit/tools/<tool>/ -v - Coverage >80% on new code
- No linting errors:
uv run lintro fmt && uv run lintro chk - Manifest generator passes in mode (no version drift)
--check - Tool added to (root and non-root blocks) and
DockerfileDockerfile.tools - Tool added to (external tools only)
install-tools.sh - Tool added to (version matches
lintro/tools/manifest.json)_tool_versions.py - Renovate managers added for BOTH and
_tool_versions.pymanifest.json - Homebrew template updated with + caveats (if Homebrew-installable)
depends_on - Docker image builds:
docker build -t py-lintro:test .
Use the skill for the full post-implementation review.
lintro-verify- 显示新工具
uv run lintro tools - 可正常运行无错误——通常
uv run lintro check --tools <tool> .技能禁止单工具运行;这是验证开发中工具的明确例外。完成后仍需运行完整的lint。uv run lintro chk - 显示工具及其正确版本(无"No cmd defined"提示)
uv run lintro doctor - 工具可检测到示例文件中的违规内容
- 解析器单元测试通过:
pytest tests/unit/parsers/test_<tool>_parser.py -v - 插件单元测试通过:
pytest tests/unit/tools/<tool>/ -v - 新增代码覆盖率>80%
- 无代码检查错误:
uv run lintro fmt && uv run lintro chk - 清单生成器在模式下通过(无版本不一致)
--check - 工具已添加至(root和非root代码块)和
DockerfileDockerfile.tools - 工具已添加至(仅限外部工具)
install-tools.sh - 工具已添加至(版本与
lintro/tools/manifest.json匹配)_tool_versions.py - 已为和
_tool_versions.py添加Renovate管理器manifest.json - Homebrew模板已更新+ 说明(如果支持Homebrew安装)
depends_on - Docker镜像可构建:
docker build -t py-lintro:test .
使用技能进行完整的实现后审查。
lintro-verify