1#!/usr/bin/env bash
2set -o errexit -o pipefail
3DIR=$(dirname "${0}")
4MAIN_DIR=$(readlink -f "${DIR}/..")
5if [ -L "${MAIN_DIR}/.git/config" ]; then
6    # Support git-new-workdir
7    GIT_DIR="$(dirname "$(realpath "${MAIN_DIR}/.git/config")")"
8else
9    # Support git-worktree
10    GIT_DIR="$(cd "${MAIN_DIR}" && git rev-parse --no-flags --git-common-dir)"
11fi
12if test -z "${IMAGE}" ; then
13    # shellcheck disable=SC2016
14    IMAGE=$(grep ^image: "${MAIN_DIR}/.gitlab-ci.yml" | \
15            sed -e 's,^image: ,,g' | sed -e 's,\$CI_REGISTRY,registry.gitlab.com,g')
16fi
17
18declare -a docker_opts=(
19    -i
20    --rm
21    --user "$(id -u):$(id -g)"
22    --workdir "$(pwd)"
23    --security-opt label=disable
24    --network host
25)
26
27declare -a mountpoints=(
28    "${MAIN_DIR}"
29    "$(pwd)"
30)
31
32# curl lists (and recognises and uses) other types of *_proxy variables,
33# but only those make sense for Buildroot:
34for env in all_proxy http_proxy https_proxy ftp_proxy no_proxy; do
35    if [ "${!env}" ]; then
36        docker_opts+=( --env "${env}" )
37        # The lower-case variant takes precedence on the upper-case one
38        # (dixit curl)
39        continue
40    fi
41    # http_proxy is only lower-case (dixit curl)
42    if [ "${env}" = http_proxy ]; then
43        continue
44    fi
45    # All the others also exist in the upper-case variant
46    env="${env^^}"
47    if [ "${!env}" ]; then
48        docker_opts+=( --env "${env}" )
49    fi
50done
51
52# Empty GIT_DIR means that we are not in a workdir, *and* git is too old
53# to know about worktrees, so we're not in a worktree either. So it means
54# we're in the main git working copy, and thus we don't need to mount the
55# .git directory.
56if [ "${GIT_DIR}" ]; then
57    # GIT_DIR in the main working copy (when git supports worktrees) will
58    # be just '.git', but 'docker run' needs an absolute path. If it is
59    # not absolute, GIT_DIR is relative to MAIN_DIR. If it's an absolute
60    # path already (in a wordir), then that's a noop.
61    GIT_DIR="$(cd "${MAIN_DIR}"; readlink -e "${GIT_DIR}")"
62    mountpoints+=( "${GIT_DIR}" )
63
64    # 'repo' stores .git/objects separately.
65    if [ -L "${GIT_DIR}/objects" ]; then
66        # GITDIR is already an absolute path, but for symetry
67        # with the above, keep the same cd+readlink construct.
68        OBJECTS_DIR="$(cd "${MAIN_DIR}"; readlink -e "${GIT_DIR}/objects")"
69        mountpoints+=( "${OBJECTS_DIR}" )
70    fi
71fi
72
73if [ "${BR2_DL_DIR}" ]; then
74    mountpoints+=( "${BR2_DL_DIR}" )
75    docker_opts+=( --env BR2_DL_DIR )
76fi
77
78# shellcheck disable=SC2013 # can't use while-read because of the assignment
79for dir in $(printf '%s\n' "${mountpoints[@]}" |LC_ALL=C sort -u); do
80    docker_opts+=( --mount "type=bind,src=${dir},dst=${dir}" )
81done
82
83if tty -s; then
84    docker_opts+=( -t )
85fi
86
87exec docker run "${docker_opts[@]}" "${IMAGE}" "${@}"
88