|
13 | 13 | # SPDX-License-Identifier: Apache-2.0 |
14 | 14 | # ******************************************************************************* |
15 | 15 |
|
16 | | -# Unified entry point for running a CLI tool by name. |
17 | | -# Inside a container the tool is expected on PATH; outside, it is resolved via Bazel. |
18 | | -# See https://github.com/eclipse-score/devcontainer/tree/main/tools for further information. |
19 | | -# |
20 | | -# Do not modify this file. Its source of truth is managed by the |
21 | | -# SCORE devcontainer standardization policy. |
| 16 | +# This copy is managed by repo_policy_sync in eclipse-score/tools. |
| 17 | +# Please do not edit this copy; update the score-devcontainer-run-tool policy asset. |
| 18 | +# Consumer repositories install this runner as .devcontainer/run-tool. |
| 19 | +# It runs a pinned CLI tool from PATH in a container, from local PATH on the host |
| 20 | +# when available, or through Bazel otherwise. |
| 21 | +# Use --strict to bypass local tools on the host and force execution through Bazel. |
| 22 | +# See https://github.com/eclipse-score/devcontainer/tree/main/tools. |
22 | 23 |
|
23 | 24 | set -euo pipefail |
24 | 25 |
|
| 26 | +strict=0 |
| 27 | +if [[ "${1:-}" == "--strict" ]]; then |
| 28 | + strict=1 |
| 29 | + shift |
| 30 | +fi |
| 31 | + |
25 | 32 | if [[ "$#" -lt 1 ]]; then |
26 | | - echo "Usage: $0 <tool> [args...]" >&2 |
| 33 | + echo "Usage: $0 [--strict] <tool> [args...]" >&2 |
27 | 34 | exit 2 |
28 | 35 | fi |
29 | 36 |
|
30 | 37 | tool_name="$1" |
31 | 38 | shift |
32 | 39 |
|
33 | | -if { [[ -f /.dockerenv ]] || [[ -f /run/.containerenv ]] || [[ -d /devcontainer ]]; } && |
34 | | - command -v "${tool_name}" >/dev/null 2>&1; then |
35 | | - exec "${tool_name}" "$@" |
| 40 | +# Tests can force either side of the container boundary without changing the |
| 41 | +# automatic detection behavior. Reject invalid overrides instead of silently |
| 42 | +# treating them as a host environment. |
| 43 | +container_mode="${RUN_TOOL_CONTAINER_MODE:-auto}" |
| 44 | +case "${container_mode}" in |
| 45 | + host) is_container=0 ;; |
| 46 | + container) is_container=1 ;; |
| 47 | + auto) |
| 48 | + if [[ -f /.dockerenv ]] || [[ -f /run/.containerenv ]] || [[ -d /devcontainer ]]; then |
| 49 | + is_container=1 |
| 50 | + else |
| 51 | + is_container=0 |
| 52 | + fi |
| 53 | + ;; |
| 54 | + *) |
| 55 | + echo "Invalid RUN_TOOL_CONTAINER_MODE: ${container_mode}" >&2 |
| 56 | + exit 2 |
| 57 | + ;; |
| 58 | +esac |
| 59 | + |
| 60 | +# A container built from this catalog only ever has the pinned version on |
| 61 | +# PATH, so container execution is direct and untouched. |
| 62 | +if [[ "${is_container}" -eq 1 ]] && command -v "${tool_name}" >/dev/null 2>&1; then |
| 63 | + exec "${tool_name}" "$@" |
| 64 | +# On the host, prefer the local tool on PATH for faster execution unless --strict |
| 65 | +# is set. If local execution fails, suggest --strict to run the pinned Bazel target. |
| 66 | +elif [[ "${strict}" -eq 0 ]] && command -v "${tool_name}" >/dev/null 2>&1; then |
| 67 | + if "${tool_name}" "$@"; then |
| 68 | + exit 0 |
| 69 | + else |
| 70 | + exit_code=$? |
| 71 | + echo "Execution of local '${tool_name}' failed with exit code ${exit_code}." >&2 |
| 72 | + echo "Use '--strict' to bypass the local tool and run the pinned version via Bazel." >&2 |
| 73 | + exit "${exit_code}" |
| 74 | + fi |
36 | 75 | elif command -v bazel >/dev/null 2>&1; then |
37 | | - exec bazel run "@score_devcontainer//tools:${tool_name}" -- "$@" |
| 76 | + # Consumer repositories expose this module as @score_devcontainer; `--` |
| 77 | + # prevents tool flags from being interpreted as Bazel flags. |
| 78 | + exec bazel run "@score_devcontainer//tools:${tool_name}" -- "$@" |
38 | 79 | else |
39 | | - echo "Could not run '${tool_name}': not available on PATH in a container, and bazel was not found." >&2 |
40 | | - exit 127 |
| 80 | + echo "Could not run '${tool_name}': no container command or Bazel executable is available." >&2 |
| 81 | + exit 127 |
41 | 82 | fi |
0 commit comments