#!/usr/bin/env bash set -euo pipefail command_name="${1:-build}" requested_arch="${2:-${ALPINE_ARCH:-x86_64}}" repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" . "${repo_root}/scripts/apk/package-lib.sh" alpine_version="${ALPINE_VERSION:-3.23}" repo_name="${ALPINE_REPO_NAME:-local}" build_platform="${ALPINE_BUILD_PLATFORM:-linux/amd64}" builder_uid="$(id -u)" builder_gid="$(id -g)" if [[ "${builder_uid}" == "0" ]]; then builder_uid=1000 fi if [[ "${builder_gid}" == "0" ]]; then builder_gid=1000 fi cache_scope_from_remote() { local remote local path local owner local repo remote="$(git -C "${repo_root}" remote get-url origin 2>/dev/null || true)" remote="${remote%.git}" case "${remote}" in ssh://*/*/*) path="${remote#ssh://*/}" ;; http://*/*/*|https://*/*/*) path="${remote#*://*/}" ;; *:*) path="${remote#*:}" ;; *) path="$(basename "${repo_root}")" ;; esac owner="$(basename "$(dirname "${path}")")" repo="$(basename "${path}")" if [[ -n "${owner}" && "${owner}" != "." && -n "${repo}" ]]; then printf '%s-%s\n' "${owner}" "${repo}" | sed 's/[^A-Za-z0-9_.-]/-/g' else printf '%s\n' "$(basename "${repo_root}")" | sed 's/[^A-Za-z0-9_.-]/-/g' fi } validate_arch() { case "$1" in x86_64|aarch64) ;; *) printf 'unsupported Alpine architecture: %s\n' "$1" >&2; return 2 ;; esac } run_for_arch() { local arch="$1" local subcommand="$2" local package_dir="$3" local image_name local container_package_dir local package_name local cache_scope local cache_prefix validate_arch "${arch}" apk_validate_package_dir "${package_dir}" package_name="$(apk_package_name "${package_dir}")" container_package_dir="$(apk_container_package_dir "${repo_root}" "${package_dir}")" image_name="${ALPINE_APK_BUILDER_IMAGE:-alpine-apk-builder:${arch}}" cache_scope="${ALPINE_APK_CACHE_SCOPE:-$(cache_scope_from_remote)}" cache_prefix="${ALPINE_APK_CACHE_PREFIX:-alpine-apk}-${cache_scope}-${package_name}-${arch}" docker build \ --platform "${build_platform}" \ --build-arg "ALPINE_VERSION=${alpine_version}" \ --build-arg "BUILDER_UID=${builder_uid}" \ --build-arg "BUILDER_GID=${builder_gid}" \ -f "${repo_root}/scripts/apk/Dockerfile" \ -t "${image_name}" \ "${repo_root}" docker_args=(--rm --platform "${build_platform}") if [[ -t 0 && -t 1 ]]; then docker_args+=(-it) fi docker run "${docker_args[@]}" \ -e "ALPINE_ARCH=${arch}" \ -e "CARCH=${arch}" \ -e "ALPINE_REPO_NAME=${repo_name}" \ -e "APKBUILD_DIR=${container_package_dir}" \ -e "CARGO_HOME=/home/builder/.cache/cargo" \ -e "CARGO_TARGET_DIR=/home/builder/.cache/cargo-target" \ -e "PACKAGER=${PACKAGER:-Joachim Schlöffel }" \ -e "RUSTUP_HOME=/home/builder/.cache/rustup" \ -v "${cache_prefix}-cargo:/home/builder/.cache/cargo" \ -v "${cache_prefix}-cargo-target:/home/builder/.cache/cargo-target" \ -v "${cache_prefix}-rustup:/home/builder/.cache/rustup" \ -v "${repo_root}:/work" \ -v "${repo_root}/.cache/abuild:/home/builder/.abuild" \ -v "${repo_root}/.cache/apk-distfiles:/var/cache/distfiles" \ -v "${repo_root}/packages:/home/builder/packages" \ "${image_name}" \ "${subcommand}" } mkdir -p \ "${repo_root}/.cache/abuild" \ "${repo_root}/.cache/apk-distfiles" \ "${repo_root}/packages" case "${command_name}" in build-all) while IFS= read -r package_dir; do for arch in ${ALPINE_ARCHES:-x86_64 aarch64}; do if ! apk_package_supports_arch "${package_dir}" "${arch}"; then printf 'Skipping %s for unsupported arch %s\n' "$(apk_package_name "${package_dir}")" "${arch}" continue fi run_for_arch "${arch}" build "${package_dir}" done done < <(apk_package_dirs "${repo_root}") ;; build|checksum|lint) while IFS= read -r package_dir; do if [[ "${command_name}" == "build" ]] && ! apk_package_supports_arch "${package_dir}" "${requested_arch}"; then printf 'Skipping %s for unsupported arch %s\n' "$(apk_package_name "${package_dir}")" "${requested_arch}" continue fi run_for_arch "${requested_arch}" "${command_name}" "${package_dir}" done < <(apk_package_dirs "${repo_root}") ;; shell) package_count=0 selected_package_dir="" while IFS= read -r package_dir; do package_count=$((package_count + 1)) selected_package_dir="${package_dir}" done < <(apk_package_dirs "${repo_root}") if [[ "${package_count}" -ne 1 ]]; then printf 'apk:shell needs exactly one package; set ALPINE_PACKAGE=\n' >&2 exit 2 fi run_for_arch "${requested_arch}" "${command_name}" "${selected_package_dir}" ;; *) printf 'unknown command: %s\n' "${command_name}" >&2 printf 'usage: %s [build|build-all|checksum|lint|shell] [x86_64|aarch64]\n' "$0" >&2 exit 2 ;; esac