Files
goose/scripts/clippy-baseline.sh
Michael Neale e78a1e7d4e feat: codex subscription support (#6600)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Adrian Cole <adrian@tetrate.io>
2026-01-23 17:11:58 +11:00

162 lines
5.0 KiB
Bash
Executable File

#!/bin/bash
# Baseline clippy rules - only fail on NEW violations
#
# Format: "rule_name|violation_parser"
#
# Violation parsers (run clippy on your rule to see which fits):
# function_name - When spans show: "fn my_function(..."
# type_name - When spans show: "struct MyStruct" or "enum MyEnum"
# file_only - When spans show file-level issues
#
# Note: If your rule doesn't fit these parsers, you may need to add a new parser
# to the parse_violation() function below
#
# To add new rules:
# 1. Add rule below: "clippy::your_rule|violation_parser"
# 2. Generate baseline: ./scripts/clippy-baseline.sh generate clippy::your_rule
BASELINE_RULES=(
"clippy::too_many_lines|function_name"
)
parse_violation() {
local rule_code="$1"
local violation_parser="$2"
case "$violation_parser" in
"function_name")
jq -r 'select(.message.code.code == "'"$rule_code"'") |
.message.spans[0] as $span |
($span.text | map(.text) | map(select(test("\\bfn\\b"))) | first // "") as $line |
if $line == "" then empty else "\($span.file_name)::\($line | capture("fn\\s+(?<name>[a-z_][a-z0-9_]*)") | .name)" end'
;;
"type_name")
jq -r 'select(.message.code.code == "'"$rule_code"'") |
"\(.message.spans[0].file_name)::\(.message.spans[0].text[0].text | split(" ")[1] | split(" ")[0])"'
;;
"file_only")
jq -r 'select(.message.code.code == "'"$rule_code"'") |
"\(.message.spans[0].file_name)"'
;;
*)
echo "Unknown violation parser: $violation_parser" >&2
exit 1
;;
esac
}
get_baseline_file() {
local rule_name="$1"
local safe_name=$(echo "$rule_name" | sed 's/clippy:://' | sed 's/:/-/g')
echo "clippy-baselines/${safe_name}.txt"
}
generate_baseline() {
local rule_name="$1"
[[ -z "$rule_name" ]] && { echo "Missing rule name"; return 1; }
local violation_parser=""
for rule in "${BASELINE_RULES[@]}"; do
[[ "${rule%|*}" == "$rule_name" ]] && { violation_parser="${rule#*|}"; break; }
done
[[ -z "$violation_parser" ]] && { echo "Unknown rule: $rule_name"; return 1; }
local baseline_file=$(get_baseline_file "$rule_name")
cargo clippy --jobs 2 --message-format=json -- -W "$rule_name" | \
parse_violation "$rule_name" "$violation_parser" | \
sort > "$baseline_file"
echo "✅ Generated baseline for $rule_name ($(wc -l < "$baseline_file") violations)"
}
# Check a single rule from pre-generated JSON (optimized version)
check_rule_from_json() {
local temp_json="$1"
local rule_name="$2"
local violation_parser="$3"
local baseline_file="$4"
echo " → Checking $rule_name"
if [[ ! -f "$baseline_file" ]]; then
echo "$rule_name: baseline file not found"
return 1
fi
local temp_parsed=$(mktemp)
cat "$temp_json" | parse_violation "$rule_name" "$violation_parser" | sort > "$temp_parsed"
local new_violations_file=$(mktemp)
diff <(sort "$baseline_file") <(sort "$temp_parsed") | grep "^>" | cut -c3- > "$new_violations_file"
if [[ -s "$new_violations_file" ]]; then
echo "$rule_name: NEW violations found:"
while IFS= read -r violation; do
# Extract all violations for this rule and find the matching one
cat "$temp_json" | jq -c 'select(.message.code.code == "'"$rule_name"'")' 2>/dev/null | while read -r json_line; do
parsed_id=$(echo "$json_line" | parse_violation "$rule_name" "$violation_parser")
if [[ "$parsed_id" == "$violation" ]]; then
echo "$json_line" | jq -r '.message.rendered' | sed 's/^/ /'
fi
done
done < "$new_violations_file"
rm "$temp_parsed" "$new_violations_file"
return 1
fi
rm "$new_violations_file"
echo "$rule_name: ok"
rm "$temp_parsed"
return 0
}
check_all_baseline_rules() {
echo "🔍 Checking baseline clippy rules..."
local clippy_flags=""
for rule in "${BASELINE_RULES[@]}"; do
local rule_name="${rule%|*}"
clippy_flags="$clippy_flags -W $rule_name"
done
local temp_json=$(mktemp)
cargo clippy --jobs 2 --message-format=json -- $clippy_flags | tee "$temp_json"
local failed_rules=()
# Check each rule against its baseline
for rule in "${BASELINE_RULES[@]}"; do
local rule_name="${rule%|*}"
local violation_parser="${rule#*|}"
local baseline_file=$(get_baseline_file "$rule_name")
if ! check_rule_from_json "$temp_json" "$rule_name" "$violation_parser" "$baseline_file"; then
failed_rules+=("$rule_name")
fi
done
rm "$temp_json"
if [[ ${#failed_rules[@]} -gt 0 ]]; then
echo ""
echo "❌ Failed baseline checks for: ${failed_rules[*]}"
exit 1
else
echo ""
echo "✅ All baseline clippy checks passed!"
fi
}
if [[ "$1" == "generate" ]]; then
generate_baseline "$2"
fi