From 3acf26818f3dfab084d69e3dad045949568e9b1f Mon Sep 17 00:00:00 2001 From: Sudhanva Sreesha Date: Sat, 16 May 2026 19:14:09 -0400 Subject: [PATCH 1/2] Add `bazel-compile-commands` --- src/bazel-compile-commands/README.md | 42 ++++++++ .../devcontainer-feature.json | 21 ++++ src/bazel-compile-commands/install.sh | 52 +++++++++ src/bazel-compile-commands/library_scripts.sh | 100 ++++++++++++++++++ test/bazel-compile-commands/scenarios.json | 25 +++++ test/bazel-compile-commands/test.sh | 10 ++ test/bazel-compile-commands/test_debian.sh | 10 ++ .../test_specific_version.sh | 11 ++ 8 files changed, 271 insertions(+) create mode 100644 src/bazel-compile-commands/README.md create mode 100644 src/bazel-compile-commands/devcontainer-feature.json create mode 100755 src/bazel-compile-commands/install.sh create mode 100644 src/bazel-compile-commands/library_scripts.sh create mode 100644 test/bazel-compile-commands/scenarios.json create mode 100755 test/bazel-compile-commands/test.sh create mode 100755 test/bazel-compile-commands/test_debian.sh create mode 100644 test/bazel-compile-commands/test_specific_version.sh diff --git a/src/bazel-compile-commands/README.md b/src/bazel-compile-commands/README.md new file mode 100644 index 00000000..dcb9da00 --- /dev/null +++ b/src/bazel-compile-commands/README.md @@ -0,0 +1,42 @@ +# bazel-compile-commands (via Github Releases) (bazel-compile-commands) + +Generates `compile_commands.json` from Bazel builds, enabling accurate code intelligence (go-to-definition, cross-references, diagnostics) in editors that support the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/). + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/bazel-compile-commands:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +| ---------- | -------------------------------------------------------------------------------------------------------------------------------- | ------ | ------------- | +| version | Version to install. Accepts `latest`, a numeric version like `0.22.4`, or the full release tag `bazel-compile-commands-v0.22.4`. | string | latest | + +## Install behaviour + +The feature selects the best available package for the current environment: + +| Environment | Package used | +| -------------------- | ------------------------------- | +| Ubuntu Noble (24.04) | Native `.deb` via `apt-get` | +| Other Linux | Generic `.zip` (amd64 or arm64) | +| macOS | Universal `.zip` | + +## Pairing with Bazel + +This feature pairs naturally with [`ghcr.io/devcontainers-community/features/bazel:1`](https://github.com/devcontainers-community/features-bazel), which installs Bazelisk and Buildifier. When both are present in `devcontainer.json`, the Bazel feature is installed first. + +```json +"features": { + "ghcr.io/devcontainers-community/features/bazel:1": {}, + "ghcr.io/devcontainers-extra/features/bazel-compile-commands:1": {} +} +``` + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/bazel-compile-commands/devcontainer-feature.json b/src/bazel-compile-commands/devcontainer-feature.json new file mode 100644 index 00000000..d8149697 --- /dev/null +++ b/src/bazel-compile-commands/devcontainer-feature.json @@ -0,0 +1,21 @@ +{ + "id": "bazel-compile-commands", + "version": "1.0.0", + "name": "bazel-compile-commands (via Github Releases)", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bazel-compile-commands", + "description": "Generates compile_commands.json from Bazel builds. Installs the appropriate binary for the current platform and CPU architecture: a native .deb on Ubuntu Noble (24.04), a generic zip on other Linux distros, and the macOS universal binary on Darwin.", + "options": { + "version": { + "default": "latest", + "description": "Version to install. Accepts 'latest', a numeric version like '0.22.4', or the full release tag 'bazel-compile-commands-v0.22.4'.", + "proposals": [ + "latest", + "0.22.4" + ], + "type": "string" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers-community/features/bazel" + ] +} diff --git a/src/bazel-compile-commands/install.sh b/src/bazel-compile-commands/install.sh new file mode 100755 index 00000000..73525fe2 --- /dev/null +++ b/src/bazel-compile-commands/install.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +set -e + +source ./library_scripts.sh + +BINARY_NAME="bazel-compile-commands" +GITHUB_REPO="kiron1/bazel-compile-commands" +VERSION="${VERSION:-"latest"}" + +PLATFORM="$(detect_platform)" +ARCH="$(detect_arch)" +ensure_packages curl ca-certificates +TAG="$(resolve_tag "${VERSION}" "${GITHUB_REPO}" "${BINARY_NAME}")" + +# Extract the numeric version from the tag (e.g. "bazel-compile-commands-v0.22.4" → "0.22.4") +FILE_VERSION="${TAG#${BINARY_NAME}-v}" + +BASE_URL="https://github.com/${GITHUB_REPO}/releases/download/${TAG}" + +echo "Installing ${BINARY_NAME} ${TAG} for ${PLATFORM}/${ARCH}..." + +USE_DEB=false +ZIP_ASSET="" + +if [ "${PLATFORM}" = "linux" ]; then + # On Ubuntu Noble (24.04), prefer the native .deb package; fall back to the generic .zip. + if command -v apt-get >/dev/null 2>&1 && \ + [ -f /etc/os-release ] && \ + grep -qi "noble" /etc/os-release; then + USE_DEB=true + else + ZIP_ASSET="linux_${ARCH}" + fi +elif [ "${PLATFORM}" = "macos" ]; then + ZIP_ASSET="macos_universal" +fi + +if [ "${USE_DEB}" = true ]; then + echo "Ubuntu Noble detected – installing via .deb package..." + TMP_DEB=$(mktemp --suffix=.deb) + curl -fsSL "${BASE_URL}/${BINARY_NAME}_${FILE_VERSION}-noble_${ARCH}.deb" -o "${TMP_DEB}" + apt_get_update + apt-get install -y "${TMP_DEB}" + rm -f "${TMP_DEB}" + apt_cleanup +else + echo "Installing via .zip (${ZIP_ASSET})..." + install_via_zip "${BASE_URL}/${BINARY_NAME}_${FILE_VERSION}-${ZIP_ASSET}.zip" "${BINARY_NAME}" +fi + +echo "Done! ${BINARY_NAME} installed to /usr/local/bin/${BINARY_NAME}" diff --git a/src/bazel-compile-commands/library_scripts.sh b/src/bazel-compile-commands/library_scripts.sh new file mode 100644 index 00000000..9a09c223 --- /dev/null +++ b/src/bazel-compile-commands/library_scripts.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +# Adapted from https://github.com/devcontainers-community/features-bazel/blob/main/lib.sh +# which itself traces back to the official devcontainers/features node install script. + +# Runs apt-get update only when the apt lists cache is empty, avoiding redundant network hits. +apt_get_update() { + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi +} + +# Installs the given packages only if they are not already installed (checked via dpkg). +# Debian/Ubuntu only; calls apt_get_update lazily rather than unconditionally. +check_packages() { + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update + apt-get -y install --no-install-recommends "$@" + fi +} + +# Removes apt list files to keep the container layer small. +apt_cleanup() { + rm -rf /var/lib/apt/lists/* +} + +# Ensures the given packages are installed, using apt-get on Debian/Ubuntu or apk on Alpine. +ensure_packages() { + if command -v apt-get >/dev/null 2>&1; then + check_packages "$@" + elif command -v apk >/dev/null 2>&1; then + apk add --no-cache "$@" + else + echo "No supported package manager found to install: $*" >&2 + exit 1 + fi +} + +detect_platform() { + local os + os="$(uname -s)" + case "${os}" in + Linux) echo "linux" ;; + Darwin) echo "macos" ;; + *) echo "Unsupported platform: ${os}" >&2; exit 1 ;; + esac +} + +detect_arch() { + local arch + arch="$(uname -m)" + case "${arch}" in + x86_64) echo "amd64" ;; + aarch64 | arm64) echo "arm64" ;; + *) echo "Unsupported architecture: ${arch}" >&2; exit 1 ;; + esac +} + +# Resolves a user-provided version string to the exact GitHub release tag. +# Accepted inputs: "latest", "0.22.4", "v0.22.4", or "bazel-compile-commands-v0.22.4" +resolve_tag() { + local version="$1" + local repo="$2" + local tag_prefix="$3" # e.g. "bazel-compile-commands" + + if [ "${version}" = "latest" ]; then + curl -fsSL "https://api.github.com/repos/${repo}/releases/latest" \ + | grep '"tag_name"' | sed -E 's/.*"tag_name": "([^"]+)".*/\1/' + elif [[ "${version}" == ${tag_prefix}-* ]]; then + echo "${version}" + elif [[ "${version}" == v* ]]; then + echo "${tag_prefix}-${version}" + else + echo "${tag_prefix}-v${version}" + fi +} + +# Downloads a GitHub release zip asset, extracts a named binary, and places it in /usr/local/bin. +# +# Usage: install_via_zip +# +# zip_url - Direct URL to the .zip asset on GitHub Releases. +# binary_name - Name of the binary inside the archive (e.g. "bazel-compile-commands"). +# +# unzip is auto-installed if not already present, and the temporary download +# directory is cleaned up on exit. +install_via_zip() { + local zip_url="$1" + local binary_name="$2" + + ensure_packages unzip + + local tmp_dir + tmp_dir=$(mktemp -d) + curl -fsSL "${zip_url}" -o "${tmp_dir}/${binary_name}.zip" + unzip -j "${tmp_dir}/${binary_name}.zip" -d "${tmp_dir}" + install -m 0755 "${tmp_dir}/${binary_name}" /usr/local/bin/ + rm -rf "${tmp_dir}" +} diff --git a/test/bazel-compile-commands/scenarios.json b/test/bazel-compile-commands/scenarios.json new file mode 100644 index 00000000..a893dbd7 --- /dev/null +++ b/test/bazel-compile-commands/scenarios.json @@ -0,0 +1,25 @@ +{ + "test": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", + "features": { + "ghcr.io/devcontainers-community/features/bazel:1": {}, + "bazel-compile-commands": {} + } + }, + "test_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", + "features": { + "ghcr.io/devcontainers-community/features/bazel:1": {}, + "bazel-compile-commands": { + "version": "0.22.4" + } + } + }, + "test_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "ghcr.io/devcontainers-community/features/bazel:1": {}, + "bazel-compile-commands": {} + } + } +} diff --git a/test/bazel-compile-commands/test.sh b/test/bazel-compile-commands/test.sh new file mode 100755 index 00000000..2b2cfd07 --- /dev/null +++ b/test/bazel-compile-commands/test.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "bazel-compile-commands is installed" bazel-compile-commands --version +check "bazelisk is installed" bazelisk --version + +reportResults diff --git a/test/bazel-compile-commands/test_debian.sh b/test/bazel-compile-commands/test_debian.sh new file mode 100755 index 00000000..2b2cfd07 --- /dev/null +++ b/test/bazel-compile-commands/test_debian.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "bazel-compile-commands is installed" bazel-compile-commands --version +check "bazelisk is installed" bazelisk --version + +reportResults diff --git a/test/bazel-compile-commands/test_specific_version.sh b/test/bazel-compile-commands/test_specific_version.sh new file mode 100644 index 00000000..a42376b8 --- /dev/null +++ b/test/bazel-compile-commands/test_specific_version.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +which bazel-compile-commands +check "bazel-compile-commands version is 0.22.4" sh -c "bazel-compile-commands --version 2>&1 | grep '0.22.4'" +check "bazelisk is installed" bazelisk --version + +reportResults From d0b4881e87f98c0c84856d9f18115fcc20547d07 Mon Sep 17 00:00:00 2001 From: Sudhanva Sreesha Date: Sun, 17 May 2026 15:10:24 +0000 Subject: [PATCH 2/2] Refactor: Smplify `install.sh` to use `gh-release` pattern and standarize `library_scripts.sh`. --- .../devcontainer-feature.json | 4 +- src/bazel-compile-commands/install.sh | 70 ++--- src/bazel-compile-commands/library_scripts.sh | 239 ++++++++++++------ 3 files changed, 182 insertions(+), 131 deletions(-) diff --git a/src/bazel-compile-commands/devcontainer-feature.json b/src/bazel-compile-commands/devcontainer-feature.json index d8149697..7d196334 100644 --- a/src/bazel-compile-commands/devcontainer-feature.json +++ b/src/bazel-compile-commands/devcontainer-feature.json @@ -3,11 +3,11 @@ "version": "1.0.0", "name": "bazel-compile-commands (via Github Releases)", "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/bazel-compile-commands", - "description": "Generates compile_commands.json from Bazel builds. Installs the appropriate binary for the current platform and CPU architecture: a native .deb on Ubuntu Noble (24.04), a generic zip on other Linux distros, and the macOS universal binary on Darwin.", + "description": "Generates compile_commands.json from Bazel builds.", "options": { "version": { "default": "latest", - "description": "Version to install. Accepts 'latest', a numeric version like '0.22.4', or the full release tag 'bazel-compile-commands-v0.22.4'.", + "description": "Version to install. Accepts 'latest' or a numeric version like '0.22.4'.", "proposals": [ "latest", "0.22.4" diff --git a/src/bazel-compile-commands/install.sh b/src/bazel-compile-commands/install.sh index 73525fe2..de53af50 100755 --- a/src/bazel-compile-commands/install.sh +++ b/src/bazel-compile-commands/install.sh @@ -2,51 +2,29 @@ set -e -source ./library_scripts.sh - -BINARY_NAME="bazel-compile-commands" -GITHUB_REPO="kiron1/bazel-compile-commands" -VERSION="${VERSION:-"latest"}" - -PLATFORM="$(detect_platform)" -ARCH="$(detect_arch)" -ensure_packages curl ca-certificates -TAG="$(resolve_tag "${VERSION}" "${GITHUB_REPO}" "${BINARY_NAME}")" - -# Extract the numeric version from the tag (e.g. "bazel-compile-commands-v0.22.4" → "0.22.4") -FILE_VERSION="${TAG#${BINARY_NAME}-v}" - -BASE_URL="https://github.com/${GITHUB_REPO}/releases/download/${TAG}" - -echo "Installing ${BINARY_NAME} ${TAG} for ${PLATFORM}/${ARCH}..." - -USE_DEB=false -ZIP_ASSET="" - -if [ "${PLATFORM}" = "linux" ]; then - # On Ubuntu Noble (24.04), prefer the native .deb package; fall back to the generic .zip. - if command -v apt-get >/dev/null 2>&1 && \ - [ -f /etc/os-release ] && \ - grep -qi "noble" /etc/os-release; then - USE_DEB=true - else - ZIP_ASSET="linux_${ARCH}" - fi -elif [ "${PLATFORM}" = "macos" ]; then - ZIP_ASSET="macos_universal" -fi - -if [ "${USE_DEB}" = true ]; then - echo "Ubuntu Noble detected – installing via .deb package..." - TMP_DEB=$(mktemp --suffix=.deb) - curl -fsSL "${BASE_URL}/${BINARY_NAME}_${FILE_VERSION}-noble_${ARCH}.deb" -o "${TMP_DEB}" - apt_get_update - apt-get install -y "${TMP_DEB}" - rm -f "${TMP_DEB}" - apt_cleanup -else - echo "Installing via .zip (${ZIP_ASSET})..." - install_via_zip "${BASE_URL}/${BINARY_NAME}_${FILE_VERSION}-${ZIP_ASSET}.zip" "${BINARY_NAME}" +. ./library_scripts.sh + +# nanolayer is a cli utility which keeps container layers as small as possible +# source code: https://github.com/devcontainers-extra/nanolayer +# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, +# and if missing - will download a temporary copy that automatically get deleted at the end +# of the script +ensure_nanolayer nanolayer_location "v0.5.6" + +# Upstream tags use a non-standard "bazel-compile-commands-v" format. Normalise +# any plain version (e.g. "0.22.4" or "v0.22.4") so nanolayer can match it exactly. +if [[ "${VERSION}" != "latest" && "${VERSION}" != bazel-compile-commands-* ]]; then + VERSION="bazel-compile-commands-v${VERSION#v}" fi -echo "Done! ${BINARY_NAME} installed to /usr/local/bin/${BINARY_NAME}" +$nanolayer_location \ + install \ + devcontainer-feature \ + "ghcr.io/devcontainers-extra/features/gh-release:1" \ + --option repo='kiron1/bazel-compile-commands' \ + --option binaryNames='bazel-compile-commands' \ + --option version="$VERSION" \ + --option assetRegex='linux_' \ + --option releaseTagRegex='bazel-compile-commands-v' + +echo 'Done!' diff --git a/src/bazel-compile-commands/library_scripts.sh b/src/bazel-compile-commands/library_scripts.sh index 9a09c223..f6d0760d 100644 --- a/src/bazel-compile-commands/library_scripts.sh +++ b/src/bazel-compile-commands/library_scripts.sh @@ -1,100 +1,173 @@ #!/usr/bin/env bash -# Adapted from https://github.com/devcontainers-community/features-bazel/blob/main/lib.sh -# which itself traces back to the official devcontainers/features node install script. +clean_download() { + # The purpose of this function is to download a file with minimal impact on container layer size + # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a + # temporary manner, and making sure to + # 1. uninstall the downloader at the return of the function + # 2. revert back any changes to the package installer database/cache (for example apt-get lists) + # The above steps will minimize the leftovers being created while installing the downloader + # Supported distros: + # debian/ubuntu/alpine -# Runs apt-get update only when the apt lists cache is empty, avoiding redundant network hits. -apt_get_update() { - if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then - echo "Running apt-get update..." + url=$1 + output_location=$2 + tempdir=$(mktemp -d) + downloader_installed="" + + function _apt_get_install() { + tempdir=$1 + + # copy current state of apt list - in order to revert back later (minimize contianer layer size) + cp -p -R /var/lib/apt/lists $tempdir apt-get update -y - fi -} + apt-get -y install --no-install-recommends wget ca-certificates + } + + function _apt_get_cleanup() { + tempdir=$1 + + echo "removing wget" + apt-get -y purge wget --auto-remove + + echo "revert back apt lists" + rm -rf /var/lib/apt/lists/* + rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists + } + + function _apk_install() { + tempdir=$1 + # copy current state of apk cache - in order to revert back later (minimize contianer layer size) + cp -p -R /var/cache/apk $tempdir + + apk add --no-cache wget + } -# Installs the given packages only if they are not already installed (checked via dpkg). -# Debian/Ubuntu only; calls apt_get_update lazily rather than unconditionally. -check_packages() { - if ! dpkg -s "$@" > /dev/null 2>&1; then - apt_get_update - apt-get -y install --no-install-recommends "$@" + function _apk_cleanup() { + tempdir=$1 + + echo "removing wget" + apk del wget + } + # try to use either wget or curl if one of them already installer + if type curl >/dev/null 2>&1; then + downloader=curl + elif type wget >/dev/null 2>&1; then + downloader=wget + else + downloader="" fi -} -# Removes apt list files to keep the container layer small. -apt_cleanup() { - rm -rf /var/lib/apt/lists/* -} + # in case none of them is installed, install wget temporarly + if [ -z $downloader ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_install $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_install $tempdir + else + echo "distro not supported" + exit 1 + fi + downloader="wget" + downloader_installed="true" + fi -# Ensures the given packages are installed, using apt-get on Debian/Ubuntu or apk on Alpine. -ensure_packages() { - if command -v apt-get >/dev/null 2>&1; then - check_packages "$@" - elif command -v apk >/dev/null 2>&1; then - apk add --no-cache "$@" + if [ $downloader = "wget" ]; then + wget -q $url -O $output_location else - echo "No supported package manager found to install: $*" >&2 - exit 1 + curl -sfL $url -o $output_location fi -} -detect_platform() { - local os - os="$(uname -s)" - case "${os}" in - Linux) echo "linux" ;; - Darwin) echo "macos" ;; - *) echo "Unsupported platform: ${os}" >&2; exit 1 ;; - esac -} + # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because + # alpine lack bash, and RETURN is not a valid signal under sh shell + if ! [ -z $downloader_installed ]; then + if [ -x "/usr/bin/apt-get" ]; then + _apt_get_cleanup $tempdir + elif [ -x "/sbin/apk" ]; then + _apk_cleanup $tempdir + else + echo "distro not supported" + exit 1 + fi + fi -detect_arch() { - local arch - arch="$(uname -m)" - case "${arch}" in - x86_64) echo "amd64" ;; - aarch64 | arm64) echo "arm64" ;; - *) echo "Unsupported architecture: ${arch}" >&2; exit 1 ;; - esac } -# Resolves a user-provided version string to the exact GitHub release tag. -# Accepted inputs: "latest", "0.22.4", "v0.22.4", or "bazel-compile-commands-v0.22.4" -resolve_tag() { - local version="$1" - local repo="$2" - local tag_prefix="$3" # e.g. "bazel-compile-commands" - - if [ "${version}" = "latest" ]; then - curl -fsSL "https://api.github.com/repos/${repo}/releases/latest" \ - | grep '"tag_name"' | sed -E 's/.*"tag_name": "([^"]+)".*/\1/' - elif [[ "${version}" == ${tag_prefix}-* ]]; then - echo "${version}" - elif [[ "${version}" == v* ]]; then - echo "${tag_prefix}-${version}" - else - echo "${tag_prefix}-v${version}" +ensure_nanolayer() { + # Ensure existance of the nanolayer cli program + local variable_name=$1 + + local required_version=$2 + # normalize version + if ! [[ $required_version == v* ]]; then + required_version=v$required_version fi -} -# Downloads a GitHub release zip asset, extracts a named binary, and places it in /usr/local/bin. -# -# Usage: install_via_zip -# -# zip_url - Direct URL to the .zip asset on GitHub Releases. -# binary_name - Name of the binary inside the archive (e.g. "bazel-compile-commands"). -# -# unzip is auto-installed if not already present, and the temporary download -# directory is cleaned up on exit. -install_via_zip() { - local zip_url="$1" - local binary_name="$2" - - ensure_packages unzip - - local tmp_dir - tmp_dir=$(mktemp -d) - curl -fsSL "${zip_url}" -o "${tmp_dir}/${binary_name}.zip" - unzip -j "${tmp_dir}/${binary_name}.zip" -d "${tmp_dir}" - install -m 0755 "${tmp_dir}/${binary_name}" /usr/local/bin/ - rm -rf "${tmp_dir}" + local nanolayer_location="" + + # If possible - try to use an already installed nanolayer + if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then + if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then + if type nanolayer >/dev/null 2>&1; then + echo "Found a pre-existing nanolayer in PATH" + nanolayer_location=nanolayer + fi + elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ]; then + nanolayer_location=${NANOLAYER_CLI_LOCATION} + echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" + fi + + # make sure its of the required version + if ! [[ -z "${nanolayer_location}" ]]; then + local current_version + current_version=$($nanolayer_location --version) + if ! [[ $current_version == v* ]]; then + current_version=v$current_version + fi + + if ! [ $current_version == $required_version ]; then + echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" + nanolayer_location="" + fi + fi + + fi + + # If not previuse installation found, download it temporarly and delete at the end of the script + if [[ -z "${nanolayer_location}" ]]; then + + if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then + tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) + + clean_up() { + ARG=$? + rm -rf $tmp_dir + exit $ARG + } + trap clean_up EXIT + + if [ -x "/sbin/apk" ]; then + clib_type=musl + else + clib_type=gnu + fi + + tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz + + # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed + clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename + + tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" + chmod a+x $tmp_dir/nanolayer + nanolayer_location=$tmp_dir/nanolayer + + else + echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" + exit 1 + fi + fi + + # Expose outside the resolved location + declare -g ${variable_name}=$nanolayer_location + }