1# Copyright 2019 The Hafnium Authors.
2#
3# Use of this source code is governed by a BSD-style
4# license that can be found in the LICENSE file or at
5# https://opensource.org/licenses/BSD-3-Clause.
6
7# Fail on any error.
8set -e
9# Fail on any part of a pipeline failing.
10set -o pipefail
11# Treat unset variables as an error.
12set -u
13# Display commands being run.
14set -x
15
16# Returns absolute path to a file or a directory. The path must exist.
17function abs_path() {
18	local rel_path="$1"
19	if [ -d "$rel_path" ]
20	then
21		# Parameter is a directory
22		local rel_dir="$rel_path"
23		local rel_base=""
24	elif [ -f "$rel_path" ]
25	then
26		# Parameter is a regular file
27		local rel_dir="$(dirname "$rel_path")"
28		local rel_base="/$(basename "$rel_path")"
29	else
30		# File does not exist
31		echo "File not found: $rel_path" >&2
32		exit 1
33	fi
34	echo "$(cd $rel_dir && pwd)$rel_base"
35	return 0
36}
37
38# Returns true if the environment contains Kokoro build variables.
39function is_kokoro_build() {
40	[ -v KOKORO_JOB_NAME ]
41	return $?
42}
43
44# Returns true if the environment contains Jenkins build variables.
45function is_jenkins_build() {
46	[ -v JENKINS_HOME ]
47	return $?
48}
49
50# Returns true if the `.repo_manifest` folder exists. The folder should contain
51# the manifest and be present in all Repo builds. Eventually this should be
52# obsolete as we switch exclusively to Repo.
53function is_repo_build() {
54	[ -d "${ROOT_DIR}/.repo_manifest" ]
55	return $?
56}
57
58# Returns absolute path to the source file that called this function.
59function get_script_path() {
60	abs_path "${BASH_SOURCE[1]}"
61}
62
63# Returns absolute path to the directory containing the source file that called
64# this function.
65function get_script_dir() {
66	local caller_path="${BASH_SOURCE[1]}"
67	local caller_abs_path="$(abs_path $caller_path)"
68	dirname "$caller_abs_path"
69}
70
71# Assigns value (second arg) of a variable (first arg) if it is not set already.
72function default_value {
73	local var_name=$1
74	local value=$2
75	export ${var_name}=${!var_name:-${value}}
76}
77
78# Returns true if `git status` reports uncommitted changes in the source tree.
79# Runs on all projects if Repo is detected.
80function is_repo_dirty() {
81	local cmd=(git status --porcelain=v1)
82
83	# Temporary workaround for b/152398137 (all symlinks dirty on Kokoro).
84	# All affected files are in submodules, skip them.
85	if [ "${HAFNIUM_IGNORE_SUBMODULE_STATUS:-false}" == "true" ]
86	then
87		cmd+=(--ignore-submodules)
88	fi
89
90	if is_repo_build
91	then
92		# This source tree was checked out using `repo`. Check the
93		# status of all projects.
94		cmd=(${REPO} forall -c "${cmd[@]}")
95	fi
96	! (u="$(${cmd[@]})" && test -z "$u")
97	return $?
98}
99
100# Prepares the source directory for building. This includes setting global
101# variables and workaronuds for different build environments.
102function init_build() {
103	##
104	## Find Hafnium's root directory.
105	##
106	ROOT_DIR="$(abs_path $(get_script_dir)/../..)"
107	# Temporary workaround for Repo builds. Check if there is a project
108	# folder specific to Repo builds in a parent directory. If it is, the
109	# root is further one level up.
110	if [ -d "${ROOT_DIR}/../.repo_manifest" ]
111	then
112		ROOT_DIR="$(dirname ${ROOT_DIR})"
113	fi
114
115	##
116	## Paths to tools
117	##
118
119	#TODO: CLANG definition may require update based on build host.
120	CLANG="${ROOT_DIR}/prebuilts/linux-x64/clang/bin/clang"
121	REPO="${ROOT_DIR}/prebuilts/generic/repo/repo"
122
123	##
124	## Workarounds for Kokoro+Repo builds.
125	##
126	if is_kokoro_build && is_repo_build
127	then
128		# Kokoro does not correctly initialize the `.repo` folder which
129		# causes `is_repo_dirty` checks to fail. We check out the
130		# manifest as one of the projects and use it to initialize the
131		# `.repo` folder here.
132		(cd "${ROOT_DIR}/.repo_manifest" && git branch master)
133		(cd "${ROOT_DIR}" && "${REPO}" init -u .repo_manifest)
134		# Kokoro does not support '<linkfile>' manifest tags. Parse the
135		# manifest and symlink files here.
136		"$(get_script_dir)/symlink_repo.py" "${ROOT_DIR}"
137	fi
138
139	##
140	## Temporary workaround for b/152398137 (all symlinks dirty on Kokoro).
141	## The `is_kokoro_build` check does not work inside container builds.
142	## Use an environment variable with HAFNIUM_ prefix to pass that
143	## information into the container (run_in_container.sh propagates them).
144	##
145	if is_kokoro_build
146	then
147		export HAFNIUM_IGNORE_SUBMODULE_STATUS=true
148	fi
149}
150