mirror of
https://github.com/arvidn/libtorrent.git
synced 2026-07-26 22:11:43 -04:00
105 lines
3.6 KiB
YAML
105 lines
3.6 KiB
YAML
name: Python tools
|
|
|
|
on:
|
|
push:
|
|
branches: [ RC_1_2 RC_2_0 master ]
|
|
pull_request:
|
|
|
|
concurrency:
|
|
group: ${{ github.ref }}-${{ github.workflow }}-${{ github.event_name }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
|
|
tools:
|
|
name: validate tools/
|
|
runs-on: ubuntu-24.04
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 1
|
|
filter: tree:0
|
|
|
|
- uses: actions/setup-python@v6
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
- name: install dependencies
|
|
run: |
|
|
python3 -m pip install --upgrade pip
|
|
# black for formatting; the rest cover the third-party imports
|
|
# used by tools/*.py so the import check below resolves them.
|
|
python3 -m pip install black matplotlib numpy docutils psutil
|
|
|
|
- name: syntax check
|
|
run: |
|
|
# Compile every tools/*.py. Fails on any SyntaxError.
|
|
python3 -m compileall -q tools
|
|
|
|
- name: black formatting check
|
|
run: |
|
|
# Mirror the exclusions in .pre-commit-config.yaml so this CI
|
|
# matches what pre-commit's black hook checks today. When a file
|
|
# is removed from the pre-commit exclude list, drop it here too.
|
|
python3 -m black --check --diff \
|
|
tools/disk_latency.py \
|
|
tools/gen_corpus.py \
|
|
tools/libtorrent_lldb.py \
|
|
tools/parse_piece_downloads.py \
|
|
tools/perf_call_tree.py \
|
|
tools/plot_layout.py \
|
|
tools/test_filesystems.py \
|
|
tools/vmstat.py
|
|
|
|
- name: import resolution check
|
|
run: |
|
|
# For every tools/*.py, walk the module-level imports and verify
|
|
# each name resolves on sys.path. This catches the case where a
|
|
# script imports a sibling module that was never git-added.
|
|
# We use importlib.util.find_spec rather than `import`, because
|
|
# several scripts do real work at module scope (e.g. open(argv[1]))
|
|
# and would crash on import even when nothing is missing.
|
|
python3 <<'PY'
|
|
import ast
|
|
import importlib.util
|
|
import pathlib
|
|
import sys
|
|
|
|
tools = pathlib.Path("tools")
|
|
sys.path.insert(0, str(tools))
|
|
|
|
# lldb's Python bindings ship with LLDB, not PyPI; skip the helper
|
|
# that depends on them rather than installing LLDB in CI.
|
|
skip = {"libtorrent_lldb.py"}
|
|
|
|
def module_level_imports(tree):
|
|
# Only imports executed unconditionally at module load. We skip
|
|
# imports inside try/except (commonly used for optional deps)
|
|
# and inside function/class bodies.
|
|
for node in tree.body:
|
|
if isinstance(node, ast.Import):
|
|
for alias in node.names:
|
|
yield alias.name
|
|
elif isinstance(node, ast.ImportFrom):
|
|
if node.level == 0 and node.module:
|
|
yield node.module
|
|
|
|
errors = []
|
|
for py in sorted(tools.glob("*.py")):
|
|
if py.name in skip:
|
|
continue
|
|
tree = ast.parse(py.read_text())
|
|
for name in module_level_imports(tree):
|
|
try:
|
|
spec = importlib.util.find_spec(name)
|
|
except (ImportError, ValueError):
|
|
spec = None
|
|
if spec is None:
|
|
errors.append(f"{py}: cannot resolve import '{name}'")
|
|
|
|
if errors:
|
|
print("\n".join(errors))
|
|
sys.exit(1)
|
|
PY
|