Created
February 5, 2026 02:21
-
-
Save dims/41e381da9d88158bc0975a6913903ec5 to your computer and use it in GitHub Desktop.
verify-unwanted-deps-classification.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Validates unwantedReferences classifications in unwanted-dependencies.json | |
| # Replicates the logic from cmd/dependencyverifier/dependencyverifier.go | |
| # Usage: ./hack/verify-unwanted-deps-classification.sh [unwanted-module] | |
| set -euo pipefail | |
| KUBE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" | |
| JSON_FILE="${KUBE_ROOT}/hack/unwanted-dependencies.json" | |
| # Replicate runGoListWithoutReplace from dependencyverifier.go | |
| run_go_list_without_replace() { | |
| local moddir=$1 | |
| local tmpdir | |
| tmpdir=$(mktemp -d) | |
| # Copy module contents to temp dir | |
| cp -r "$moddir"/. "$tmpdir" | |
| chmod -R u+w "$tmpdir" | |
| # Remove replace blocks and single replace directives (matching Go logic) | |
| local in_block=false | |
| local new_content="" | |
| while IFS= read -r line || [[ -n "$line" ]]; do | |
| local trimmed="${line#"${line%%[![:space:]]*}"}" | |
| if [[ "$trimmed" == "replace ("* ]] || [[ "$trimmed" == "replace("* ]]; then | |
| in_block=true | |
| continue | |
| fi | |
| if [[ "$in_block" == true ]]; then | |
| [[ "$trimmed" == ")" ]] && in_block=false | |
| continue | |
| fi | |
| [[ "$trimmed" == "replace "* ]] && continue | |
| new_content+="$line"$'\n' | |
| done < "$tmpdir/go.mod" | |
| echo -n "$new_content" > "$tmpdir/go.mod" | |
| # Run go mod tidy then go list | |
| (cd "$tmpdir" && go mod tidy 2>/dev/null) || { rm -rf "$tmpdir"; return 1; } | |
| local output | |
| output=$(cd "$tmpdir" && go list -buildvcs=false -f '{{range .Imports}}{{.}} | |
| {{end}}' ./... 2>/dev/null) || { rm -rf "$tmpdir"; return 1; } | |
| rm -rf "$tmpdir" | |
| echo "$output" | |
| } | |
| # Check if module imports unwanted module (replicates buildModuleImportsMap logic) | |
| check_module_imports() { | |
| local mod=$1 version=$2 unwanted=$3 | |
| local moddir imports | |
| # Download module and get directory | |
| moddir=$(go mod download -json "${mod}@${version}" 2>/dev/null | jq -r '.Dir // empty') || return 1 | |
| [[ -z "$moddir" ]] && return 1 | |
| # Try go list from within module directory (matching Go code: ./...) | |
| if imports=$(cd "$moddir" && go list -buildvcs=false -f '{{range .Imports}}{{.}} | |
| {{end}}' ./... 2>/dev/null); then | |
| # Check if any import starts with unwanted module path | |
| echo "$imports" | grep -q "^${unwanted}" && return 0 || return 1 | |
| fi | |
| # Fallback: copy to temp, strip replace directives | |
| imports=$(run_go_list_without_replace "$moddir") || return 1 | |
| echo "$imports" | grep -q "^${unwanted}" && return 0 || return 1 | |
| } | |
| get_version() { | |
| local mod=$1 | |
| go mod graph 2>/dev/null | grep " ${mod}@" | head -1 | sed 's/.*@//' | |
| } | |
| validate_refs() { | |
| local unwanted=$1 category=$2 | |
| local mods errors=0 | |
| mods=$(jq -r ".status.unwantedReferences[\"$unwanted\"].$category // [] | .[]" "$JSON_FILE" 2>/dev/null) | |
| [[ -z "$mods" ]] && return 0 | |
| for mod in $mods; do | |
| [[ "$mod" == k8s.io/* ]] && continue | |
| version=$(get_version "$mod") | |
| [[ -z "$version" ]] && { echo " WARN: $mod - no version found"; continue; } | |
| if check_module_imports "$mod" "$version" "$unwanted"; then | |
| if [[ "$category" == "goModOnly" ]]; then | |
| echo " FAIL: $mod DOES import $unwanted (should be transitive)" | |
| ((errors++)) || true | |
| fi | |
| else | |
| if [[ "$category" == "transitive" ]]; then | |
| echo " FAIL: $mod does NOT import $unwanted (should be goModOnly)" | |
| ((errors++)) || true | |
| fi | |
| fi | |
| done | |
| return $errors | |
| } | |
| cd "$KUBE_ROOT" | |
| filter="${1:-}" | |
| total_errors=0 | |
| for unwanted in $(jq -r '.status.unwantedReferences | keys[]' "$JSON_FILE"); do | |
| [[ -n "$filter" && "$unwanted" != "$filter" ]] && continue | |
| echo "Checking: $unwanted" | |
| validate_refs "$unwanted" "transitive" || ((total_errors+=$?)) || true | |
| validate_refs "$unwanted" "goModOnly" || ((total_errors+=$?)) || true | |
| done | |
| [[ $total_errors -eq 0 ]] && echo "All classifications verified." || echo "Found $total_errors misclassifications." | |
| exit $total_errors |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment