|
1 | | -# Code formatter. |
| 1 | +# Code formatter - runs targeted formatters based on what changed from trunk. |
| 2 | +# Usage: format.ps1 [-All] [-PreCommit] [-PrePush] [-Lint] |
| 3 | +# (default) Check all changes relative to trunk including uncommitted work |
| 4 | +# -All Format everything, skip change detection |
| 5 | +# -PreCommit Only check staged changes |
| 6 | +# -PrePush Only check committed changes relative to trunk |
| 7 | +# -Lint Also run linters before formatting |
| 8 | + |
| 9 | +param( |
| 10 | + [switch]$All, |
| 11 | + [switch]$PreCommit, |
| 12 | + [switch]$PrePush, |
| 13 | + [switch]$Lint |
| 14 | +) |
2 | 15 |
|
3 | 16 | Set-StrictMode -Version 'Latest' |
4 | 17 | $ErrorActionPreference = 'Stop' |
5 | 18 |
|
| 19 | +# Validate mutually exclusive flags |
| 20 | +if ($PreCommit -and $PrePush) { |
| 21 | + Write-Error "Cannot use both -PreCommit and -PrePush" |
| 22 | + exit 1 |
| 23 | +} |
| 24 | + |
6 | 25 | function section($message) { |
7 | 26 | Write-Host "- $message" -ForegroundColor Green |
8 | 27 | } |
9 | 28 |
|
| 29 | +# Find what's changed compared to trunk (skip if -All) |
| 30 | +$formatAll = $All |
| 31 | +$trunkRef = git rev-parse --verify trunk 2>$null |
| 32 | + |
| 33 | +if (-not $formatAll -and $trunkRef) { |
| 34 | + $base = git merge-base HEAD $trunkRef 2>$null |
| 35 | + if ($base) { |
| 36 | + if ($PreCommit) { |
| 37 | + $changed = git diff --name-only --cached |
| 38 | + } elseif ($PrePush) { |
| 39 | + $changed = git diff --name-only $base HEAD |
| 40 | + } else { |
| 41 | + $committed = git diff --name-only $base HEAD |
| 42 | + $staged = git diff --name-only --cached |
| 43 | + $unstaged = git diff --name-only |
| 44 | + $untracked = git ls-files --others --exclude-standard |
| 45 | + $changed = ($committed + $staged + $unstaged + $untracked) | Sort-Object -Unique |
| 46 | + } |
| 47 | + } else { |
| 48 | + $formatAll = $true |
| 49 | + } |
| 50 | +} elseif (-not $formatAll) { |
| 51 | + # No trunk ref found, format everything |
| 52 | + $formatAll = $true |
| 53 | +} |
| 54 | + |
| 55 | +# Helper to check if a pattern matches changed files |
| 56 | +function changedMatches($pattern) { |
| 57 | + if ($formatAll) { return $true } |
| 58 | + return ($changed | Where-Object { $_ -match $pattern }).Count -gt 0 |
| 59 | +} |
| 60 | + |
10 | 61 | $WORKSPACE_ROOT = (bazel info workspace) |
11 | | -$GOOGLE_JAVA_FORMAT = (bazel run --run_under=echo //scripts:google-java-format) |
12 | 62 |
|
| 63 | +# Capture baseline to detect formatter-introduced changes |
| 64 | +$baseline = git status --porcelain |
| 65 | + |
| 66 | +# Always run buildifier and copyright |
13 | 67 | section "Buildifier" |
14 | | -Write-Host " buildifier" -ForegroundColor Green |
| 68 | +Write-Host " buildifier" |
15 | 69 | bazel run //:buildifier |
16 | 70 |
|
17 | | -section "Java" |
18 | | -Write-Host " google-java-format" -ForegroundColor Green |
19 | | -Get-ChildItem -Path "$PWD/java" -Include "*.java" -Recurse | ForEach-Object { |
20 | | - &"$GOOGLE_JAVA_FORMAT" --replace $_.FullName |
| 71 | +section "Copyright" |
| 72 | +Write-Host " update_copyright" |
| 73 | +bazel run //scripts:update_copyright |
| 74 | + |
| 75 | +# Run language formatters only if those files changed |
| 76 | +if (changedMatches '^java/') { |
| 77 | + section "Java" |
| 78 | + Write-Host " google-java-format" |
| 79 | + $GOOGLE_JAVA_FORMAT = (bazel run --run_under=echo //scripts:google-java-format) |
| 80 | + Get-ChildItem -Path "$WORKSPACE_ROOT/java" -Include "*.java" -Recurse | ForEach-Object { |
| 81 | + & "$GOOGLE_JAVA_FORMAT" --replace $_.FullName |
| 82 | + } |
21 | 83 | } |
22 | 84 |
|
23 | | -section "Javascript" |
24 | | -Write-Host " javascript/selenium-webdriver - prettier" -ForegroundColor Green |
25 | | -$NODE_WEBDRIVER = "$WORKSPACE_ROOT/javascript/selenium-webdriver" |
26 | | -bazel run //javascript:prettier -- "$NODE_WEBDRIVER" --write "$NODE_WEBDRIVER/.prettierrc" --log-level=warn |
| 85 | +if (changedMatches '^javascript/selenium-webdriver/') { |
| 86 | + section "JavaScript" |
| 87 | + Write-Host " prettier" |
| 88 | + $NODE_WEBDRIVER = "$WORKSPACE_ROOT/javascript/selenium-webdriver" |
| 89 | + bazel run //javascript:prettier -- "$NODE_WEBDRIVER" --write "$NODE_WEBDRIVER/.prettierrc" --log-level=warn |
| 90 | +} |
27 | 91 |
|
28 | | -section "Ruby" |
29 | | -Write-Host " rubocop" -ForegroundColor Green |
30 | | -bazel run //rb:lint |
| 92 | +if (changedMatches '^rb/|^rake_tasks/|^Rakefile') { |
| 93 | + section "Ruby" |
| 94 | + Write-Host " rubocop -a" |
| 95 | + if ($Lint) { |
| 96 | + bazel run //rb:rubocop -- -a |
| 97 | + } else { |
| 98 | + bazel run //rb:rubocop -- -a --fail-level F |
| 99 | + } |
| 100 | +} |
31 | 101 |
|
32 | | -section "Rust" |
33 | | -Write-Host " rustfmt" -ForegroundColor Green |
34 | | -bazel run @rules_rust//:rustfmt |
| 102 | +if (changedMatches '^rust/') { |
| 103 | + section "Rust" |
| 104 | + Write-Host " rustfmt" |
| 105 | + bazel run @rules_rust//:rustfmt |
| 106 | +} |
35 | 107 |
|
36 | | -section "Python" |
37 | | -Write-Host " python - ruff" -ForegroundColor Green |
38 | | -bazel run //py:ruff-format |
| 108 | +if (changedMatches '^py/') { |
| 109 | + section "Python" |
| 110 | + if ($Lint) { |
| 111 | + Write-Host " ruff check" |
| 112 | + bazel run //py:ruff-check |
| 113 | + } |
| 114 | + Write-Host " ruff format" |
| 115 | + bazel run //py:ruff-format |
| 116 | +} |
39 | 117 |
|
40 | | -section "Copyright" |
41 | | -bazel run //scripts:update_copyright |
| 118 | +if (changedMatches '^dotnet/') { |
| 119 | + section ".NET" |
| 120 | + Write-Host " dotnet format" |
| 121 | + bazel run //dotnet:format -- style --severity warn |
| 122 | + bazel run //dotnet:format -- whitespace |
| 123 | +} |
| 124 | + |
| 125 | +# Run shellcheck and actionlint when -Lint is passed |
| 126 | +if ($Lint) { |
| 127 | + section "Shell/Actions" |
| 128 | + Write-Host " actionlint (with shellcheck)" |
| 129 | + $SHELLCHECK = (bazel run --run_under=echo @multitool//tools/shellcheck) |
| 130 | + bazel run @multitool//tools/actionlint:cwd -- -shellcheck "$SHELLCHECK" |
| 131 | +} |
| 132 | + |
| 133 | +# Check if formatting introduced new changes (comparing to baseline) |
| 134 | +$after = git status --porcelain |
| 135 | +if ($after -ne $baseline) { |
| 136 | + Write-Host "" |
| 137 | + Write-Host "Formatters modified files:" -ForegroundColor Red |
| 138 | + git diff --name-only |
| 139 | + exit 1 |
| 140 | +} |
| 141 | + |
| 142 | +Write-Host "Format check passed." -ForegroundColor Green |
0 commit comments