github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/hack/prune-libraries.sh (about) 1 #!/bin/bash 2 # Copyright 2018 The Kubernetes Authors. 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 16 17 # Identifies go_library() bazel targets in the workspace with no dependencies. 18 # Deletes the target and its files. Cleans up any :all-srcs references 19 20 # By default just checks for extra libraries, run with --fix to make changes. 21 22 23 set -o nounset 24 set -o errexit 25 set -o pipefail 26 27 # This list is used for rules in vendor/ which may not have any explicit 28 # dependencies outside of vendor, e.g. helper commands we have vendored. 29 # It should probably match the list in Gopkg.toml. 30 REQUIRED=( 31 //vendor/github.com/bazelbuild/bazel-gazelle/cmd/gazelle:gazelle 32 //vendor/github.com/golang/dep/cmd/dep:dep 33 //vendor/github.com/client9/misspell/cmd/misspell:misspell 34 //vendor/github.com/kubernetes/repo-infra/kazel:kazel 35 ) 36 37 # darwin is great 38 SED=sed 39 if which gsed &>/dev/null; then 40 SED=gsed 41 fi 42 if ! ($SED --version 2>&1 | grep -q GNU); then 43 echo "!!! GNU sed is required. If on OS X, use 'brew install gnu-sed'." >&2 44 exit 1 45 fi 46 47 unused-go-libraries() { 48 # Find all the go_library rules in vendor except those that something outside 49 # of vendor eventually depends on. 50 required_items=( "${REQUIRED[@]/#/+ }" ) 51 echo "Looking for //vendor targets that no one outside of //vendor depends on..." >&2 52 bazel query "kind('go_library rule', //vendor/... -deps(//... -//vendor/... ${required_items[@]}))" 53 } 54 55 # Output this:source.go that:file.txt sources of //this //that targets 56 target-sources() { 57 (for i in "$@"; do 58 bazel query "kind(\"source file\", deps(\"$(package-name "$i"):package-srcs\", 1))" 59 done) | sort -u 60 } 61 62 sources() { 63 local t 64 for j in $(target-sources "${@}"); do 65 case "$(target-name "$j")" in 66 LICENSE*|PATENTS*|*.md) # Keep these files 67 continue 68 ;; 69 esac 70 echo $(package-name "${j:2}")/$(target-name $j) 71 done 72 } 73 74 # Convert //foo:and/bar:stuff to //foo:and/bar 75 package-name() { 76 echo ${1%:*} 77 } 78 79 # Convert //foo:and/bar:stuff to stuff 80 target-name() { 81 echo ${1##*:} 82 } 83 84 # Find every package that directly depends on //foo:all-srcs 85 all-srcs-refs() { 86 packages $(for i in "$@"; do 87 bazel query "rdeps(//..., \"${i}:all-srcs\", 1)" 88 done) 89 } 90 91 # Convert //foo/bar:stuff //this //foo/bar:stuff to //foo/bar //this 92 packages() { 93 (for i in "$@"; do 94 echo $(package-name "${i}") 95 done) | sort -u 96 } 97 98 # Convert //foo //bar to foo/BUILD bar/BUILD.bazel (whichever exist) 99 builds() { 100 for i in "${@}"; do 101 echo $(ls ${i:2}/{BUILD,BUILD.bazel} 2>/dev/null) 102 done 103 } 104 105 # Remove lines with //something:all-srcs from files 106 # Usage: 107 # remove-all-srcs <targets-to-remove> <remove-from-packages> 108 remove-all-srcs() { 109 for b in $1; do 110 $SED -i -e "\|${b}:all-srcs|d" $(builds $2) 111 done 112 } 113 114 # Global variable to track when we are finished 115 remove_unused_go_libraries_finished= 116 # Remove every go_library() target from workspace with no one depending on it. 117 remove-unused-go-libraries() { 118 local libraries deps 119 deps="$(unused-go-libraries)" 120 if [[ -z "$deps" ]]; then 121 echo "All remaining go libraries are alive" >&2 122 remove_unused_go_libraries_finished=true 123 return 0 124 fi 125 echo "Unused libraries:" >&2 126 for d in $deps; do 127 echo " DEAD: $d" >&2 128 done 129 if [[ "$1" == "--check" || "$1" != "--fix" ]]; then 130 echo "Correct with $0 --fix" >&2 131 exit 1 132 else 133 echo Cleaning up unused dependencies... >&2 134 fi 135 local unused_packs unused_files all_srcs_packs 136 unused_packs=$(packages $deps) 137 unused_files=$(sources $deps) 138 # Packages with //unused-package:all-srcs references 139 all_srcs_packs=$(all-srcs-refs $unused_packs) 140 141 pushd "$(dirname ${BASH_SOURCE})/.." 142 remove-all-srcs "$unused_packs" "$all_srcs_packs" 143 rm -f $unused_files $(builds $unused_packs) 144 popd 145 } 146 147 # Continue until we do not remove anything 148 while [[ -z $remove_unused_go_libraries_finished ]]; do 149 remove-unused-go-libraries "${1:-}" 150 done