|  | #!/bin/bash | 
|  | # Copyright 2020 The Fuchsia Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style license that can be | 
|  | # found in the LICENSE file. | 
|  |  | 
|  | #### CATEGORY=Internal API | 
|  | ### Builds and returns a list of a desired set of build artifacts | 
|  |  | 
|  | ## usage: fx list-build-artifacts [--build] [--allow-empty | --expect-one] [FILTERS...] MODE | 
|  | ## | 
|  | ## Builds and returns a list of paths to special sets of build artifacts within | 
|  | ## the GN graph relative to the build directory. | 
|  | ## | 
|  | ##  --build       build the artifacts as well as returning a list of them | 
|  | ##  --allow-empty do not fail if no such artifacts are found | 
|  | ##  --expect-one  fail if zero or more than one artifacts are found. This | 
|  | ##                option is mutually exclusive from `--allow-empty`. | 
|  | ##  --name        filter the set of artifacts to pick out the particular one of | 
|  | ##                the same name | 
|  | ##  --os          filter the set of artifacts by intended operating system: one | 
|  | ##                of `fuchsia`, `linux`, or `mac`. Defaults to $HOST_OS when | 
|  | ##                the mode is `tools.` | 
|  | ##  --cpu         filter the set of artifacts by intended architecture: one of | 
|  | ##                `x64` or `arm64`. Defaults to $HOST_CPU when the mode is | 
|  | ##                `tools`. | 
|  | ##  --type         filter the set of artifacts by type. | 
|  | ## | 
|  | ##  MODE          One of the following: | 
|  | ##                `images` -- returns the list of images | 
|  | ##                `pave`-- returns the list of images needed to pave; | 
|  | ##                `pave-zedboot`-- returns the list of images needed to pave | 
|  | ##                zedboot; | 
|  | ##                `netboot`-- returns the list of images needed to netboot | 
|  | ##                `flash`-- returns the list of images needed to flash | 
|  | ##                `tools` -- returns the list of host tools | 
|  | ##                `zbi-tests`-- returns the list of ZBI tests | 
|  | ##                `generated-sources`-- returns the list of generated sources | 
|  | ###                (e.g., FIDL and Banjo bindings). | 
|  | ## | 
|  |  | 
|  | set -o errexit | 
|  |  | 
|  | source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/vars.sh | 
|  | fx-config-read | 
|  |  | 
|  | readonly IMAGES_JSON="images.json" | 
|  | readonly TOOL_PATHS_JSON="tool_paths.json" | 
|  | readonly ZBI_TESTS_JSON="zbi_tests.json" | 
|  | readonly GENERATED_SOURCES_JSON="generated_sources.json" | 
|  |  | 
|  | build=false | 
|  | allow_empty=false | 
|  | expect_one=false | 
|  | mode="" | 
|  | name="" | 
|  | os="" | 
|  | cpu="" | 
|  | type="" | 
|  | while [[ $# -ne 0 ]]; do | 
|  | case "$1" in | 
|  | --help|-h) | 
|  | fx-command-help | 
|  | exit 0 | 
|  | ;; | 
|  | --build) | 
|  | build=true | 
|  | ;; | 
|  | --allow-empty) | 
|  | allow_empty=true | 
|  | ;; | 
|  | --expect-one) | 
|  | expect_one=true | 
|  | ;; | 
|  | --name) | 
|  | shift | 
|  | name="$1" | 
|  | ;; | 
|  | --os) | 
|  | shift | 
|  | os="$1" | 
|  | ;; | 
|  | --cpu) | 
|  | shift | 
|  | cpu="$1" | 
|  | ;; | 
|  | --type) | 
|  | shift | 
|  | type="$1" | 
|  | ;; | 
|  | -*) | 
|  | fx-error "Unknown flag: $1" | 
|  | fx-command-help | 
|  | exit 1 | 
|  | ;; | 
|  | *) | 
|  | if [[ -z "${mode}" ]]; then | 
|  | mode="$1" | 
|  | else | 
|  | fx-error "unexpected argument: '$1'" | 
|  | exit 1 | 
|  | fi | 
|  | ;; | 
|  | esac | 
|  | shift | 
|  | done | 
|  |  | 
|  | if [[ -z "${mode}" ]]; then | 
|  | fx-error "MODE must be specified" | 
|  | fx-command-help | 
|  | exit 1 | 
|  | fi | 
|  |  | 
|  | if $allow_empty && $expect_one ; then | 
|  | fx-error "cannot set both --allow-empty and --expect-one" | 
|  | fx-command-help | 
|  | exit 1 | 
|  | fi | 
|  |  | 
|  | # Some build API modules are just plain JSON lists; in that case, we should | 
|  | # not apply any filters. | 
|  | is_list_like=false | 
|  | manifest="" | 
|  | jq_filter=".[]" | 
|  | paths=() | 
|  | if [[ "${mode}" == images ]]; then | 
|  | manifest="${IMAGES_JSON}" | 
|  | elif [[ "${mode}" == pave ]]; then | 
|  | manifest="${IMAGES_JSON}" | 
|  | paths+=("pave.sh") | 
|  | jq_filter+=" | select(.bootserver_pave != null)" | 
|  | elif [[ "${mode}" == pave-zedboot ]]; then | 
|  | manifest="${IMAGES_JSON}" | 
|  | paths+=("pave-zedboot.sh") | 
|  | jq_filter+=" | select(.bootserver_pave_zedboot != null)" | 
|  | elif [[ "${mode}" == netboot ]]; then | 
|  | manifest="${IMAGES_JSON}" | 
|  | paths+=("netboot.sh") | 
|  | jq_filter+=" | select(.bootserver_netboot != null)" | 
|  | elif [[ "${mode}" == flash ]]; then | 
|  | manifest="${IMAGES_JSON}" | 
|  | paths+=("flash.sh") | 
|  | jq_filter+=" | select(.fastboot_flash != null)" | 
|  | elif [[ "${mode}" == tools ]]; then | 
|  | manifest="${TOOL_PATHS_JSON}" | 
|  | os="${os:-${HOST_OS}}" | 
|  | cpu="${cpu:-${HOST_CPU}}" | 
|  | elif [[ "${mode}" == zbi-tests ]]; then | 
|  | manifest="${ZBI_TESTS_JSON}" | 
|  | elif [[ "${mode}" == generated-sources ]]; then | 
|  | manifest="${GENERATED_SOURCES_JSON}" | 
|  | is_list_like=true | 
|  | else | 
|  | fx-error "unknown MODE: ${mode}" | 
|  | fx-command-help | 
|  | exit 1 | 
|  | fi | 
|  |  | 
|  | if [[ ! -z "${name}" ]]; then | 
|  | jq_filter+=" | select(.name == \"${name}\")" | 
|  | # Filter existing paths by the name as well. | 
|  | if [[ "${paths[@]}" =~ "${name}" ]]; then | 
|  | paths=("${name}") | 
|  | else | 
|  | paths=() | 
|  | fi | 
|  | fi | 
|  |  | 
|  | if ! $is_list_like ; then | 
|  | if [[ ! -z "${os}" ]]; then | 
|  | jq_filter+=" | select(.os == \"${os}\")" | 
|  | fi | 
|  | if [[ ! -z "${cpu}" ]]; then | 
|  | jq_filter+=" | select(.cpu == \"${cpu}\")" | 
|  | fi | 
|  | if [[ ! -z "${type}" ]]; then | 
|  | jq_filter+=" | select(.type == \"${type}\")" | 
|  | fi | 
|  | jq_filter+=" | .path" | 
|  | fi | 
|  |  | 
|  | paths+=($(fx-command-run jq --raw-output "${jq_filter}" "${FUCHSIA_BUILD_DIR}/${manifest}")) | 
|  | if $build && [[ ${#paths[@]} -ne 0 ]] ; then | 
|  | # For efficiency's sake, we avoid having to build zircon when building | 
|  | # host-side artifacts. | 
|  | if [[ ! -z "${os}" && "$os" != fuchsia ]]; then | 
|  | fx-command-run build --no-zircon "${paths[@]}" >&2 | 
|  | else | 
|  | fx-command-run build "${paths[@]}" >&2 | 
|  | fi | 
|  | fi | 
|  |  | 
|  | if [[ ${#paths[@]} -eq 0 ]] && (! $allow_empty || $expect_one) ; then | 
|  | fx-error "found no artifacts in the GN graph of type \"${mode}\" with (name, os, cpu, type) == (\"${name:-*}\", \"${os:-*}\", \"${cpu:-*}\", \"${type:-*}\")" | 
|  | exit 1 | 
|  | fi | 
|  |  | 
|  | if [[ ${#paths[@]} -gt 1 ]] && $expect_one ; then | 
|  | fx-error "expected one artifact; found multiple: ${paths[@]}" | 
|  | exit 1 | 
|  | fi | 
|  |  | 
|  | echo "${paths[@]}" |