1#!/usr/bin/env bash
2
3# Copyright 2018 The Fuchsia Authors
4#
5# Use of this source code is governed by a MIT-style
6# license that can be found in the LICENSE file or at
7# https://opensource.org/licenses/MIT
8
9readonly SCRIPT_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
10readonly ZIRCON_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
11readonly PREBUILTS_DIR="$(cd "${ZIRCON_ROOT}/prebuilt" && pwd)"
12readonly ENSURE_FILE="${PREBUILTS_DIR}/zircon.ensure"
13readonly VERSIONS_FILE="${PREBUILTS_DIR}/zircon.versions"
14readonly GSUTIL="gsutil"
15readonly GS_URL_PREFIX="gs://fuchsia"
16
17case "$#:$1" in
180:|1:--update)
19  mode=update
20  ;;
211:--verify)
22  mode=verify
23  ;;
241:--upload)
25  mode=upload
26  ;;
27*)
28  echo >&2 "Usage: $0 [--update | --upload | --verify]"
29  exit 1
30  ;;
31esac
32
33
34find_cipd() {
35  # If the Zircon checkout is part of a jiri checkout that includes
36  # //buildtools, then find cipd there.  Otherwise, if cipd is in
37  # the PATH, take it from there.
38  type -p "${ZIRCON_ROOT}/../buildtools/cipd" || type -p cipd
39}
40
41readonly CIPD="$(find_cipd)" || {
42  echo >&2 "$0: Need cipd in the PATH"
43}
44
45resolve_one_package() {
46  local -r package="$1" version="$2"
47  local result
48  result="$($CIPD resolve "fuchsia/$package" -version "$version")" || {
49    local rc=$?
50    echo >&2 "$0: cipd cannot resolve fuchsia/$package -version $version"
51    return $rc
52  }
53  echo "${package} ${result##*:}"
54}
55
56# TODO(crbug.com/827637): Use `cipd ensure-file-verify -resolve` when that
57# gets implemented.
58resolve_ensure_file() {
59  echo "\
60# This file is generated by scripts/update-prebuilt-versions.  DO NOT EDIT!
61# Instead, edit zircon.ensure and run the script.
62"
63
64  local -a platforms matched_platforms
65  local lhs rhs package platform
66  while read lhs rhs; do
67    case "$lhs" in
68    '$VerifiedPlatform')
69      platforms+=("$rhs")
70      ;;
71    '#MatchedPlatform')
72      matched_platforms+=("$rhs")
73      ;;
74    fuchsia/*/\${platform})
75      lhs="${lhs#fuchsia/}"
76      package="${lhs%/*}"
77      for platform in "${platforms[@]}"; do
78        resolve_one_package "${package}/${platform}" "$rhs" || return
79      done
80      ;;
81    fuchsia/*/\${os=*)
82      lhs="${lhs#fuchsia/}"
83      package="${lhs%/*}"
84      lhs="${lhs#*=}"
85      lhs="${lhs%%\}*}"
86      for platform in "${platforms[@]}" "${matched_platforms[@]}"; do
87        if [[ "$platform" == $lhs-* ]]; then
88          resolve_one_package "${package}/${platform}" "$rhs" || return
89        fi
90      done
91      ;;
92    fuchsia/*)
93      package="${lhs#fuchsia/}"
94      resolve_one_package "$package" "$rhs" || return
95      ;;
96    esac
97  done
98}
99
100do_staged_uploads() {
101  local -r zipfile="$1"
102  while read package instance; do
103    if [[ -z "$package" || "$package" == \#* ]]; then
104      continue
105    fi
106    rm -f "$zipfile"
107    "$CIPD" pkg-fetch "fuchsia/$package" -version "$instance" -out "$zipfile"
108    "$GSUTIL" cp -n "$zipfile" "${GS_URL_PREFIX}/${package}/${instance}"
109  done
110}
111
112NEW_VERSIONS_FILE="$(mktemp "${PREBUILTS_DIR}/tmp.versions.XXXXXX")" || exit
113trap 'rm -f "$NEW_VERSIONS_FILE"' EXIT ERR HUP INT TERM
114
115set -e -o pipefail
116
117resolve_ensure_file < "$ENSURE_FILE" > "$NEW_VERSIONS_FILE"
118
119if [[ "$mode" = upload ]]; then
120  cmp -s "$VERSIONS_FILE" "$NEW_VERSIONS_FILE" || {
121    echo >&2 "Run $0 --update first."
122    exit 1
123  }
124  rm -f "$NEW_VERSIONS_FILE"
125  STAGING_ZIP="$(mktemp "${PREBUILTS_DIR}/tmp.zip.XXXXXX")"
126  trap 'rm -f "$STAGING_ZIP"' EXIT ERR HUP INT TERM
127  do_staged_uploads "$STAGING_ZIP" < "$VERSIONS_FILE"
128  exit
129fi
130
131diff -u "$VERSIONS_FILE" "$NEW_VERSIONS_FILE" && exit 0
132status=$?
133
134if [[ "$mode" = update ]]; then
135  mv -f "$NEW_VERSIONS_FILE" "$VERSIONS_FILE"
136  exit 0
137fi
138
139exit $status
140