diff options
author | Patrice Arruda <patricearruda@google.com> | 2019-03-27 10:59:54 -0700 |
---|---|---|
committer | Patrice Arruda <patricearruda@google.com> | 2019-03-29 15:57:47 -0700 |
commit | b4e93fbdc2183d8c06253e90882612ebb7f1b961 (patch) | |
tree | c92bda5485a7168b6fe155ee5df61d97a93b0b9c /scripts | |
parent | d637872f440cb3400700fffb34edcdb8ca637b91 (diff) | |
download | build_soong-b4e93fbdc2183d8c06253e90882612ebb7f1b961.tar.gz build_soong-b4e93fbdc2183d8c06253e90882612ebb7f1b961.tar.bz2 build_soong-b4e93fbdc2183d8c06253e90882612ebb7f1b961.zip |
Soong: Add unbind option to setup_go_workspace_for_soong.sh script
The setup_go_workspace_for_soong now allows the reverse operation
of unbinding the directories of the previous operation. Also,
refactored the script to easily add more directories to bind/unbind
in the future, catch failures on running in subshell commands and
a cleaner way to find the repo top directory.
Bug: b/129407866
Test: Manually tested by running the script on binding and unbinding
the directories. Tested both darwin and linux OS.
Change-Id: I7c93230aeab819ab5747e990e95aa26077071d9e
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/setup_go_workspace_for_soong.sh | 351 |
1 files changed, 308 insertions, 43 deletions
diff --git a/scripts/setup_go_workspace_for_soong.sh b/scripts/setup_go_workspace_for_soong.sh index e2fb9fa3..6374aae7 100755 --- a/scripts/setup_go_workspace_for_soong.sh +++ b/scripts/setup_go_workspace_for_soong.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -# Copyright 2017 Google Inc. All rights reserved. +# Copyright 2019 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,23 +15,174 @@ set -e # See the License for the specific language governing permissions and # limitations under the License. -#mounts the components of soong into a directory structure that Go tools and editors expect +# Mounts the components of soong into a directory structure that Go tools +# and editors expect. -#move to the script's directory -cd "$(dirname $0)" -SCRIPT_PATH="$PWD" -#find the root of the Repo checkout -cd "${SCRIPT_PATH}"/../../.. -ANDROID_PATH="${PWD}" -OUTPUT_PATH="$(echo ${GOPATH} | sed 's/\:.*//')" #if GOPATH contains multiple paths, use the first one - -if [ -z "${OUTPUT_PATH}" ]; then - echo "Error; could not determine the desired location at which to create a Go-compatible workspace. Please update GOPATH to specify the desired destination directory" +##################################################################### +# Print the message to stderr with the prefix ERROR and abort this +# script. +##################################################################### +function log_FATAL() { + echo "ERROR:" "$*" >&2 exit 1 -fi +} + +##################################################################### +# Print the message to stderr with the prefix WARN +##################################################################### +function log_WARN() { + echo "WARN:" "$*" >&2 +} + + +##################################################################### +# Print the message with the prefix INFO. +##################################################################### +function log_INFO() { + echo "INFO:" "$*" +} + + +##################################################################### +# Find the root project directory of this repo. This is done by +# finding the directory of where this script lives and then go up one +# directory to check the ".repo" directory exist. If not, keep going +# up until we find the ".repo" file or we reached to the filesystem +# root. Project root directory is printed to stdout. +##################################################################### +function root_dir() ( + local dir + if ! dir="$("${readlink}" -e $(dirname "$0"))"; then + log_FATAL "failed to read the script's current directory." + fi + + dir=${dir}/../../.. + if ! dir="$("${readlink}" -e "${dir}")"; then + log_FATAL "Cannot find the root project directory" + fi + + echo "${dir}" +) + + +##################################################################### +# executes a shell command by printing out to the screen first and +# then evaluating the command. +##################################################################### +function execute() { + echo "$@" + eval "$@" +} + + +##################################################################### +# Returns the source directory of a passed in path from BIND_PATHS +# array. +##################################################################### +function bind_path_src_dir() ( + local -r bind_path="$1" + echo "${bind_path/%|*/}" +) -function confirm() { + +##################################################################### +# Returns the destination directory of a passed in path from +# BIND_PATHS array. +##################################################################### +function bind_path_dst_dir() ( + local -r bind_path="$1" + echo "${bind_path/#*|}" +) + + +##################################################################### +# Executes the bindfs command in linux. Expects $1 to be src +# directory and $2 to be destination directory. +##################################################################### +function linux_bind_dir() ( + execute bindfs "$1" "$2" +) + +##################################################################### +# Executes the fusermount -u command in linux. Expects $1 to be the +# destination directory. +##################################################################### +function linux_unbind_dir() ( + execute fusermount -u "$1" +) + +##################################################################### +# Executes the bindfs command in darwin. Expects $1 to be src +# directory and $2 to be destination directory. +##################################################################### +function darwin_bind_dir() ( + execute bindfs -o allow_recursion -n "$1" "$2" +) + + +##################################################################### +# Execute the umount command in darwin to unbind a directory. Expects +# $1 to be the destination directory +##################################################################### +function darwin_unbind_dir() ( + execute umount -f "$1" +) + + +##################################################################### +# Bind all the paths that are specified in the BIND_PATHS array. +##################################################################### +function bind_all() ( + local src_dir + local dst_dir + + for path in ${BIND_PATHS[@]}; do + src_dir=$(bind_path_src_dir "${path}") + + dst_dir=$(bind_path_dst_dir "${path}") + mkdir -p "${dst_dir}" + + "${bind_dir}" ${src_dir} "${dst_dir}" + done + + echo + log_INFO "Created GOPATH-compatible directory structure at ${OUTPUT_PATH}." +) + + +##################################################################### +# Unbind all the paths that are specified in the BIND_PATHS array. +##################################################################### +function unbind_all() ( + local dst_dir + local exit_code=0 + + # need to go into reverse since several parent directory may have been + # first before the child one. + for (( i=${#BIND_PATHS[@]}-1; i>=0; i-- )); do + dst_dir=$(bind_path_dst_dir "${BIND_PATHS[$i]}") + + # continue to unmount even one of them fails + if ! "${unbind_dir}" "${dst_dir}"; then + log_WARN "Failed to umount ${dst_dir}." + exit_code=1 + fi + done + + if [[ ${exit_code} -ne 0 ]]; then + exit ${exit_code} + fi + + echo + log_INFO "Unmounted the GOPATH-compatible directory structure at ${OUTPUT_PATH}." +) + + +##################################################################### +# Asks the user to create the GOPATH-compatible directory structure. +##################################################################### +function confirm() ( while true; do echo "Will create GOPATH-compatible directory structure at ${OUTPUT_PATH}" echo -n "Ok [Y/n]?" @@ -42,48 +193,162 @@ function confirm() { if [ "${decision}" == "n" ]; then return 1 else - echo "Invalid choice ${decision}; choose either 'y' or 'n'" + log_WARN "Invalid choice ${decision}; choose either 'y' or 'n'" fi fi done -} +) -function bindAll() { - bindOne "${ANDROID_PATH}/build/blueprint" "${OUTPUT_PATH}/src/github.com/google/blueprint" - bindOne "${ANDROID_PATH}/build/soong" "${OUTPUT_PATH}/src/android/soong" - bindOne "${ANDROID_PATH}/art/build" "${OUTPUT_PATH}/src/android/soong/art" - bindOne "${ANDROID_PATH}/external/golang-protobuf" "${OUTPUT_PATH}/src/github.com/golang/protobuf" - bindOne "${ANDROID_PATH}/external/llvm/soong" "${OUTPUT_PATH}/src/android/soong/llvm" - bindOne "${ANDROID_PATH}/external/clang/soong" "${OUTPUT_PATH}/src/android/soong/clang" - echo - echo "Created GOPATH-compatible directory structure at ${OUTPUT_PATH}" +##################################################################### +# Help function. +##################################################################### +function help() ( + cat <<EOF +Mounts the components of soong into a directory structure that Go tools +and editors expect. + + --help + This help + + --bind + Create the directory structure that Go tools and editors expect by + binding the one to aosp build directory. + + --unbind + Reverse operation of bind. + +If no flags were specified, the --bind one is selected by default. +EOF +) + + +##################################################################### +# Parse the arguments passed in to this script. +##################################################################### +function parse_arguments() { + while [[ -n "$1" ]]; do + case "$1" in + --bind) + ACTION="bind" + shift + ;; + --unbind) + ACTION="unbind" + shift + ;; + --help ) + help + shift + exit 0 + ;; + *) + log_WARN "Unknown option: $1" + help + exit 1 + ;; + esac + done + + if [[ -z "${ACTION}" ]]; then + ACTION=bind + fi } -function bindOne() { - #causes $newPath to mirror $existingPath - existingPath="$1" - newPath="$2" - mkdir -p "$newPath" - case $(uname -s) in + +##################################################################### +# Verifies that a list of required binaries are installed in the +# host in order to run this script. +##################################################################### +function check_exec_existence() ( + function check() { + if ! hash "$1" &>/dev/null; then + log_FATAL "missing $1" + fi + } + + local bins + case "${os_type}" in Darwin) - echoAndDo bindfs -o allow_recursion -n "${existingPath}" "${newPath}" + bins=("bindfs" "greadlink") ;; Linux) - echoAndDo bindfs "${existingPath}" "${newPath}" + bins=("bindfs" "fusermount") ;; + *) + log_FATAL "${os_type} is not a recognized system." esac -} -function echoAndDo() { - echo "$@" - eval "$@" + for bin in "${bins[@]}"; do + check "${bin}" + done +) + + +function main() { + parse_arguments "$@" + + check_exec_existence + + if [[ "${ACTION}" == "bind" ]]; then + if confirm; then + echo + bind_all + else + echo "skipping due to user request" + exit 1 + fi + else + echo + unbind_all + fi } -if confirm; then - echo - bindAll -else - echo "skipping due to user request" - exit 1 +readonly os_type="$(uname -s)" +case "${os_type}" in + Darwin) + bind_dir=darwin_bind_dir + unbind_dir=darwin_unbind_dir + readlink=greadlink + ;; + Linux) + bind_dir=linux_bind_dir + unbind_dir=linux_unbind_dir + readlink=readlink + ;; + *) + log_FATAL "${os_type} is not a recognized system." +esac +readonly bind_dir +readonly unbind_dir +readonly readlink + + +if ! ANDROID_PATH="$(root_dir)"; then + log_FATAL "failed to find the root of the repo checkout" +fi +readonly ANDROID_PATH + +#if GOPATH contains multiple paths, use the first one +if ! OUTPUT_PATH="$(echo ${GOPATH} | sed 's/\:.*//')"; then + log_FATAL "failed to extract the first GOPATH environment variable" fi +readonly OUTPUT_PATH +if [ -z "${OUTPUT_PATH}" ]; then + log_FATAL "Could not determine the desired location at which to create a" \ + "Go-compatible workspace. Please update GOPATH to specify the" \ + "desired destination directory." +fi + +# Below are the paths to bind from src to dst. The paths are separated by | +# where the left side is the source and the right side is destination. +readonly BIND_PATHS=( + "${ANDROID_PATH}/build/blueprint|${OUTPUT_PATH}/src/github.com/google/blueprint" + "${ANDROID_PATH}/build/soong|${OUTPUT_PATH}/src/android/soong" + "${ANDROID_PATH}/art/build|${OUTPUT_PATH}/src/android/soong/art" + "${ANDROID_PATH}/external/golang-protobuf|${OUTPUT_PATH}/src/github.com/golang/protobuf" + "${ANDROID_PATH}/external/llvm/soong|${OUTPUT_PATH}/src/android/soong/llvm" + "${ANDROID_PATH}/external/clang/soong|${OUTPUT_PATH}/src/android/soong/clang" +) + +main "$@" |