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