Seewai Fu | e4232e8 | 2021-05-07 17:48:44 -0700 | [diff] [blame^] | 1 | #!/bin/bash -e |
| 2 | |
| 3 | # Copyright 2021 The Chromium OS Authors. All rights reserved. |
| 4 | # Use of this source code is governed by a BSD-style license that can be |
| 5 | # found in the LICENSE file. |
| 6 | |
| 7 | # This script quickly builds the testservice executable or its unit tests within a |
| 8 | # Chrome OS chroot. |
| 9 | |
| 10 | # Personal Go workspace used to cache compiled packages. |
| 11 | readonly GOHOME="${HOME}/go" |
| 12 | |
| 13 | # Directory where compiled packages are cached. |
| 14 | readonly PKGDIR="${GOHOME}/pkg" |
| 15 | |
| 16 | # Go workspaces containing the Test Service source. |
| 17 | readonly SRCDIRS=( |
| 18 | "${HOME}/trunk/src/platform/dev/test" |
| 19 | ) |
| 20 | |
| 21 | # Package to build to produce testservice executables. |
| 22 | readonly TESTSERVICE_PKG="chromiumos/testservice/cmd/testservice" |
| 23 | |
| 24 | # Output filename for testservice executable. |
| 25 | readonly TESTSERVICE_OUT="${GOHOME}/bin/testservice" |
| 26 | |
| 27 | # Readonly Go workspaces containing source to build. Note that the packages |
| 28 | # installed to /usr/lib/gopath (dev-go/crypto, dev-go/subcommand, etc.) need to |
| 29 | # be emerged beforehand. |
| 30 | export GOPATH="$(IFS=:; echo "${SRCDIRS[*]}"):"${HOME}"/trunk/src/platform/dev/lib:/usr/lib/gopath" |
| 31 | |
| 32 | # Disable cgo and PIE on building Test Service binaries. See: |
| 33 | # https://crbug.com/976196 |
| 34 | # https://github.com/golang/go/issues/30986#issuecomment-475626018 |
| 35 | export CGO_ENABLED=0 |
| 36 | export GOPIE=0 |
| 37 | |
| 38 | readonly CMD=$(basename "${0}") |
| 39 | |
| 40 | # Prints usage information and exits. |
| 41 | usage() { |
| 42 | cat - <<EOF >&2 |
| 43 | Quickly builds the testservice executable or its unit tests. |
| 44 | |
| 45 | Usage: ${CMD} Builds testservice to ${TESTSERVICE_OUT}. |
| 46 | ${CMD} -b <pkg> -o <path> Builds <pkg> to <path>. |
| 47 | ${CMD} [-v] -T Tests all packages. |
| 48 | ${CMD} [-v] [-r <regex>] -t <pkg> Tests <pkg>. |
| 49 | ${CMD} -C Checks all code using "go vet". |
| 50 | ${CMD} -c <pkg> Checks <pkg>'s code. |
| 51 | |
| 52 | EOF |
| 53 | exit 1 |
| 54 | } |
| 55 | |
| 56 | # Prints all checkable packages. |
| 57 | get_check_pkgs() { |
| 58 | local dir |
| 59 | for dir in "${SRCDIRS[@]}"; do |
| 60 | if [[ -d "${dir}/src" ]]; then |
| 61 | (cd "${dir}/src" |
| 62 | find . -name '*.go' | xargs dirname | sort | uniq | cut -b 3-) |
| 63 | fi |
| 64 | done |
| 65 | } |
| 66 | |
| 67 | # Prints all testable packages. |
| 68 | get_test_pkgs() { |
| 69 | local dir |
| 70 | for dir in "${SRCDIRS[@]}"; do |
| 71 | if [[ -d "${dir}/src" ]]; then |
| 72 | (cd "${dir}/src" |
| 73 | find . -name '*_test.go' | xargs dirname | sort | uniq | cut -b 3-) |
| 74 | fi |
| 75 | done |
| 76 | } |
| 77 | |
| 78 | # Builds an executable package to a destination path. |
| 79 | run_build() { |
| 80 | local pkg="${1}" |
| 81 | local dest="${2}" |
| 82 | go build -i -pkgdir "${PKGDIR}" -o "${dest}" "${pkg}" |
| 83 | } |
| 84 | |
| 85 | # Checks one or more packages. |
| 86 | run_vet() { |
| 87 | go vet -unusedresult.funcs=errors.New,errors.Wrap,errors.Wrapf,fmt.Errorf,\ |
| 88 | fmt.Sprint,fmt.Sprintf,sort.Reverse \ |
| 89 | -printf.funcs=Log,Logf,Error,Errorf,Fatal,Fatalf,Wrap,Wrapf "${@}" |
| 90 | } |
| 91 | |
| 92 | # Tests one or more packages. |
| 93 | run_test() { |
| 94 | local args=("${@}" "${EXTRAARGS[@]}") |
| 95 | go test ${verbose_flag} -pkgdir "${PKGDIR}" \ |
| 96 | ${test_regex:+"-run=${test_regex}"} "${args[@]}" |
| 97 | } |
| 98 | |
| 99 | # Executable package to build. |
| 100 | build_pkg= |
| 101 | |
| 102 | # Path to which executable package should be installed. |
| 103 | build_out= |
| 104 | |
| 105 | # Package to check via "go vet". |
| 106 | check_pkg= |
| 107 | |
| 108 | # Test package to build and run. |
| 109 | test_pkg= |
| 110 | |
| 111 | # Verbose flag for testing. |
| 112 | verbose_flag= |
| 113 | |
| 114 | # Test regex list for unit testing. |
| 115 | test_regex= |
| 116 | |
| 117 | while getopts "CTb:c:ho:r:t:v-" opt; do |
| 118 | case "${opt}" in |
| 119 | C) |
| 120 | check_pkg=all |
| 121 | ;; |
| 122 | T) |
| 123 | test_pkg=all |
| 124 | ;; |
| 125 | b) |
| 126 | build_pkg="${OPTARG}" |
| 127 | ;; |
| 128 | c) |
| 129 | check_pkg="${OPTARG}" |
| 130 | ;; |
| 131 | o) |
| 132 | build_out="${OPTARG}" |
| 133 | ;; |
| 134 | r) |
| 135 | test_regex="${OPTARG}" |
| 136 | ;; |
| 137 | t) |
| 138 | test_pkg="${OPTARG}" |
| 139 | ;; |
| 140 | v) |
| 141 | verbose_flag="-v" |
| 142 | ;; |
| 143 | *) |
| 144 | usage |
| 145 | ;; |
| 146 | esac |
| 147 | done |
| 148 | |
| 149 | shift $((OPTIND-1)) |
| 150 | EXTRAARGS=( "$@" ) |
| 151 | |
| 152 | if [ -n "${build_pkg}" ]; then |
| 153 | if [ -z "${build_out}" ]; then |
| 154 | echo "Required output file missing: -o <path>" >&2 |
| 155 | exit 1 |
| 156 | fi |
| 157 | run_build "${build_pkg}" "${build_out}" |
| 158 | elif [ -n "${test_pkg}" ]; then |
| 159 | if [ "${test_pkg}" = 'all' ]; then |
| 160 | run_test "$(get_test_pkgs)" |
| 161 | else |
| 162 | run_test "${test_pkg}" |
| 163 | fi |
| 164 | elif [ -n "${check_pkg}" ]; then |
| 165 | if [ "${check_pkg}" = 'all' ]; then |
| 166 | run_vet "$(get_check_pkgs)" |
| 167 | else |
| 168 | run_vet "${check_pkg}" |
| 169 | fi |
| 170 | else |
| 171 | run_build "${TESTSERVICE_PKG}" "${TESTSERVICE_OUT}" |
| 172 | fi |