1#! /usr/bin/env nix-shell
2#! nix-shell -i bash -p curl jq git gnused gnugrep -I nixpkgs=.
3# shellcheck shell=bash
4#
5# SYNOPSIS
6#
7# Update version constraints in hackage2nix config file from Stackage.
8#
9# DESCRIPTION
10#
11# Fetches the latest snapshot of the configured Stackage solver which is
12# configured via the SOLVER (either LTS or Nightly) and VERSION variables in
13# the script.
14#
15# VERSION is only applicable if SOLVER is LTS. SOLVER=LTS and VERSION=22
16# will cause update-stackage.sh to fetch the latest LTS-22.XX version.
17# If empty, the latest version of the solver is used.
18#
19# If the configuration file has been updated, update-stackage.sh prints a
20# version difference to stdout, e.g. 23.11 -> 23.13. Otherwise, stdout remains
21# empty.
22#
23# EXIT STATUS
24#
25# Always exit with zero (even if nothing changed) unless there was an error.
26
27set -eu -o pipefail
28
29if [[ "${1:-}" == "--do-commit" ]]; then
30 echo "$0: --do-commit is no longer supported. Use update-package-set.sh instead."
31 exit 100
32fi
33
34# Stackage solver to use, LTS or Nightly
35# (should be capitalized like the display name)
36SOLVER=LTS
37# Stackage solver verson, if any. Use latest if empty
38VERSION=
39TMP_TEMPLATE=update-stackage.XXXXXXX
40readonly SOLVER
41readonly VERSION
42readonly TMP_TEMPLATE
43
44toLower() {
45 printf "%s" "$1" | tr '[:upper:]' '[:lower:]'
46}
47
48tmpfile=$(mktemp "$TMP_TEMPLATE")
49tmpfile_new=$(mktemp "$TMP_TEMPLATE")
50
51stackage_config="pkgs/development/haskell-modules/configuration-hackage2nix/stackage.yaml"
52
53trap 'rm "${tmpfile}" "${tmpfile_new}"' 0
54touch "$tmpfile" "$tmpfile_new" # Creating files here so that trap creates no errors.
55
56curl -L -s "https://stackage.org/$(toLower "$SOLVER")${VERSION:+-$VERSION}/cabal.config" >"$tmpfile"
57old_version=$(grep '^# Stackage' $stackage_config | sed -e 's/.\+ \([A-Za-z]\+ [0-9.-]\+\)$/\1/g')
58version="$SOLVER $(sed -rn "s/^--.*http:..(www.)?stackage.org.snapshot.$(toLower "$SOLVER")-//p" "$tmpfile")"
59
60if [[ "$old_version" == "$version" ]]; then
61 echo "No new stackage version" >&2
62 exit 0 # Nothing to do
63fi
64
65echo "Updating Stackage from $old_version to $version." >&2
66
67# Create a simple yaml version of the file.
68sed -r \
69 -e '/^--/d' \
70 -e 's|^constraints:||' \
71 -e 's|^ +| - |' \
72 -e 's|,$||' \
73 -e '/^with-compiler:/d' \
74 -e '/installed$/d' \
75 -e '/^$/d' \
76 < "${tmpfile}" | LC_ALL=C.UTF-8 sort --ignore-case >"${tmpfile_new}"
77
78cat > $stackage_config << EOF
79# Stackage $version
80# This file is auto-generated by
81# maintainers/scripts/haskell/update-stackage.sh
82default-package-overrides:
83EOF
84
85# Drop restrictions on some tools where we always want the latest version.
86sed -r \
87 -e '/ cabal2nix /d' \
88 -e '/ distribution-nixpkgs /d' \
89 -e '/ jailbreak-cabal /d' \
90 -e '/ language-nix /d' \
91 -e '/ hackage-db /d' \
92 -e '/ cabal-install /d' \
93 -e '/ cabal-install-solver /d' \
94 -e '/ lsp /d' \
95 -e '/ lsp-types /d' \
96 -e '/ lsp-test /d' \
97 -e '/ hie-bios /d' \
98 -e '/ ShellCheck /d' \
99 -e '/ Agda /d' \
100 -e '/ stack /d' \
101 < "${tmpfile_new}" >> $stackage_config
102# Explanations:
103# cabal2nix, distribution-nixpkgs, jailbreak-cabal, language-nix: These are our packages and we know what we are doing.
104# lsp, lsp-types, lsp-test, hie-bios: These are tightly coupled to hls which is not in stackage. They have no rdeps in stackage.
105# ShellCheck: latest version of command-line dev tool.
106# Agda: The Agda community is fast-moving; we strive to always include the newest versions of Agda and the Agda packages in nixpkgs.
107
108echo "$old_version -> $version"