-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
Expand file tree
/
Copy pathformat.sh
More file actions
executable file
·147 lines (128 loc) · 4.57 KB
/
format.sh
File metadata and controls
executable file
·147 lines (128 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env bash
# Code formatter - runs targeted formatters based on what changed from trunk.
# Usage: format.sh [--all] [--pre-commit] [--pre-push] [--lint]
# (default) Check all changes relative to trunk including uncommitted work
# --all Format everything, skip change detection (previous behavior)
# --pre-commit Only check staged changes
# --pre-push Only check committed changes relative to trunk
# --lint Also run linters before formatting
set -eufo pipefail
run_lint=false
format_all=false
mode="default"
for arg in "$@"; do
case "$arg" in
--lint) run_lint=true ;;
--all) format_all=true ;;
--pre-commit|--pre-push)
[[ "$mode" == "default" ]] || { echo "Cannot use both --pre-commit and --pre-push" >&2; exit 1; }
mode="${arg#--}"
;;
*)
echo "Unknown option: $arg" >&2
echo "Usage: $0 [--all] [--pre-commit] [--pre-push] [--lint]" >&2
exit 1
;;
esac
done
section() {
echo "- $*" >&2
}
# Find what's changed compared to trunk (skip if --all)
trunk_ref="$(git rev-parse --verify trunk 2>/dev/null || echo "")"
if [[ "$format_all" == "false" && -n "$trunk_ref" ]]; then
base="$(git merge-base HEAD "$trunk_ref" 2>/dev/null || echo "")"
if [[ -n "$base" ]]; then
case "$mode" in
pre-commit)
changed="$(git diff --name-only --cached)"
;;
pre-push)
changed="$(git diff --name-only "$base" HEAD)"
;;
default)
committed="$(git diff --name-only "$base" HEAD)"
staged="$(git diff --name-only --cached)"
unstaged="$(git diff --name-only)"
untracked="$(git ls-files --others --exclude-standard)"
changed="$(printf '%s\n%s\n%s\n%s' "$committed" "$staged" "$unstaged" "$untracked" | sort -u)"
;;
esac
else
format_all=true
fi
elif [[ "$format_all" == "false" ]]; then
# No trunk ref found, format everything
format_all=true
fi
# Helper to check if a pattern matches changed files
changed_matches() {
[[ "$format_all" == "true" ]] || echo "$changed" | grep -qE "$1"
}
WORKSPACE_ROOT="$(bazel info workspace)"
# Capture baseline to detect formatter-introduced changes (allows pre-existing uncommitted work)
baseline="$(git status --porcelain)"
# Always run buildifier and copyright
section "Buildifier"
echo " buildifier" >&2
bazel run //:buildifier
section "Copyright"
echo " update_copyright" >&2
bazel run //scripts:update_copyright
# Run language formatters only if those files changed
if changed_matches '^java/'; then
section "Java"
echo " google-java-format" >&2
GOOGLE_JAVA_FORMAT="$(bazel run --run_under=echo //scripts:google-java-format)"
find "${WORKSPACE_ROOT}/java" -type f -name '*.java' -exec "$GOOGLE_JAVA_FORMAT" --replace {} +
fi
if changed_matches '^javascript/selenium-webdriver/'; then
section "JavaScript"
echo " prettier" >&2
NODE_WEBDRIVER="${WORKSPACE_ROOT}/javascript/selenium-webdriver"
bazel run //javascript:prettier -- "${NODE_WEBDRIVER}" --write "${NODE_WEBDRIVER}/.prettierrc" --log-level=warn
fi
if changed_matches '^rb/|^rake_tasks/|^Rakefile'; then
section "Ruby"
echo " rubocop -a" >&2
if [[ "$run_lint" == "true" ]]; then
bazel run //rb:rubocop -- -a
else
bazel run //rb:rubocop -- -a --fail-level F
fi
fi
if changed_matches '^rust/'; then
section "Rust"
echo " rustfmt" >&2
bazel run @rules_rust//:rustfmt
fi
if changed_matches '^py/'; then
section "Python"
if [[ "$run_lint" == "true" ]]; then
echo " ruff check" >&2
bazel run //py:ruff-check
fi
echo " ruff format" >&2
bazel run //py:ruff-format
fi
if changed_matches '^dotnet/'; then
section ".NET"
echo " dotnet format" >&2
bazel run //dotnet:format -- style --severity warn
bazel run //dotnet:format -- whitespace
fi
# Run shellcheck and actionlint when --lint is passed
if [[ "$run_lint" == "true" ]]; then
section "Shell/Actions"
echo " actionlint (with shellcheck)" >&2
SHELLCHECK="$(bazel run --run_under=echo @multitool//tools/shellcheck)"
bazel run @multitool//tools/actionlint:cwd -- -shellcheck "$SHELLCHECK"
fi
# Check if formatting introduced new changes (comparing to baseline)
if [[ "$(git status --porcelain)" != "$baseline" ]]; then
echo "" >&2
echo "Formatters modified files:" >&2
git diff --name-only >&2
exit 1
fi
echo "Format check passed." >&2