1#!/usr/bin/env bash
2set -o pipefail
3set -e
4
5# On CircleCI, we want to see what commands are being run, at least for now
6test -n "$CIRCLECI" && set -x
7
8REPO_PATH="github.com/sensu/sensu-go"
9DASHBOARD_PATH="dashboard"
10
11eval $(go env)
12
13cmd=${1:-"all"}
14
15RACE=""
16
17VERSION_CMD="go run ./version/cmd/version/version.go"
18
19set_race_flag() {
20    if [ "$GOARCH" == "amd64" ] && [ "$CGO_ENABLED" == "1" ]; then
21        RACE="-race"
22    fi
23}
24
25case "$GOOS" in
26    darwin)
27        set_race_flag
28        ;;
29    freebsd)
30        set_race_flag
31        ;;
32    linux)
33        set_race_flag
34        ;;
35    windows)
36        set_race_flag
37        ;;
38esac
39
40cmd_name_map() {
41    local cmd=$1
42
43    case "$cmd" in
44        backend)
45            echo "sensu-backend"
46            ;;
47        agent)
48            echo "sensu-agent"
49            ;;
50        cli)
51            echo "sensuctl"
52            ;;
53    esac
54}
55
56build_tool_binary () {
57    local goos=$1
58    local goarch=$2
59    local cmd=$3
60    local subdir=$4
61
62    local outfile="target/${goos}-${goarch}/${subdir}/${cmd}"
63
64    GOOS=$goos GOARCH=$goarch go build -o $outfile ${REPO_PATH}/${subdir}/${cmd}/...
65
66    echo $outfile
67}
68
69build_binary () {
70    # Unset GOOS and GOARCH so that the version command builds on native OS/arch
71    unset GOOS
72    unset GOARCH
73
74    local version_pkg="github.com/sensu/sensu-go/version"
75    local version=$($VERSION_CMD -v)
76    local prerelease=$($VERSION_CMD -p)
77
78    local goos=$1
79    local goarch=$2
80    local cmd=$3
81    local cmd_name=$4
82    local ext="${@:5}"
83    local date=$(date -u +%FT%T.%3NZ)
84    local outfile="target/${goos}-${goarch}/${cmd_name}"
85
86    local main_pkg="cmd/${cmd_name}"
87
88    CGO_ENABLED=0 GOOS=$goos GOARCH=$goarch go build -ldflags '-X "'$version_pkg'.Version='$version'" -X "'$version_pkg'.BuildDate='$date'" -X "'$version_pkg'.BuildSHA='$buildsha'"' $ext -o $outfile ${REPO_PATH}/${main_pkg}
89
90    echo $outfile
91}
92
93build_tool () {
94    local cmd=$1
95    local subdir=$2
96
97    if [ ! -d bin/${subdir} ]; then
98        mkdir -p bin/${subdir}
99    fi
100
101    echo "Building $subdir/$cmd for ${GOOS}-${GOARCH}"
102    out=$(build_tool_binary $GOOS $GOARCH $cmd $subdir)
103    rm -f bin/$(basename $out)
104    cp ${out} bin/${subdir}
105}
106
107build_commands () {
108    echo "Build all commands..."
109
110    build_agent $@
111    build_backend $@
112    build_cli $@
113}
114
115build_agent() {
116    build_command agent $@
117}
118
119build_backend() {
120    build_command backend $@
121}
122
123build_cli() {
124    build_command cli $@
125}
126
127build_command () {
128    local cmd=$1
129    local cmd_name=$(cmd_name_map $cmd)
130    local ext="${@:2}"
131
132    if [ ! -d bin/ ]; then
133        mkdir -p bin/
134    fi
135
136    echo "Building $cmd for ${GOOS}-${GOARCH}"
137    out=$(build_binary $GOOS $GOARCH $cmd $cmd_name $ext)
138    rm -f bin/$(basename $out)
139    cp ${out} bin
140}
141
142linter_commands () {
143    echo "Running linter..."
144
145    go get honnef.co/go/tools/cmd/megacheck
146    go get gopkg.in/alecthomas/gometalinter.v2
147    go get github.com/gordonklaus/ineffassign
148    go get github.com/jgautheron/goconst/cmd/goconst
149
150    megacheck $(go list ./... | grep -v dashboardd | grep -v agent/assetmanager | grep -v scripts)
151    if [ $? -ne 0 ]; then
152        echo "Linting failed..."
153        exit 1
154    fi
155
156    gometalinter.v2 --vendor --disable-all --enable=vet --enable=ineffassign --enable=goconst --tests ./...
157    if [ $? -ne 0 ]; then
158        echo "Linting failed..."
159        exit 1
160    fi
161
162    # Make sure every package has a LICENSE
163    go list ./... | sed -n '1!p' | sed -e 's_github.com/sensu/sensu-go/__g' | xargs -I '{}' stat '{}'/LICENSE > /dev/null
164}
165
166unit_test_commands () {
167    echo "Running unit tests..."
168
169    go test -timeout=60s $RACE $(go list ./... | egrep -v '(testing|vendor|scripts)')
170    if [ $? -ne 0 ]; then
171        echo "Unit testing failed..."
172        exit 1
173    fi
174}
175
176integration_test_commands () {
177    echo "Running integration tests..."
178
179    go test -timeout=180s -tags=integration $(go list ./... | egrep -v '(testing|vendor|scripts)')
180    if [ $? -ne 0 ]; then
181        echo "Integration testing failed..."
182        exit 1
183    fi
184}
185
186docker_commands () {
187    local cmd=$1
188
189    if [ "$cmd" == "build" ]; then
190        docker_build ${@:2}
191    else
192        docker_commands build $@
193    fi
194}
195
196docker_build() {
197    # install sensuctl to make sure it's current with the docker build
198    go install ./cmd/sensuctl
199
200    local ext=$@
201
202    for cmd in agent backend cli; do
203        echo "Building $cmd for linux-amd64"
204        local cmd_name=$(cmd_name_map $cmd)
205        build_binary linux amd64 $cmd $cmd_name $ext
206    done
207
208    # build the docker image with latest tag
209    docker build --label build.sha=${build_sha} -t sensu/sensu:latest .
210}
211
212test_dashboard() {
213    pushd "${DASHBOARD_PATH}"
214    yarn install
215    yarn test
216    popd
217}
218
219prompt_confirm() {
220    read -r -n 1 -p "${1} [y/N] " response
221    case "$response" in
222        [yY][eE][sS]|[yY])
223            true
224            ;;
225        *)
226            false
227            ;;
228    esac
229}
230
231case "$cmd" in
232    "build")
233        build_commands "${@:2}"
234        ;;
235    "build_agent")
236        build_agent "${@:2}"
237        ;;
238    "build_backend")
239        build_backend "${@:2}"
240        ;;
241    "build_cli")
242        build_cli "${@:2}"
243        ;;
244    "dashboard")
245        test_dashboard
246        ;;
247    "dashboard-ci")
248        test_dashboard
249        ;;
250    "docker")
251        docker_commands "${@:2}"
252        ;;
253    "lint")
254        linter_commands
255        ;;
256    "none")
257        echo "noop"
258        ;;
259    "quality")
260        unit_test_commands
261        ;;
262    "unit")
263        unit_test_commands
264        ;;
265    "integration")
266        integration_test_commands
267        ;;
268    *)
269        unit_test_commands
270        integration_test_commands
271        build_commands
272        ;;
273esac
274