From f7bace3ed2a5d378ebd4608bf1832ced483a1371 Mon Sep 17 00:00:00 2001 From: Juan Hernandez Date: Fri, 12 Jun 2026 10:09:45 +0200 Subject: [PATCH] NO-ISSUE: Use `uv run dev.py lint` from the pre-commit hook The pre-commit hook was calling `bin/golangci-lint` directly, which meant that the tool had to be installed separately before linting could work. This changes the hook to call `uv run dev.py lint` instead, so that the project's development tooling manages the linter lifecycle end to end. To support this the `lint` command now calls `setup.install_golangci_lint` before running the linter, making it self-contained. The `is_installed` helper in `setup.py` is also updated to look in the project's `bin/` directory first and to use the resolved path when checking the installed version, so it correctly detects tools already downloaded by previous runs. Because `lint` now installs its own dependencies, the separate `uv run dev.py setup` step in the CI workflow is no longer needed and has been removed. Assisted-by: Cursor Signed-off-by: Juan Hernandez --- .github/workflows/check-pull-request.yaml | 1 - .pre-commit-config.yaml | 2 +- dev/lint.py | 5 ++- dev/setup.py | 54 ++++++++++++++--------- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/.github/workflows/check-pull-request.yaml b/.github/workflows/check-pull-request.yaml index 93967f0b9..921a342b2 100644 --- a/.github/workflows/check-pull-request.yaml +++ b/.github/workflows/check-pull-request.yaml @@ -56,7 +56,6 @@ jobs: - uses: ./.github/actions/setup-go - uses: ./.github/actions/setup-python - run: | - uv run dev.py setup uv run dev.py lint check-generated-code: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e0e8c18c6..519baaa47 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,4 +27,4 @@ repos: name: golangci-lint language: system files: \.go$ - entry: bin/golangci-lint run --fix + entry: uv run dev.py lint diff --git a/dev/lint.py b/dev/lint.py index 359e67428..b1b6c6386 100755 --- a/dev/lint.py +++ b/dev/lint.py @@ -18,7 +18,7 @@ import click from . import commands -from . import tools +from . import setup @click.command() @@ -27,7 +27,8 @@ def lint() -> None: Runs the linter. """ logging.info("Running linter") + setup.install_golangci_lint() commands.run( - args=[tools.GOLANGCI_LINT.name, "run"], + args=["golangci-lint", "run"], check=True, ) diff --git a/dev/setup.py b/dev/setup.py index 04e9ee727..684d67f1c 100755 --- a/dev/setup.py +++ b/dev/setup.py @@ -140,28 +140,38 @@ def install_golangci_lint() -> None: def is_installed(tool: tools.Tool) -> bool: """ - Checks if the given tool is already installed. + Checks if the given tool is already installed. It first looks in the project's bin directory, + then falls back to the system PATH. """ - installed_path = shutil.which(tool.name) - if installed_path is not None: - tool_code, tool_out = commands.eval(args=tool.version_command) - if tool_code != 0: - raise Exception(f"Failed to find version of installed '{tool.name}'") - version_match = re.search( - pattern=tool.version_pattern, - string=tool_out, - flags=re.MULTILINE, - ) - if version_match is None: - raise Exception(f"Failed to find version of installed '{tool.name}'") - installed_version = version_match.group("version") - if installed_version == tool.version: - logging.info( - f"Version {tool.version} of '{tool.name}' is already installed at '{installed_path}'" - ) - return True + # Check the project bin directory first, then the system path: + bin_path = dirs.bin() / tool.name + if bin_path.exists(): + installed_path = str(bin_path) + else: + installed_path = shutil.which(tool.name) + if installed_path is None: + return False + + # Build the version command using the resolved path so we check the right binary: + version_command = [installed_path] + tool.version_command[1:] + tool_code, tool_out = commands.eval(args=version_command) + if tool_code != 0: + raise Exception(f"Failed to find version of installed '{tool.name}'") + version_match = re.search( + pattern=tool.version_pattern, + string=tool_out, + flags=re.MULTILINE, + ) + if version_match is None: + raise Exception(f"Failed to find version of installed '{tool.name}'") + installed_version = version_match.group("version") + if installed_version == tool.version: logging.info( - f"Found '{tool.name}' already installed at '{installed_path}', but version is '{installed_version}' " - f"instead of '{tool.version}'" + f"Version {tool.version} of '{tool.name}' is already installed at '{installed_path}'" ) - return False + return True + logging.info( + f"Found '{tool.name}' already installed at '{installed_path}', but version is '{installed_version}' " + f"instead of '{tool.version}'" + ) + return False