325 lines
13 KiB
Bash
325 lines
13 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
LOAD_ENV_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
DEFAULT_OMNISOCKETGO_ROOT="$(cd "${LOAD_ENV_SCRIPT_DIR}/../.." && pwd)"
|
|
|
|
die() {
|
|
echo "$*" >&2
|
|
return 1 2>/dev/null || exit 1
|
|
}
|
|
|
|
normalize_loaded_env_vars() {
|
|
local var_name
|
|
local value
|
|
|
|
for var_name in $(compgen -A variable); do
|
|
case "${var_name}" in
|
|
BACKEND_*|BLITZ_*|B_SIDE_*|CONTROL_*|FRONTEND_*|OMNI_*|PYTHON3_BIN|PYTHON_VENV_PATH|ROBOT_*|ROS_DISTRO|VITE_*)
|
|
value="${!var_name}"
|
|
if [[ "${value}" == *$'\r' ]]; then
|
|
printf -v "${var_name}" '%s' "${value%$'\r'}"
|
|
export "${var_name}"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
is_omnisocketgo_root() {
|
|
local dir="$1"
|
|
[[ -f "${dir}/Makefile" && -f "${dir}/cmd/b_side_omnid.c" && -d "${dir}/ros-control-py" ]]
|
|
}
|
|
|
|
is_robot_command_center_root() {
|
|
local dir="$1"
|
|
[[ -f "${dir}/backend/config/asgi.py" && -f "${dir}/frontend/package.json" ]]
|
|
}
|
|
|
|
require_robot_command_center_root() {
|
|
if ! is_robot_command_center_root "${ROBOT_COMMAND_CENTER_ROOT}"; then
|
|
die "ROBOT_COMMAND_CENTER_ROOT must point to the robot-command-center repo root. Current value: ${ROBOT_COMMAND_CENTER_ROOT}. Set it in ${LOAD_ENV_SCRIPT_DIR}/robot-remote.env.local if needed."
|
|
fi
|
|
}
|
|
|
|
export OMNISOCKETGO_ROOT="${OMNISOCKETGO_ROOT:-${DEFAULT_OMNISOCKETGO_ROOT}}"
|
|
|
|
omni_camera_device_was_set=0
|
|
omni_camera_profile_was_set=0
|
|
omni_camera_brightness_was_set=0
|
|
omni_camera_custom_ctrl_was_set=0
|
|
omni_camera_verify_was_set=0
|
|
|
|
if [[ "${OMNI_CAMERA_DEVICE+x}" == "x" ]]; then
|
|
omni_camera_device_was_set=1
|
|
preserved_omni_camera_device="${OMNI_CAMERA_DEVICE}"
|
|
fi
|
|
if [[ "${OMNI_CAMERA_PROFILE+x}" == "x" ]]; then
|
|
omni_camera_profile_was_set=1
|
|
preserved_omni_camera_profile="${OMNI_CAMERA_PROFILE}"
|
|
fi
|
|
if [[ "${OMNI_CAMERA_BRIGHTNESS+x}" == "x" ]]; then
|
|
omni_camera_brightness_was_set=1
|
|
preserved_omni_camera_brightness="${OMNI_CAMERA_BRIGHTNESS}"
|
|
fi
|
|
if [[ "${OMNI_CAMERA_CUSTOM_CTRL+x}" == "x" ]]; then
|
|
omni_camera_custom_ctrl_was_set=1
|
|
preserved_omni_camera_custom_ctrl="${OMNI_CAMERA_CUSTOM_CTRL}"
|
|
fi
|
|
if [[ "${OMNI_CAMERA_VERIFY+x}" == "x" ]]; then
|
|
omni_camera_verify_was_set=1
|
|
preserved_omni_camera_verify="${OMNI_CAMERA_VERIFY}"
|
|
fi
|
|
|
|
ENV_FILES=(
|
|
"${LOAD_ENV_SCRIPT_DIR}/robot-remote.env"
|
|
"${LOAD_ENV_SCRIPT_DIR}/robot-remote.env.local"
|
|
)
|
|
|
|
for env_file in "${ENV_FILES[@]}"; do
|
|
if [[ -f "${env_file}" ]]; then
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
source "${env_file}"
|
|
set +a
|
|
fi
|
|
done
|
|
|
|
normalize_loaded_env_vars
|
|
|
|
if [[ "${omni_camera_device_was_set}" == "1" ]]; then
|
|
export OMNI_CAMERA_DEVICE="${preserved_omni_camera_device}"
|
|
fi
|
|
if [[ "${omni_camera_profile_was_set}" == "1" ]]; then
|
|
export OMNI_CAMERA_PROFILE="${preserved_omni_camera_profile}"
|
|
fi
|
|
if [[ "${omni_camera_brightness_was_set}" == "1" ]]; then
|
|
export OMNI_CAMERA_BRIGHTNESS="${preserved_omni_camera_brightness}"
|
|
fi
|
|
if [[ "${omni_camera_custom_ctrl_was_set}" == "1" ]]; then
|
|
export OMNI_CAMERA_CUSTOM_CTRL="${preserved_omni_camera_custom_ctrl}"
|
|
fi
|
|
if [[ "${omni_camera_verify_was_set}" == "1" ]]; then
|
|
export OMNI_CAMERA_VERIFY="${preserved_omni_camera_verify}"
|
|
fi
|
|
|
|
export OMNISOCKETGO_ROOT="${OMNISOCKETGO_ROOT:-${DEFAULT_OMNISOCKETGO_ROOT}}"
|
|
export ROBOT_COMMAND_CENTER_ROOT="${ROBOT_COMMAND_CENTER_ROOT:-$(dirname "${OMNISOCKETGO_ROOT}")/robot-command-center}"
|
|
|
|
if ! is_omnisocketgo_root "${OMNISOCKETGO_ROOT}"; then
|
|
die "OMNISOCKETGO_ROOT must point to the OmniSocketGo repo root. Current value: ${OMNISOCKETGO_ROOT}"
|
|
fi
|
|
|
|
export BACKEND_DIR="${BACKEND_DIR:-${ROBOT_COMMAND_CENTER_ROOT}/backend}"
|
|
export FRONTEND_DIR="${FRONTEND_DIR:-${ROBOT_COMMAND_CENTER_ROOT}/frontend}"
|
|
export ROS_CONTROL_PY_DIR="${ROS_CONTROL_PY_DIR:-${OMNISOCKETGO_ROOT}/ros-control-py}"
|
|
export PYTHON3_BIN="${PYTHON3_BIN:-python3}"
|
|
export PYTHON_VENV_PATH="${PYTHON_VENV_PATH:-${OMNISOCKETGO_ROOT}/.venv}"
|
|
export BACKEND_HOST="${BACKEND_HOST:-0.0.0.0}"
|
|
export BACKEND_PORT="${BACKEND_PORT:-8001}"
|
|
export FRONTEND_HOST="${FRONTEND_HOST:-0.0.0.0}"
|
|
export FRONTEND_PORT="${FRONTEND_PORT:-5173}"
|
|
export OMNISOCKET_TELEMETRY_PEER_ID="${OMNISOCKET_TELEMETRY_PEER_ID:-peer-a-telemetry}"
|
|
export OMNISOCKET_TELEMETRY_INTERVAL_MS="${OMNISOCKET_TELEMETRY_INTERVAL_MS:-1000}"
|
|
export OMNISOCKET_TELEMETRY_STALE_AFTER_MS="${OMNISOCKET_TELEMETRY_STALE_AFTER_MS:-3000}"
|
|
export OMNI_NETWORK_SUMMARY_LOG_ENABLED="${OMNI_NETWORK_SUMMARY_LOG_ENABLED:-1}"
|
|
export OMNI_NETWORK_SUMMARY_LOG_PATH="${OMNI_NETWORK_SUMMARY_LOG_PATH:-${OMNISOCKETGO_ROOT}/logs/a-network-summary.jsonl}"
|
|
export OMNI_NETWORK_SUMMARY_LOG_INTERVAL_MS="${OMNI_NETWORK_SUMMARY_LOG_INTERVAL_MS:-1000}"
|
|
export OMNI_NETWORK_SUMMARY_LOG_REQUEST_TIMEOUT_SEC="${OMNI_NETWORK_SUMMARY_LOG_REQUEST_TIMEOUT_SEC:-3}"
|
|
export CONTROL_SIDE_OMNISOCKET_SERVER_ADDR="${CONTROL_SIDE_OMNISOCKET_SERVER_ADDR:-}"
|
|
export CONTROL_SIDE_OMNISOCKET_RELAY_VIA="${CONTROL_SIDE_OMNISOCKET_RELAY_VIA:-}"
|
|
export ROBOT_SIDE_OMNISOCKET_SERVER_ADDR="${ROBOT_SIDE_OMNISOCKET_SERVER_ADDR:-}"
|
|
export ROBOT_SIDE_OMNISOCKET_RELAY_VIA="${ROBOT_SIDE_OMNISOCKET_RELAY_VIA:-}"
|
|
export ROS_DISTRO="${ROS_DISTRO:-jazzy}"
|
|
export ROBOT_RECEIVER_TRANSPORT="${ROBOT_RECEIVER_TRANSPORT:-unix_dgram}"
|
|
export ROBOT_RECEIVER_SERVER_ADDR="${ROBOT_RECEIVER_SERVER_ADDR:-${ROBOT_SIDE_OMNISOCKET_SERVER_ADDR:-}}"
|
|
export ROBOT_RECEIVER_RELAY_VIA="${ROBOT_RECEIVER_RELAY_VIA:-${ROBOT_SIDE_OMNISOCKET_RELAY_VIA:-}}"
|
|
export ROBOT_RECEIVER_PEER_ID="${ROBOT_RECEIVER_PEER_ID:-ros-bridge-ctrl}"
|
|
export ROBOT_RECEIVER_EXPECTED_SENDER="${ROBOT_RECEIVER_EXPECTED_SENDER:-}"
|
|
export ROBOT_RECEIVER_LOCAL_SOCKET_PATH="${ROBOT_RECEIVER_LOCAL_SOCKET_PATH:-/tmp/omnisocket-b-side-cmd.sock}"
|
|
export ROBOT_RECEIVER_OUTPUT_TOPIC="${ROBOT_RECEIVER_OUTPUT_TOPIC:-/hric/robot/cmd_vel}"
|
|
export ROBOT_RECEIVER_FRAME_ID="${ROBOT_RECEIVER_FRAME_ID:-pelvis}"
|
|
export ROBOT_RECEIVER_WATCHDOG_TIMEOUT="${ROBOT_RECEIVER_WATCHDOG_TIMEOUT:-0.5}"
|
|
export ROBOT_RECEIVER_PUBLISH_RATE_HZ="${ROBOT_RECEIVER_PUBLISH_RATE_HZ:-100.0}"
|
|
export OMNI_CAMERA_DEVICE="${OMNI_CAMERA_DEVICE:-/dev/video0}"
|
|
export OMNI_CAMERA_PROFILE="${OMNI_CAMERA_PROFILE:-night}"
|
|
export OMNI_CAMERA_BRIGHTNESS="${OMNI_CAMERA_BRIGHTNESS:-}"
|
|
export OMNI_CAMERA_CUSTOM_CTRL="${OMNI_CAMERA_CUSTOM_CTRL:-}"
|
|
export OMNI_CAMERA_VERIFY="${OMNI_CAMERA_VERIFY:-0}"
|
|
export OMNI_GPSD_HOST="${OMNI_GPSD_HOST:-127.0.0.1}"
|
|
export OMNI_VIDEO_SERVER_ADDR="${OMNI_VIDEO_SERVER_ADDR:-${ROBOT_SIDE_OMNISOCKET_SERVER_ADDR:-}}"
|
|
export OMNI_VIDEO_RELAY_VIA="${OMNI_VIDEO_RELAY_VIA:-${ROBOT_SIDE_OMNISOCKET_RELAY_VIA:-}}"
|
|
export OMNI_CONTROL_SERVER_ADDR="${OMNI_CONTROL_SERVER_ADDR:-${ROBOT_SIDE_OMNISOCKET_SERVER_ADDR:-}}"
|
|
export OMNI_CONTROL_RELAY_VIA="${OMNI_CONTROL_RELAY_VIA:-${ROBOT_SIDE_OMNISOCKET_RELAY_VIA:-}}"
|
|
export OMNI_CONTROL_UNIX_SOCKET_PATH="${OMNI_CONTROL_UNIX_SOCKET_PATH:-${ROBOT_RECEIVER_LOCAL_SOCKET_PATH}}"
|
|
export OMNI_CONTROL_ACK_PEER_ID="${OMNI_CONTROL_ACK_PEER_ID:-peer-b-ctrl-ack}"
|
|
export OMNI_CONTROL_ACK_TARGET_PEER="${OMNI_CONTROL_ACK_TARGET_PEER:-peer-a-ctrl-ack}"
|
|
export B_SIDE_OMNID_USE_SUDO="${B_SIDE_OMNID_USE_SUDO:-1}"
|
|
export BLITZ_RUNTIME_DIR="${BLITZ_RUNTIME_DIR:-${OMNISOCKETGO_ROOT}/logs/runtime}"
|
|
export BLITZ_RUN_ROOT="${BLITZ_RUN_ROOT:-${OMNISOCKETGO_ROOT}/logs}"
|
|
export BLITZ_RUN_CONTEXT_FILE="${BLITZ_RUN_CONTEXT_FILE:-${BLITZ_RUNTIME_DIR}/run-context.env}"
|
|
export BLITZ_RUN_ID_FILE="${BLITZ_RUN_ID_FILE:-${BLITZ_RUNTIME_DIR}/run-id}"
|
|
export BLITZ_CURRENT_RUN_LINK="${BLITZ_CURRENT_RUN_LINK:-${BLITZ_RUN_ROOT}/current}"
|
|
export BLITZ_5G_INTERFACE="${BLITZ_5G_INTERFACE:-}"
|
|
export BLITZ_5G_MODEM_SUBNET="${BLITZ_5G_MODEM_SUBNET:-192.168.224.0/22}"
|
|
export BLITZ_5G_GATEWAY="${BLITZ_5G_GATEWAY:-192.168.225.1}"
|
|
export BLITZ_5G_ROUTE_TARGETS="${BLITZ_5G_ROUTE_TARGETS:-106.55.173.235}"
|
|
export BLITZ_5G_INFO_JSON="${BLITZ_5G_INFO_JSON:-${OMNISOCKETGO_ROOT}/scripts/boot/modem_network_info.json}"
|
|
export BLITZ_TIME_SERVER_IP="${BLITZ_TIME_SERVER_IP:-}"
|
|
export BLITZ_KCP_STATS_INTERVAL_MS="${BLITZ_KCP_STATS_INTERVAL_MS:-1000}"
|
|
export BLITZ_CONTROL_LATENCY_LOG_ENABLED="${BLITZ_CONTROL_LATENCY_LOG_ENABLED:-1}"
|
|
export BLITZ_CONTROL_LATENCY_LOG_SAMPLE_MOD="${BLITZ_CONTROL_LATENCY_LOG_SAMPLE_MOD:-100}"
|
|
export BLITZ_CONTROL_ACK_SAMPLE_MOD="${BLITZ_CONTROL_ACK_SAMPLE_MOD:-10}"
|
|
export BLITZ_VIDEO_STAGE_LOG_ENABLED="${BLITZ_VIDEO_STAGE_LOG_ENABLED:-1}"
|
|
export BLITZ_VIDEO_STAGE_LOG_SAMPLE_MOD="${BLITZ_VIDEO_STAGE_LOG_SAMPLE_MOD:-10}"
|
|
export BLITZ_5G_LINK_LOG_INTERVAL_SEC="${BLITZ_5G_LINK_LOG_INTERVAL_SEC:-5}"
|
|
export BLITZ_JSONL_FLUSH_INTERVAL_MS="${BLITZ_JSONL_FLUSH_INTERVAL_MS:-1000}"
|
|
export BLITZ_JSONL_FLUSH_BYTES="${BLITZ_JSONL_FLUSH_BYTES:-262144}"
|
|
export BLITZ_JSONL_ROTATE_BYTES="${BLITZ_JSONL_ROTATE_BYTES:-134217728}"
|
|
export BLITZ_JSONL_ROTATE_FILES="${BLITZ_JSONL_ROTATE_FILES:-8}"
|
|
|
|
blitz_dev_utc_compact_timestamp() {
|
|
date -u '+%Y%m%dT%H%M%SZ'
|
|
}
|
|
|
|
blitz_dev_git_commit() {
|
|
git -C "${OMNISOCKETGO_ROOT}" rev-parse HEAD 2>/dev/null || true
|
|
}
|
|
|
|
blitz_dev_git_dirty_flag() {
|
|
if git -C "${OMNISOCKETGO_ROOT}" diff --quiet --ignore-submodules=dirty >/dev/null 2>&1; then
|
|
printf '0\n'
|
|
return 0
|
|
fi
|
|
printf '1\n'
|
|
}
|
|
|
|
blitz_dev_prepare_dirs() {
|
|
mkdir -p "${BLITZ_RUNTIME_DIR}" "${BLITZ_RUN_ROOT}/runs" "${BLITZ_RUN_ROOT}/incidents"
|
|
}
|
|
|
|
blitz_dev_write_run_info() {
|
|
local run_dir="$1"
|
|
local run_id="$2"
|
|
local boot_id="$3"
|
|
local tmp_info="${run_dir}/run-info.json.tmp.$$"
|
|
local started_at
|
|
local commit_hash
|
|
local dirty_flag
|
|
|
|
started_at="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
|
|
commit_hash="$(blitz_dev_git_commit)"
|
|
dirty_flag="$(blitz_dev_git_dirty_flag)"
|
|
|
|
python3 - "${tmp_info}" "${run_id}" "${run_dir}" "${boot_id}" "${started_at}" "${commit_hash}" "${dirty_flag}" "${HOSTNAME:-$(hostname)}" <<'PY'
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
path, run_id, run_dir, boot_id, started_at, commit_hash, dirty_flag, hostname = sys.argv[1:9]
|
|
payload = {
|
|
"run_id": run_id,
|
|
"run_dir": run_dir,
|
|
"boot_id": boot_id,
|
|
"started_at": started_at,
|
|
"hostname": hostname,
|
|
"git_commit": commit_hash,
|
|
"git_dirty": dirty_flag == "1",
|
|
"env": {
|
|
key: os.environ.get(key, "")
|
|
for key in sorted(os.environ)
|
|
if key.startswith(("BLITZ_", "OMNI_", "ROBOT_RECEIVER_"))
|
|
},
|
|
}
|
|
with open(path, "w", encoding="utf-8") as handle:
|
|
json.dump(payload, handle, ensure_ascii=False, indent=2, sort_keys=True)
|
|
PY
|
|
mv -f "${tmp_info}" "${run_dir}/run-info.json"
|
|
}
|
|
|
|
blitz_dev_init_run_context() {
|
|
local run_id="${1:-$(blitz_dev_utc_compact_timestamp)}"
|
|
local boot_id="dev-$(blitz_dev_utc_compact_timestamp)"
|
|
local run_dir="${BLITZ_RUN_ROOT}/runs/${run_id}"
|
|
local tmp_context="${BLITZ_RUN_CONTEXT_FILE}.tmp.$$"
|
|
|
|
blitz_dev_prepare_dirs
|
|
mkdir -p "${run_dir}"
|
|
export BLITZ_RUN_ID="${run_id}"
|
|
export BLITZ_RUN_DIR="${run_dir}"
|
|
export BLITZ_BOOT_ID="${boot_id}"
|
|
printf '%s\n' "${run_id}" > "${BLITZ_RUN_ID_FILE}"
|
|
cat > "${tmp_context}" <<EOF
|
|
BLITZ_RUN_ID=${run_id}
|
|
BLITZ_RUN_DIR=${run_dir}
|
|
BLITZ_BOOT_ID=${boot_id}
|
|
BLITZ_RUN_ROOT=${BLITZ_RUN_ROOT}
|
|
EOF
|
|
mv -f "${tmp_context}" "${BLITZ_RUN_CONTEXT_FILE}"
|
|
ln -sfn "${run_dir}" "${BLITZ_CURRENT_RUN_LINK}"
|
|
blitz_dev_write_run_info "${run_dir}" "${run_id}" "${boot_id}"
|
|
}
|
|
|
|
blitz_dev_load_run_context() {
|
|
if [[ ! -f "${BLITZ_RUN_CONTEXT_FILE}" ]]; then
|
|
return 1
|
|
fi
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
source "${BLITZ_RUN_CONTEXT_FILE}"
|
|
set +a
|
|
}
|
|
|
|
blitz_dev_ensure_run_context() {
|
|
if blitz_dev_load_run_context; then
|
|
return 0
|
|
fi
|
|
blitz_dev_init_run_context
|
|
}
|
|
|
|
blitz_dev_reset_run_context() {
|
|
rm -f "${BLITZ_RUN_CONTEXT_FILE}" "${BLITZ_RUN_ID_FILE}"
|
|
blitz_dev_init_run_context
|
|
}
|
|
|
|
blitz_dev_init_instance_context() {
|
|
if [[ -z "${BLITZ_INSTANCE_ID:-}" ]]; then
|
|
export BLITZ_INSTANCE_ID="$(blitz_dev_utc_compact_timestamp)-$$"
|
|
fi
|
|
}
|
|
|
|
blitz_dev_component_log_path() {
|
|
local stem="$1"
|
|
printf '%s/%s.%s.jsonl\n' "${BLITZ_RUN_DIR}" "${stem}" "${BLITZ_INSTANCE_ID}"
|
|
}
|
|
|
|
blitz_dev_prepare_backend_logging_env() {
|
|
blitz_dev_init_instance_context
|
|
if [[ "${OMNI_NETWORK_SUMMARY_LOG_PATH}" == "${OMNISOCKETGO_ROOT}/logs/a-network-summary.jsonl" ]]; then
|
|
export OMNI_NETWORK_SUMMARY_LOG_PATH
|
|
OMNI_NETWORK_SUMMARY_LOG_PATH="$(blitz_dev_component_log_path "a-network-summary")"
|
|
fi
|
|
export BLITZ_A_CONTROL_EVENTS_LOG_PATH="${BLITZ_A_CONTROL_EVENTS_LOG_PATH:-$(blitz_dev_component_log_path "a-control-events")}"
|
|
export BLITZ_A_CONTROL_ACKS_LOG_PATH="${BLITZ_A_CONTROL_ACKS_LOG_PATH:-$(blitz_dev_component_log_path "a-control-acks")}"
|
|
export BLITZ_A_VIDEO_FRAME_RECV_LOG_PATH="${BLITZ_A_VIDEO_FRAME_RECV_LOG_PATH:-$(blitz_dev_component_log_path "a-video-frame-recv")}"
|
|
export BLITZ_A_VIDEO_DISPLAY_PROBE_LOG_PATH="${BLITZ_A_VIDEO_DISPLAY_PROBE_LOG_PATH:-$(blitz_dev_component_log_path "a-video-display-probe")}"
|
|
}
|
|
|
|
blitz_dev_prepare_bside_logging_env() {
|
|
blitz_dev_init_instance_context
|
|
export BLITZ_KCP_STATS_LOG_PATH="${BLITZ_KCP_STATS_LOG_PATH:-$(blitz_dev_component_log_path "b-kcp-session-stats")}"
|
|
export BLITZ_CONTROL_LATENCY_LOG_PATH="${BLITZ_CONTROL_LATENCY_LOG_PATH:-$(blitz_dev_component_log_path "b-control-latency")}"
|
|
export BLITZ_VIDEO_STAGE_LOG_PATH="${BLITZ_VIDEO_STAGE_LOG_PATH:-$(blitz_dev_component_log_path "b-video-frame-stages")}"
|
|
}
|
|
|
|
blitz_dev_prepare_5g_logging_env() {
|
|
blitz_dev_init_instance_context
|
|
export BLITZ_5G_LINK_LOG_PATH="${BLITZ_5G_LINK_LOG_PATH:-$(blitz_dev_component_log_path "b-5g-link-quality")}"
|
|
}
|
|
|
|
if [[ "${BLITZ_SKIP_DEV_RUN_CONTEXT_INIT:-0}" != "1" && "${BLITZ_BOOT_LOADING_ENV:-0}" != "1" && "${OMNI_BOOT_MODE:-0}" != "1" ]]; then
|
|
blitz_dev_ensure_run_context
|
|
elif [[ -f "${BLITZ_RUN_CONTEXT_FILE}" ]]; then
|
|
blitz_dev_load_run_context || true
|
|
fi
|