prelude.bash raw

   1  #!/usr/bin/env bash
   2  export LC_ALL=C
   3  set -e -o pipefail
   4  
   5  # shellcheck source=contrib/shell/realpath.bash
   6  source contrib/shell/realpath.bash
   7  
   8  # shellcheck source=contrib/shell/git-utils.bash
   9  source contrib/shell/git-utils.bash
  10  
  11  ################
  12  # Required non-builtin commands should be invocable
  13  ################
  14  
  15  check_tools() {
  16      for cmd in "$@"; do
  17          if ! command -v "$cmd" > /dev/null 2>&1; then
  18              echo "ERR: This script requires that '$cmd' is installed and available in your \$PATH"
  19              exit 1
  20          fi
  21      done
  22  }
  23  
  24  ################
  25  # SOURCE_DATE_EPOCH should not unintentionally be set
  26  ################
  27  
  28  check_source_date_epoch() {
  29      if [ -n "$SOURCE_DATE_EPOCH" ] && [ -z "$FORCE_SOURCE_DATE_EPOCH" ]; then
  30          cat << EOF
  31  ERR: Environment variable SOURCE_DATE_EPOCH is set which may break reproducibility.
  32  
  33       Aborting...
  34  
  35  Hint: You may want to:
  36        1. Unset this variable: \`unset SOURCE_DATE_EPOCH\` before rebuilding
  37        2. Set the 'FORCE_SOURCE_DATE_EPOCH' environment variable if you insist on
  38           using your own epoch
  39  EOF
  40          exit 1
  41      fi
  42  }
  43  
  44  check_tools cat env readlink dirname basename git
  45  
  46  ################
  47  # We should be at the top directory of the repository
  48  ################
  49  
  50  same_dir() {
  51      local resolved1 resolved2
  52      resolved1="$(bash_realpath "${1}")"
  53      resolved2="$(bash_realpath "${2}")"
  54      [ "$resolved1" = "$resolved2" ]
  55  }
  56  
  57  if ! same_dir "${PWD}" "$(git_root)"; then
  58  cat << EOF
  59  ERR: This script must be invoked from the top level of the git repository
  60  
  61  Hint: This may look something like:
  62      env FOO=BAR ./contrib/guix/guix-<blah>
  63  
  64  EOF
  65  exit 1
  66  fi
  67  
  68  ################
  69  # Execute "$@" in a pinned, possibly older version of Guix, for reproducibility
  70  # across time.
  71  time-machine() {
  72      # shellcheck disable=SC2086
  73      guix time-machine --url=https://codeberg.org/guix/guix.git \
  74                        --commit=53396a22afc04536ddf75d8f82ad2eafa5082725 \
  75                        --cores="$JOBS" \
  76                        --keep-failed \
  77                        --fallback \
  78                        ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} \
  79                        ${ADDITIONAL_GUIX_COMMON_FLAGS} ${ADDITIONAL_GUIX_TIMEMACHINE_FLAGS} \
  80                        -- "$@"
  81  }
  82  
  83  ################
  84  guix_prefetch_temp=
  85  trap 'test -n "$guix_prefetch_temp" && rm -rf -- "$guix_prefetch_temp"' EXIT
  86  
  87  guix-prefetch() {
  88      local hash="$1" uri="$2"
  89      test -n "$guix_prefetch_temp" || guix_prefetch_temp="$(mktemp)"
  90      cat > "$guix_prefetch_temp" << EOF
  91  (use-modules (guix packages)
  92               (guix download)
  93               (guix build-system trivial)
  94               (guix licenses))
  95  
  96  (define-public dummy
  97    (package
  98      (name "dummy")
  99      (version "0")
 100      (source (origin
 101                (method url-fetch)
 102                (uri "${uri}")
 103                (sha256 (base32 "${hash}"))))
 104      (build-system trivial-build-system)
 105      (synopsis "")
 106      (description "")
 107      (home-page "")
 108      (license gpl3+)))
 109  
 110  dummy
 111  EOF
 112      guix build -f "$guix_prefetch_temp" --source
 113  }
 114  
 115  ################
 116  # Set common variables
 117  ################
 118  
 119  VERSION="${FORCE_VERSION:-$(git_head_version)}"
 120  DISTNAME="${DISTNAME:-limenka-${VERSION}}"
 121  
 122  version_base_prefix="${PWD}/guix-build-"
 123  VERSION_BASE="${version_base_prefix}${VERSION}"  # TOP
 124  
 125  DISTSRC_BASE="${DISTSRC_BASE:-${VERSION_BASE}}"
 126  
 127  OUTDIR_BASE="${OUTDIR_BASE:-${VERSION_BASE}/output}"
 128  
 129  var_base_basename="var"
 130  VAR_BASE="${VAR_BASE:-${VERSION_BASE}/${var_base_basename}}"
 131  
 132  profiles_base_basename="profiles"
 133  PROFILES_BASE="${PROFILES_BASE:-${VAR_BASE}/${profiles_base_basename}}"
 134