diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 589f254dc47..aa01c6f9c7f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -30,15 +30,6 @@ jobs: chmod +x llvm.sh sudo ./llvm.sh 18 sudo apt-get install -y --no-install-recommends clang-format-18 - # buildifier won't install properly if specifying a particular version - go install github.com/bazelbuild/buildtools/buildifier@latest - echo "BUILDIFIER=$HOME/go/bin/buildifier" >> $GITHUB_ENV - - name: Install pnpm - uses: pnpm/action-setup@v4 - # The pnpm version will be determined by the `packageManager` field in `.npmrc` - - name: Install project deps with pnpm - run: | - pnpm i - name: Install Ruff run: | pip install ruff diff --git a/WORKSPACE b/WORKSPACE index 51c4b21a49f..2096ef3f077 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -597,3 +597,39 @@ new_local_repository( visibility = ["//visibility:public"],)""", path = "empty", ) + +# Dev tools +http_file( + name = "buildifier-darwin-arm64", + executable = True, + integrity = "sha256-Wmr8asegn1RVuguJvZnVriO0F03F3J1sDtXOjKrD+BM=", + url = "https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildifier-darwin-arm64", +) + +http_file( + name = "buildifier-darwin-amd64", + executable = True, + integrity = "sha256-Wmr8asegn1RVuguJvZnVriO0F03F3J1sDtXOjKrD+BM=", + url = "https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildifier-darwin-arm64", +) + +http_file( + name = "buildifier-linux-arm64", + executable = True, + integrity = "sha256-C/hsS//69PCO7Xe95bIILkrlA5oR4uiwOYTBc8NKVhw=", + url = "https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildifier-linux-arm64", +) + +http_file( + name = "buildifier-linux-amd64", + executable = True, + integrity = "sha256-VHTMUSinToBng9VAgfWBZixL6K5lAi9VfpKB7V3IgAk=", + url = "https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildifier-linux-amd64", +) + +http_file( + name = "buildifier-windows-amd64", + executable = True, + integrity = "sha256-NwzVdgda0pkwqC9d4TLxod5AhMeEqCUUvU2oDIWs9Kg=", + url = "https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildifier-windows-amd64.exe", +) diff --git a/tools/cross/format.py b/tools/cross/format.py index d98ada9f247..508557b260b 100644 --- a/tools/cross/format.py +++ b/tools/cross/format.py @@ -2,9 +2,11 @@ import logging import os +import platform import re import shutil import subprocess +import sys from argparse import ArgumentParser, Namespace from concurrent.futures import ThreadPoolExecutor, as_completed from dataclasses import dataclass @@ -13,9 +15,10 @@ from typing import Callable, Optional CLANG_FORMAT = os.environ.get("CLANG_FORMAT", "clang-format") -PRETTIER = os.environ.get("PRETTIER", "node_modules/.bin/prettier") +PRETTIER = os.environ.get( + "PRETTIER", "bazel-bin/node_modules/prettier/bin/prettier.cjs" +) RUFF = os.environ.get("RUFF", "ruff") -BUILDIFIER = os.environ.get("BUILDIFIER", "buildifier") def parse_args() -> Namespace: @@ -100,6 +103,33 @@ def matches_any_glob(globs: tuple[str, ...], file: Path) -> bool: return any(file.match(glob) for glob in globs) +def exec_target() -> str: + ALIASES = {"aarch64": "arm64", "x86_64": "amd64", "AMD64": "amd64"} + + machine = platform.machine() + return f"{sys.platform}-{ALIASES.get(machine, machine)}" + + +def run_bazel_tool(tool_name: str, args: list[str]) -> subprocess.CompletedProcess: + external_dir = Path("external") + if not external_dir.exists(): + # Create a symlink to the bazel external directory + bazel_base = Path( + subprocess.run(["bazel", "info", "output_base"], capture_output=True) + .stdout.decode() + .strip() + ) + external_dir.symlink_to(bazel_base / "external") + + tool_target = f"{tool_name}-{exec_target()}" + tool_path = Path("external") / tool_target / "file" / "downloaded" + + if not tool_path.exists(): + subprocess.run(["bazel", "fetch", f"@{tool_target}//file"]) + + return subprocess.run([tool_path, *args]) + + def clang_format(files: list[Path], check: bool = False) -> bool: cmd = [CLANG_FORMAT] if check: @@ -111,14 +141,17 @@ def clang_format(files: list[Path], check: bool = False) -> bool: def prettier(files: list[Path], check: bool = False) -> bool: + if not Path(PRETTIER).exists(): + subprocess.run(["bazel", "build", "//:node_modules/prettier"]) + cmd = [PRETTIER, "--log-level=warn", "--check" if check else "--write"] result = subprocess.run(cmd + files) return result.returncode == 0 def buildifier(files: list[Path], check: bool = False) -> bool: - cmd = [BUILDIFIER, "--mode=check" if check else "--mode=fix"] - result = subprocess.run(cmd + files) + cmd = ["--mode=check" if check else "--mode=fix"] + result = run_bazel_tool("buildifier", cmd + files) return result.returncode == 0 @@ -189,18 +222,18 @@ class FormatConfig: # FormatConfig( # directory="src/workerd", globs=("*.c++", "*.h"), formatter=clang_format # ), - # FormatConfig( - # directory="src", - # globs=("*.js", "*.ts", "*.cjs", "*.ejs", "*.mjs"), - # formatter=prettier, - # ), - # FormatConfig(directory="src", globs=("*.json",), formatter=prettier), + FormatConfig( + directory="src", + globs=("*.js", "*.ts", "*.cjs", "*.ejs", "*.mjs"), + formatter=prettier, + ), + FormatConfig(directory="src", globs=("*.json",), formatter=prettier), # FormatConfig(directory=".", globs=("*.py",), formatter=ruff), - # FormatConfig( - # directory=".", - # globs=("*.bzl", "WORKSPACE", "BUILD", "BUILD.*"), - # formatter=buildifier, - # ), + FormatConfig( + directory=".", + globs=("*.bzl", "WORKSPACE", "BUILD", "BUILD.*"), + formatter=buildifier, + ), ]