1#!/usr/bin/env nix-shell
2#!nix-shell -p coreutils curl.out nix jq gnused -i bash
3
4# Usage:
5# ./update.sh [PRODUCT]
6#
7# Examples:
8# $ ./update.sh graalvm-ce # will generate ./graalvm-ce/hashes.nix
9# $ ./update.sh # same as above
10# $ ./update.sh graalpy # will generate ./graalpy/hashes.nix
11#
12# Environment variables:
13# FORCE=1 to force the update of a product (e.g.: skip up-to-date checks)
14# VERSION=xx.xx will assume that xx.xx is the new version
15
16set -eou pipefail
17
18cd "$(dirname "${BASH_SOURCE[0]}")"
19tmpfile="$(mktemp --suffix=.nix)"
20readonly tmpfile
21
22trap 'rm -rf "$tmpfile"' EXIT
23
24info() { echo "[INFO] $*"; }
25
26echo_file() { echo "$@" >> "$tmpfile"; }
27
28verlte() {
29 [ "$1" = "$(echo -e "$1\n$2" | sort -V | head -n1)" ]
30}
31
32readonly product="${1:-graalvm-ce}"
33readonly hashes_nix="$product/hashes.nix"
34readonly nixpkgs=../../../../..
35
36mkdir -p "$product"
37
38declare -r -A update_urls=(
39 [graalvm-ce]="https://api.github.com/repos/graalvm/graalvm-ce-builds/releases/latest"
40 [graaljs]="https://api.github.com/repos/oracle/graaljs/releases/latest"
41 [graalnodejs]="https://api.github.com/repos/oracle/graaljs/releases/latest"
42 [graalpy]="https://api.github.com/repos/oracle/graalpython/releases/latest"
43 [truffleruby]="https://api.github.com/repos/oracle/truffleruby/releases/latest"
44)
45
46current_version="$(nix-instantiate "$nixpkgs" --eval --strict -A "graalvmCEPackages.${product}.version" --json | jq -r)"
47readonly current_version
48
49if [[ -z "${VERSION:-}" ]]; then
50 gh_version="$(curl \
51 ${GITHUB_TOKEN:+"-u \":$GITHUB_TOKEN\""} \
52 -s "${update_urls[$product]}" | \
53 jq --raw-output .tag_name)"
54 new_version="${gh_version//jdk-/}"
55 new_version="${new_version//graal-/}"
56else
57 new_version="$VERSION"
58fi
59readonly new_version
60
61info "Current version: $current_version"
62info "New version: $new_version"
63if verlte "$new_version" "$current_version"; then
64 info "$product $current_version is up-to-date."
65 [[ -z "${FORCE:-}" ]] && exit 0
66else
67 info "$product $current_version is out-of-date. Updating..."
68fi
69
70# Make sure to get the `-community` versions!
71declare -r -A products_urls=(
72 [graalvm-ce]="https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-${new_version}/graalvm-community-jdk-${new_version}_@platform@_bin.tar.gz"
73 [graaljs]="https://github.com/oracle/graaljs/releases/download/graal-${new_version}/graaljs-community-${new_version}-@platform@.tar.gz"
74 [graalnodejs]="https://github.com/oracle/graaljs/releases/download/graal-${new_version}/graalnodejs-community-${new_version}-@platform@.tar.gz"
75 [graalpy]="https://github.com/oracle/graalpython/releases/download/graal-${new_version}/graalpy-community-${new_version}-@platform@.tar.gz"
76 [truffleruby]="https://github.com/oracle/truffleruby/releases/download/graal-${new_version}/truffleruby-community-${new_version}-@platform@.tar.gz"
77)
78
79# Argh, this is really inconsistent...
80if [[ "$product" == "graalvm-ce" ]]; then
81 declare -r -A platforms=(
82 [aarch64-linux]="linux-aarch64"
83 [x86_64-linux]="linux-x64"
84 [aarch64-darwin]="macos-aarch64"
85 [x86_64-darwin]="macos-x64"
86 )
87else
88 declare -r -A platforms=(
89 [aarch64-linux]="linux-aarch64"
90 [x86_64-linux]="linux-amd64"
91 [aarch64-darwin]="macos-aarch64"
92 [x86_64-darwin]="macos-amd64"
93 )
94fi
95
96info "Generating '$hashes_nix' file for '$product' $new_version. This will take a while..."
97
98# Indentation of `echo_file` function is on purpose to make it easier to visualize the output
99echo_file "# Generated by $(basename $0) script"
100echo_file "{"
101echo_file " \"version\" = \"$new_version\";"
102url="${products_urls["${product}"]}"
103echo_file " \"hashes\" = {"
104for nix_platform in "${!platforms[@]}"; do
105 product_platform="${platforms[$nix_platform]}"
106 args=("${url//@platform@/$product_platform}")
107 # Get current hashes to skip derivations already in /nix/store to reuse cache when the version is the same
108 # e.g.: when adding a new product and running this script with FORCE=1
109 if [[ "$current_version" == "$new_version" ]] && \
110 previous_hash="$(nix-instantiate --eval "$hashes_nix" -A "hashes.$nix_platform.sha256" --json | jq -r)"; then
111 args+=("$previous_hash" "--type" "sha256")
112 else
113 info "Hash in '$product' for '$nix_platform' not found. Re-downloading it..."
114 fi
115 if hash="$(nix-prefetch-url "${args[@]}")"; then
116echo_file " \"$nix_platform\" = {"
117echo_file " sha256 = \"$hash\";"
118echo_file " url = \"${url//@platform@/${product_platform}}\";"
119echo_file " };"
120 else
121 info "Error while downloading '$product' for '$nix_platform'. Skipping it..."
122 fi
123done
124echo_file " };"
125echo_file "}"
126
127info "Moving the temporary file to '$hashes_nix'"
128mv "$tmpfile" "$hashes_nix"
129
130info "Done!"