1#!/usr/bin/env bash
2#
3# This script will download official GHC bindists from download.haskell.org and upload
4# them to the Github Release that Stack uses.
5#
6# Prerequisites:
7#  - Create a Github release with tag `ghc-X.Y.Z-release`
8#  - Set GITHUB_AUTH_TOKEN to a token that has permission to upload assets to a Release
9#
10# To use:
11#  - Update GHCVER at the top of the script for the version you are mirring.
12#  - Update the `mirror` commands at the bottom with any required filename adjustments
13#    and other changes.
14#  - Run the script.
15#
16# The script will output a `stack-setup.yaml` file containing info for each
17# platform that you can paste into
18# https://github.com/fpco/stackage-content/blob/master/stack/stack-setup-2.yaml.
19# Be sure to double check the SHA1 sums against those in
20# https://downloads.haskell.org/~ghc/X.Y.Z/.
21#
22
23GHCVER=9.0.1
24
25if [[ -z "$GITHUB_AUTH_TOKEN" ]]; then
26  echo "$0: GITHUB_AUTH_TOKEN environment variable is required" >&2
27  exit 1
28fi
29set -xe
30UPLOAD_URL="$(curl --fail -sSLH "Authorization: token $GITHUB_AUTH_TOKEN" https://api.github.com/repos/commercialhaskell/ghc/releases/tags/ghc-$GHCVER-release |grep upload_url |head -1 |sed 's/.*"\(https.*assets\){.*/\1/')"
31if [[ -z "$UPLOAD_URL" ]]; then
32  set +x
33  echo
34  echo "$0: Could not get upload URL from Github" >&2
35  exit 1
36fi
37echo 'ghc:' >stack-setup-$GHCVER.yaml
38
39mirror_ () {
40  base_url="$1"; shift
41  suffix="$1"; shift
42  destsuffix="$1"; shift
43  srcext="$1"; shift
44  destext="$1"; shift
45  local srcurl="$base_url/ghc-$GHCVER-${suffix}.tar.${srcext}"
46  local srcfn=ghc-$GHCVER-${suffix}${destsuffix:+_}${destsuffix}.tar.${srcext}
47  if [[ ! -s "$srcfn.downloaded" ]]; then
48    rm -f "$srcfn"
49    curl -Lo "$srcfn" --fail "$srcurl"
50    date >"$srcfn.downloaded"
51  fi
52  local destfn=ghc-$GHCVER-${suffix}${destsuffix:+_}${destsuffix}.tar.${destext}
53  if [[ ! -s "$destfn.uploaded" ]]; then
54    if [[ "${srcext}" == "xz" && "${destext}" == "bz2" ]]; then
55      xzcat "$srcfn" | bzip2 -c > "$destfn"
56    elif [[ "${srcext}" != "${destext}" ]]; then
57      set +x
58      echo
59      echo "$0: Unsupported conversion: ${srcext} to ${destext}" >&2
60      exit 1
61    fi
62    curl --fail -X POST --data-binary "@$destfn" -H "Content-type: application/octet-stream" -H "Authorization: token $GITHUB_AUTH_TOKEN" "$UPLOAD_URL?name=$destfn" |cat
63    date >"$destfn.uploaded"
64  fi
65  while [[ $# -gt 0 ]]; do
66    alias="$1"
67    echo "    $alias:" >>stack-setup-$GHCVER.yaml
68    echo "        $GHCVER:" >>stack-setup-$GHCVER.yaml
69    if [[ "$srcfn" == "$destfn" ]]; then
70      echo "            url: \"$srcurl\"" >>stack-setup-$GHCVER.yaml
71      echo "            #mirror-url: \"https://github.com/commercialhaskell/ghc/releases/download/ghc-$GHCVER-release/$destfn\"" >>stack-setup-$GHCVER.yaml
72    else
73      echo "            # Converted to $destext from $srcurl" >>stack-setup-$GHCVER.yaml
74      echo "            url: \"https://github.com/commercialhaskell/ghc/releases/download/ghc-$GHCVER-release/$destfn\"" >>stack-setup-$GHCVER.yaml
75    fi
76    echo "            content-length: $(stat --printf="%s" "$destfn" 2>/dev/null || stat -f%z "$destfn")" >>stack-setup-$GHCVER.yaml
77    echo "            sha1: $(shasum -a 1 $destfn |cut -d' ' -f1)" >>stack-setup-$GHCVER.yaml
78    echo "            sha256: $(shasum -a 256 $destfn |cut -d' ' -f1)" >>stack-setup-$GHCVER.yaml
79    echo "" >>stack-setup-$GHCVER.yaml
80    shift
81  done
82}
83
84mirror () {
85  mirror_ http://downloads.haskell.org/~ghc/$GHCVER "$@"
86}
87
88# NOTE: keep the 'mirror' commands in the same order as entries in
89# https://github.com/fpco/stackage-content/blob/master/stack/stack-setup-2.yaml
90
91mirror i386-deb9-linux "" xz xz linux32
92mirror x86_64-deb9-linux "" xz xz linux64
93#mirror x86_64-centos67-linux "" xz xz linux64-gmp4
94mirror x86_64-fedora27-linux "" xz xz linux64-tinfo6
95mirror x86_64-apple-darwin "" bz2 bz2 macosx
96#mirror i386-unknown-mingw32 "" xz xz windows32
97mirror x86_64-unknown-mingw32 "" xz xz windows64
98mirror armv7-deb9-linux "" xz xz linux-armv7
99mirror aarch64-deb9-linux "" xz xz linux-aarch64
100
101mirror_ https://github.com/redneb/ghc-alt-libc/releases/download/ghc-$GHCVER-musl i386-unknown-linux-musl "" xz xz linux32-musl
102mirror_ https://github.com/redneb/ghc-alt-libc/releases/download/ghc-$GHCVER-musl x86_64-unknown-linux-musl "" xz xz linux64-musl
103
104mirror_ http://distcache.FreeBSD.org/local-distfiles/arrowd/stack-bindists/11 i386-portbld-freebsd "" xz xz freebsd32
105mirror_ http://distcache.FreeBSD.org/local-distfiles/arrowd/stack-bindists i386-portbld-freebsd "ino64" xz xz freebsd32-ino64
106mirror_ http://distcache.FreeBSD.org/local-distfiles/arrowd/stack-bindists/11 x86_64-portbld-freebsd "" xz xz freebsd64
107mirror_ http://distcache.FreeBSD.org/local-distfiles/arrowd/stack-bindists x86_64-portbld-freebsd "ino64" xz xz freebsd64-ino64
108
109set +x
110echo
111echo "DONE!  See 'stack-setup-$GHCVER.yaml' for 'stack setup' to add to"
112echo "  https://github.com/fpco/stackage-content/blob/master/stack/stack-setup-2.yaml"
113