blob: 4f52c1a2b854759c8dd97aaf4d44fae4412d92e1 [file] [log] [blame] [edit]
#!/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 "$@"