| #!/bin/bash |
| # Copyright 2018 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=Build |
| ### re-use a previous build directory set up by `fx set` |
| |
| ## usage: fx use DIR |
| ## or: fx --dir DIR use |
| ## or: fx use |
| ## |
| ## Switches further `fx` commands to using a different build directory. |
| ## This only works if `fx --dir DIR set ...` succeeded previously |
| ## (and DIR has not been removed since). The next `fx build` or other |
| ## such command will now refer to DIR. The previous build directory is |
| ## left in place, so you can switch back again with `fx use` later. |
| ## |
| ## fx use without arguments will list the available build directories, naming |
| ## the current active build directory (if any). |
| ## |
| ## fx use with `ffx.ui.mode = tui` set will prompt you to choose a build director. |
| ## ffx.ui.mode can be set using `ffx config set ffx.ui.mode tui` |
| ## The UI mode for just fx use can be set with e.g. |
| ## `ffx config set ffx.ui.overrides.fx-use text` |
| |
| source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/vars.sh || exit $? |
| |
| function main { |
| local build_dir="$1" |
| |
| case "${build_dir}" in |
| -h | --help) |
| fx-command-help |
| return 0 |
| ;; |
| esac |
| |
| if [[ -z "${build_dir}" ]]; then |
| build_dir="${_FX_BUILD_DIR}" |
| fi |
| |
| if [[ -z "${build_dir}" ]]; then |
| |
| fx-build-dir-if-present |
| local possible_build_dirs=() |
| local current="${FUCHSIA_BUILD_DIR##"${FUCHSIA_DIR}"/}" |
| if [[ -n "${current}" ]]; then |
| possible_build_dirs+=("${current} (current)") |
| fi |
| |
| shopt -s nullglob |
| for d in "${FUCHSIA_DIR}"/out/*; do |
| local item_rel_path="${d##"${FUCHSIA_DIR}"/}" |
| # Skip known invalid directories |
| if [[ "${item_rel_path}" == */*.zircon || |
| "${item_rel_path}" == */*.device || |
| "${item_rel_path}" == "${current}" || |
| "${item_rel_path}" == */*crash.log || |
| "${item_rel_path}" == */*.json || |
| "${item_rel_path}" == out/_* || |
| "${item_rel_path}" == out/repro_*.instructions || |
| "${item_rel_path}" == out/.*build_lock || |
| "${item_rel_path}" == out/rust-analyzer ]]; then |
| continue #skip |
| fi |
| possible_build_dirs+=("${item_rel_path}") |
| done |
| shopt -u nullglob |
| |
| use_tui=$(fx-get-ui-mode "fx-use") |
| if [[ "$use_tui" == "tui" ]]; then |
| # TUI picker |
| # check if we have any possible build directories to choose from. |
| if [ "${#possible_build_dirs[@]}" -eq 0 ]; then |
| fx-error "There are no current build directories. Make sure you have run fx set." |
| exit 1 |
| fi |
| |
| chosen_dir="$(fx-choose-tui "${possible_build_dirs[@]}" --select-if-one --header="Select a build dir:")" |
| # strip off any trailing spaces and the '(current)' string |
| local suffix=" (current)" |
| if [[ "${chosen_dir}" == *"${suffix}" ]]; then |
| build_dir="${chosen_dir%${suffix}}" |
| else |
| build_dir="${chosen_dir}" |
| fi |
| |
| if [[ -z "${build_dir}" ]]; then |
| # This can happen if users close out of the picker without selecting anything |
| fx-error "No build directory picked. If you still want to change directories,\nrun this command again and select a directory." |
| exit 1 |
| fi |
| else |
| # Non-TUI default |
| fx-info "listing build directories:" |
| for d in "${possible_build_dirs[@]}"; do |
| echo "$d" |
| done |
| return 1 |
| fi |
| fi |
| |
| # Remove trailing slash. |
| # This can potentially lead to the file `out/foo/.device` being written to |
| # when calling `fx set-device` instead `out/foo.device`. |
| # shellcheck disable=SC2001 |
| build_dir="$(echo "$build_dir" | sed 's:/*$::')" |
| |
| if [[ "$build_dir" == /* ]]; then |
| local -r full_build_dir="${build_dir}" |
| else |
| local -r full_build_dir="${FUCHSIA_DIR}/${build_dir}" |
| fi |
| |
| if [[ ! -e "${full_build_dir}/args.gn" ]]; then |
| fx-error "\"${build_dir}\" is not a valid build dir." |
| echo >&2 |
| fx-command-help |
| exit 1 |
| fi |
| |
| fx-change-build-dir "${build_dir}" |
| |
| # Refresh $FUCHSIA_NODENAME to ensure the below checks will report the correct |
| # error message. |
| if [[ -e "${FUCHSIA_BUILD_DIR}.device" ]]; then |
| FUCHSIA_NODENAME="$(<"${FUCHSIA_BUILD_DIR}.device")" |
| else |
| FUCHSIA_NODENAME="" |
| fi |
| |
| # Print the default target status message. |
| # If it's already been printed before, do nothing. |
| has_default_target_status_been_printed="false" |
| function print-default-target-status-once { |
| [[ $has_default_target_status_been_printed == "true" ]] && return |
| out_dir="$(realpath -s --relative-to="$FUCHSIA_DIR" "$FUCHSIA_BUILD_DIR")" |
| if [[ -n "${FUCHSIA_NODENAME}" ]]; then |
| fx-info "The default device for ${out_dir} is \"${FUCHSIA_NODENAME}\"." |
| else |
| fx-info "The default device for ${out_dir} is not set." |
| fi |
| has_default_target_status_been_printed="true" |
| } |
| if [[ -n "${FUCHSIA_NODENAME}" ]]; then |
| print-default-target-status-once |
| fi |
| |
| # Check if the user has set a default target via environment variable(s) |
| # which can override default targets set by `fx set-device`. |
| function external-default-target-env-warning { |
| print-default-target-status-once |
| fx-warn "However, you've overridden this by setting ${ENV_VARS}." |
| if [[ -n "${FUCHSIA_NODENAME}" ]]; then |
| fx-warn "If you want to use \"${FUCHSIA_NODENAME}\", please unset the ${ENV_VAR_NAMES} environment variable." |
| else |
| fx-warn "If you want to use leave it unset, please unset the ${ENV_VAR_NAMES} environment variable." |
| fi |
| |
| # Add a newline to distinguish this as a separate warning than the potential |
| # ffx-related warning below. |
| echo >&2 |
| } |
| fx-if-target-set-by-env external-default-target-env-warning |
| |
| # Check if the user has set a default target via `ffx target default set` |
| # which can override default targets set by `fx set-device`. |
| # Ignore the return code since this will just be a warning. |
| fx-check-ffx-default-target || true |
| } |
| |
| main "$@" |