Skip to content

Commit 95d34f3

Browse files
author
Paul Weil
committed
add basic building and testing scripts
1 parent 3f0f8dd commit 95d34f3

File tree

8 files changed

+411
-0
lines changed

8 files changed

+411
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
/_output
12
image-inspector

.travis.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
language: go
2+
3+
go:
4+
- 1.5.3
5+
- 1.6
6+
7+
script:
8+
- make verify test-unit
9+
10+
notifications:
11+
irc: "chat.freenode.net#openshift-dev"
12+
13+
sudo: false

Makefile

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Old-skool build tools.
2+
#
3+
# Targets (see each target for more information):
4+
# all: Build code.
5+
# build: Build code.
6+
# test-unit: Run unit tests.
7+
# clean: Clean up.
8+
9+
OUT_DIR = _output
10+
OUT_PKG_DIR = Godeps/_workspace/pkg
11+
12+
# Build code.
13+
#
14+
# Example:
15+
# make
16+
# make all
17+
all build:
18+
hack/build-go.sh
19+
.PHONY: all build
20+
21+
# Remove all build artifacts.
22+
#
23+
# Example:
24+
# make clean
25+
clean:
26+
rm -rf $(OUT_DIR) $(OUT_PKG_DIR)
27+
.PHONY: clean
28+
29+
# Verify code conventions are properly setup.
30+
#
31+
# Example:
32+
# make verify
33+
verify: build
34+
hack/verify-gofmt.sh
35+
.PHONY: verify
36+
37+
# Run unit tests.
38+
#
39+
# Args:
40+
# WHAT: Directory names to test. All *_test.go files under these
41+
# directories will be run. If not specified, "everything" will be tested.
42+
# TESTS: Same as WHAT.
43+
# GOFLAGS: Extra flags to pass to 'go' when building.
44+
# TESTFLAGS: Extra flags that should only be passed to hack/test-go.sh
45+
#
46+
# Example:
47+
# make test-unit
48+
# make test-unit WHAT=pkg/build GOFLAGS=-v
49+
test-unit:
50+
GOTEST_FLAGS="$(TESTFLAGS)" hack/test-go.sh $(WHAT) $(TESTS)
51+
.PHONY: test-unit

hack/build-go.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/bash
2+
3+
# This script sets up a go workspace locally and builds all go components.
4+
5+
set -o errexit
6+
set -o nounset
7+
set -o pipefail
8+
9+
STARTTIME=$(date +%s)
10+
CODE_ROOT=$(dirname "${BASH_SOURCE}")/..
11+
source "${CODE_ROOT}/hack/util.sh"
12+
source "${CODE_ROOT}/hack/common.sh"
13+
ii::log::install_errexit
14+
15+
ii::build::build_binaries "$@"
16+
17+
ret=$?; ENDTIME=$(date +%s); echo "$0 took $(($ENDTIME - $STARTTIME)) seconds"; exit "$ret"

hack/common.sh

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/bin/bash
2+
3+
# The root of the build/dist directory
4+
readonly II_ROOT=$(
5+
unset CDPATH
6+
ii_root=$(dirname "${BASH_SOURCE}")/..
7+
8+
cd "${ii_root}"
9+
ii_root=`pwd`
10+
if [ -h "${ii_root}" ]; then
11+
readlink "${ii_root}"
12+
else
13+
pwd
14+
fi
15+
)
16+
17+
readonly II_GOPATH=$(
18+
unset CDPATH
19+
cd ${II_ROOT}/../../../..
20+
pwd
21+
)
22+
23+
readonly II_GO_PACKAGE=github.com/simon3z/image-inspector
24+
readonly II_OUTPUT_SUBPATH="${II_OUTPUT_SUBPATH:-_output/local}"
25+
readonly II_OUTPUT="${II_ROOT}/${II_OUTPUT_SUBPATH}"
26+
readonly II_OUTPUT_BINPATH="${II_OUTPUT}/bin"
27+
28+
# ii::build::setup_env will check that the `go` commands is available in
29+
# ${PATH}. If not running on Travis, it will also check that the Go version is
30+
# good enough for the webdav code requirements (1.5+).
31+
#
32+
# Output Vars:
33+
# export GOPATH - A modified GOPATH to our created tree along with extra
34+
# stuff.
35+
# export GOBIN - This is actively unset if already set as we want binaries
36+
# placed in a predictable place.
37+
ii::build::setup_env() {
38+
if [[ -z "$(which go)" ]]; then
39+
cat <<EOF
40+
41+
Can't find 'go' in PATH, please fix and retry.
42+
See http://golang.org/doc/install for installation instructions.
43+
44+
EOF
45+
exit 2
46+
fi
47+
48+
# Travis continuous build uses a head go release that doesn't report
49+
# a version number, so we skip this check on Travis. It's unnecessary
50+
# there anyway.
51+
if [[ "${TRAVIS:-}" != "true" ]]; then
52+
local go_version
53+
go_version=($(go version))
54+
if [[ "${go_version[2]}" < "go1.5" ]]; then
55+
cat <<EOF
56+
57+
Detected Go version: ${go_version[*]}.
58+
image-inspector builds require Go version 1.5 or greater.
59+
60+
EOF
61+
exit 2
62+
fi
63+
fi
64+
65+
unset GOBIN
66+
67+
export GOPATH=${II_ROOT}/Godeps/_workspace:${II_GOPATH}
68+
export II_TARGET_BIN=${II_GOPATH}/bin
69+
}
70+
71+
# Build image-inspector.go binary.
72+
ii::build::build_binaries() {
73+
# Create a sub-shell so that we don't pollute the outer environment
74+
(
75+
# Check for `go` binary and set ${GOPATH}.
76+
ii::build::setup_env
77+
78+
# Making this super simple for now.
79+
local platform="local"
80+
export GOBIN="${II_OUTPUT_BINPATH}/${platform}"
81+
82+
mkdir -p "${II_OUTPUT_BINPATH}/${platform}"
83+
go install image-inspector.go
84+
)
85+
}

hack/test-go.sh

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#!/bin/bash
2+
#
3+
# This script runs Go language unit tests for the image-inspector repository. Arguments to this script
4+
# are parsed as a list of packages to test until the first argument starting with '-' or '--' is
5+
# found. That argument and all following arguments are interpreted as flags to be passed directly
6+
# to `go test`. If no arguments are given, then "all" packages are tested.
7+
#
8+
# Coverage reports and jUnit XML reports can be generated by this script as well, but both cannot
9+
# be generated at once.
10+
#
11+
# This script consumes the following parameters as environment variables:
12+
# - DRY_RUN: prints all packages that would be tested with the args that would be used and exits
13+
# - TIMEOUT: the timeout for any one unit test (default '60s')
14+
# - DETECT_RACES: toggles the 'go test' race detector (defaults '-race')
15+
# - COVERAGE_SPEC: a set of flags for 'go test' that specify the coverage behavior (default '-cover -covermode=atomic')
16+
# - GOTEST_FLAGS: any other flags to be sent to 'go test'
17+
set -o errexit
18+
set -o nounset
19+
set -o pipefail
20+
21+
function exit_trap() {
22+
local return_code=$?
23+
echo "[DEBUG] Exit trap handler got return code ${return_code}"
24+
25+
end_time=$(date +%s)
26+
27+
if [[ "${return_code}" -eq "0" ]]; then
28+
verb="succeeded"
29+
else
30+
verb="failed"
31+
fi
32+
33+
echo "$0 ${verb} after $((${end_time} - ${start_time})) seconds"
34+
exit "${return_code}"
35+
}
36+
37+
trap exit_trap EXIT
38+
39+
start_time=$(date +%s)
40+
CODE_ROOT=$(dirname "${BASH_SOURCE}")/..
41+
source "${CODE_ROOT}/hack/common.sh"
42+
source "${CODE_ROOT}/hack/util.sh"
43+
cd "${CODE_ROOT}"
44+
ii::log::install_errexit
45+
ii::build::setup_env
46+
47+
# Internalize environment variables we consume and default if they're not set
48+
dry_run="${DRY_RUN:-}"
49+
test_timeout="${TIMEOUT:-120s}"
50+
detect_races="${DETECT_RACES:-true}"
51+
coverage_spec="${COVERAGE_SPEC:--cover -covermode atomic}"
52+
gotest_flags="${GOTEST_FLAGS:-}"
53+
54+
# determine if user wanted verbosity
55+
verbose=
56+
if [[ "${gotest_flags}" =~ -v( |$) ]]; then
57+
verbose=true
58+
fi
59+
60+
# Build arguments for 'go test'
61+
if [[ -z "${verbose}" ]]; then
62+
gotest_flags+=" -v"
63+
fi
64+
65+
if [[ "${detect_races}" == "true" ]]; then
66+
gotest_flags+=" -race"
67+
fi
68+
69+
# check to see if user has not disabled coverage mode
70+
if [[ -n "${coverage_spec}" ]]; then
71+
# if we have a coverage spec set, we add it. '-race' implies '-cover -covermode atomic'
72+
# but specifying both at the same time does not lead to an error so we can add both specs
73+
gotest_flags+=" ${coverage_spec}"
74+
fi
75+
76+
# check to see if user has not disabled test timeouts
77+
if [[ -n "${test_timeout}" ]]; then
78+
gotest_flags+=" -timeout ${test_timeout}"
79+
fi
80+
81+
# list_test_packages_under lists all packages containing Golang test files that we want to run as unit tests
82+
# under the given base dir in the OpenShift Origin tree
83+
function list_test_packages_under() {
84+
local basedir=$@
85+
86+
# we do not quote ${basedir} to allow for multiple arguments to be passed in as well as to allow for
87+
# arguments that use expansion, e.g. paths containing brace expansion or wildcards
88+
find ${basedir} -not \( \
89+
\( \
90+
-path 'Godeps' \
91+
-o -path '*_output' \
92+
-o -path '*.git' \
93+
-o -path '*Godeps/*' \
94+
-o -path '*test/*' \
95+
\) -prune \
96+
\) -name '*_test.go' | xargs -n1 dirname | sort -u | xargs -n1 printf "${II_GO_PACKAGE}/%s\n"
97+
}
98+
99+
# Break up the positional arguments into packages that need to be tested and arguments that need to be passed to `go test`
100+
package_args=
101+
for arg in "$@"; do
102+
if [[ "${arg}" =~ -.* ]]; then
103+
# we found an arg that begins with a dash, so we stop interpreting arguments
104+
# henceforth as packages and instead interpret them as flags to give to `go test`
105+
break
106+
fi
107+
# an arg found before the first flag is a package
108+
package_args+=" ${arg}"
109+
shift
110+
done
111+
gotest_flags+=" $*"
112+
113+
# Determine packages to test
114+
godeps_package_prefix="Godeps/_workspace/src/"
115+
test_packages=
116+
if [[ -n "${package_args}" ]]; then
117+
for package in ${package_args}; do
118+
# If we're trying to recursively test a package under Godeps, strip the Godeps prefix so go test can find the packages correctly
119+
if [[ "${package}" == "${godeps_package_prefix}"*"/..." ]]; then
120+
test_packages="${test_packages} ${package:${#godeps_package_prefix}}"
121+
else
122+
test_packages="${test_packages} ${II_GO_PACKAGE}/${package}"
123+
fi
124+
done
125+
else
126+
# If no packages are given to test, we need to generate a list of all packages with unit tests
127+
ii_test_packages="$(list_test_packages_under '*')"
128+
test_packages="${ii_test_packages}"
129+
fi
130+
131+
go test ${gotest_flags} ${test_packages}

hack/util.sh

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/bin/bash
2+
3+
# Provides simple utility functions
4+
5+
# Handler for when we exit automatically on an error.
6+
# Borrowed from https://gist.github.com/ahendrix/7030300
7+
ii::log::errexit() {
8+
local err="${PIPESTATUS[@]}"
9+
10+
# If the shell we are in doesn't have errexit set (common in subshells) then
11+
# don't dump stacks.
12+
set +o | grep -qe "-o errexit" || return
13+
14+
set +o xtrace
15+
local code="${1:-1}"
16+
ii::log::error_exit "'${BASH_COMMAND}' exited with status $err" "${1:-1}" 1
17+
}
18+
19+
ii::log::install_errexit() {
20+
# trap ERR to provide an error handler whenever a command exits nonzero this
21+
# is a more verbose version of set -o errexit
22+
trap 'ii::log::errexit' ERR
23+
24+
# setting errtrace allows our ERR trap handler to be propagated to functions,
25+
# expansions and subshells
26+
set -o errtrace
27+
}
28+
29+
# Log an error and exit.
30+
# Args:
31+
# $1 Message to log with the error
32+
# $2 The error code to return
33+
# $3 The number of stack frames to skip when printing.
34+
ii::log::error_exit() {
35+
local message="${1:-}"
36+
local code="${2:-1}"
37+
local stack_skip="${3:-0}"
38+
stack_skip=$((stack_skip + 1))
39+
40+
local source_file=${BASH_SOURCE[$stack_skip]}
41+
local source_line=${BASH_LINENO[$((stack_skip - 1))]}
42+
echo "!!! Error in ${source_file}:${source_line}" >&2
43+
[[ -z ${1-} ]] || {
44+
echo " ${1}" >&2
45+
}
46+
47+
ii::log::stack $stack_skip
48+
49+
echo "Exiting with status ${code}" >&2
50+
exit "${code}"
51+
}
52+
53+
# Print out the stack trace
54+
#
55+
# Args:
56+
# $1 The number of stack frames to skip when printing.
57+
ii::log::stack() {
58+
local stack_skip=${1:-0}
59+
stack_skip=$((stack_skip + 1))
60+
if [[ ${#FUNCNAME[@]} -gt $stack_skip ]]; then
61+
echo "Call stack:" >&2
62+
local i
63+
for ((i=1 ; i <= ${#FUNCNAME[@]} - $stack_skip ; i++))
64+
do
65+
local frame_no=$((i - 1 + stack_skip))
66+
local source_file=${BASH_SOURCE[$frame_no]}
67+
local source_lineno=${BASH_LINENO[$((frame_no - 1))]}
68+
local funcname=${FUNCNAME[$frame_no]}
69+
echo " $i: ${source_file}:${source_lineno} ${funcname}(...)" >&2
70+
done
71+
fi
72+
}
73+
74+
find_files() {
75+
find . -not \( \
76+
\( \
77+
-wholename './_output' \
78+
-o -wholename './_tools' \
79+
-o -wholename './.*' \
80+
-o -wholename '*/Godeps/*' \
81+
\) -prune \
82+
\) -name '*.go' | sort -u
83+
}
84+

0 commit comments

Comments
 (0)