#!/usr/bin/env bash
# Determine the path to this script (we'll use this to figure out relative positions of other files)
SOURCE="${BASH_SOURCE[0]}"
if [ -h "$SOURCE" ]; then
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
PREV_DIR="$(dirname "$SOURCE")"
SOURCE="$(readlink "$SOURCE")"
SOURCE_NAME="$(basename "$SOURCE")"
# if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
if [[ $SOURCE != /* ]]; then
SCRIPT_PATH="$( cd -P "${PREV_DIR}/$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
SOURCE="$SCRIPT_PATH/$SOURCE_NAME"
else
SCRIPT_PATH="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
fi
done
else
SCRIPT_PATH="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
fi
# Check if we are running 'Dev Mode' and if so, override values for devs
SCRIPT_BASENAME=$(basename "$SCRIPT_PATH")
if [ "${SCRIPT_BASENAME}" == "bin" ]; then
# we can be running dev mode with a symlink to the package/dist/bin folder. In this case, our relative path is two levels up.
export QUARTO_ROOT="`cd "$SCRIPT_PATH/../../.." > /dev/null 2>&1 && pwd`"
elif [ "${SCRIPT_BASENAME}" == "common" ]; then
# we can run this script directly in the source tree. In this case, our relative path is three levels up.
export QUARTO_ROOT="`cd "$SCRIPT_PATH/../../.." > /dev/null 2>&1 && pwd`"
else
echo "ERROR: Cannot determine the Quarto source path. This script must be run from the bin or common folder."
exit 1
fi
QUARTO_SRC_PATH="$QUARTO_ROOT/src"
DEV_PATH=$QUARTO_SRC_PATH/quarto.ts
if [ -f "$DEV_PATH" ]; then
QUARTO_DEV_MODE=true
QUARTO_IMPORT_MAP_ARG=--importmap=$QUARTO_SRC_PATH/import_map.json
if [ "$1" == "--version" ] || [ "$1" == "-v" ]; then
if [ "$QUARTO_FORCE_VERSION" != "" ]; then
echo $QUARTO_FORCE_VERSION
exit 0
fi
echo "99.9.9"
exit 0
fi
# Caller can point deno at another entry point (e.g. the typescript file)
if [ -z ${QUARTO_ACTION+x} ]; then
QUARTO_ACTION=run
fi
# Turn on type checking for dev version
if [ -z ${QUARTO_NO_TYPECHECK+x} ]; then
QUARTO_DENO_OPTIONS=--check
fi
# Allow calls to override the target
if [ -z ${QUARTO_TARGET+x} ]; then
QUARTO_TARGET=$DEV_PATH
fi
export QUARTO_BIN_PATH=$SCRIPT_PATH
export QUARTO_SHARE_PATH="${QUARTO_SHARE_PATH=$QUARTO_SRC_PATH/resources/}"
export DENO_DIR=$QUARTO_BIN_PATH/deno_cache
if [ -z ${QUARTO_DEBUG+x} ]; then
export QUARTO_DEBUG=true
fi
QUARTO_CACHE_OPTIONS="--cached-only"
# Check for deno update
QUARTO_DIST_CONFIG=$QUARTO_BIN_PATH/../config
mkdir -p $QUARTO_DIST_CONFIG
DENO_VERSION_FILE=$QUARTO_DIST_CONFIG/deno-version
DENO_SOURCE_VERSION="`(cd "$QUARTO_ROOT" && source ./configuration && echo $DENO)`"
if [ -f "$DENO_VERSION_FILE" ]; then
# echo is to trim whitespace to avoid version comparison issues
DENO_INSTALLED_VERSION=$(echo `cat "$DENO_VERSION_FILE"`)
if [ "${DENO_SOURCE_VERSION}" != "${DENO_INSTALLED_VERSION}" ]; then
# configure will call back into this script so we need to update the
# version so that the check will pass next time through
(cd "$QUARTO_ROOT" && ./configure.sh)
echo ""
printf "\\033[0;31mQuarto required reconfiguration to install Deno. Had ${DENO_INSTALLED_VERSION}, needed ${DENO_SOURCE_VERSION}. Please try command again.\\033[0m\n\n"
exit 1
fi
fi
else
QUARTO_ACTION=run
QUARTO_TARGET=${SCRIPT_PATH}/quarto.js
export QUARTO_BIN_PATH=$SCRIPT_PATH
QUARTO_CACHE_OPTIONS="--cached-only"
# Turn off type checking for bundled version
QUARTO_DENO_OPTIONS=--no-check
# If Quarto is bundled into an `.app` file, it will be looking for the
# share directory over in the resources folder.
if [ -z "${QUARTO_SHARE_PATH+x}" ]; then
if [[ $SCRIPT_PATH == *"/Contents/MacOS/quarto/bin" ]]; then
export QUARTO_SHARE_PATH="`cd "$SCRIPT_PATH/../../../Resources/quarto/share";pwd`"
elif [[ $SCRIPT_PATH == *"/usr/local/bin/quarto" ]]; then
export QUARTO_SHARE_PATH="`cd "$SCRIPT_PATH/../../share/quarto";pwd`"
else
export QUARTO_SHARE_PATH="`cd "$SCRIPT_PATH/../share";pwd`"
fi
fi
if [ "$1" == "--version" ] || [ "$1" == "-v" ]; then
if [ "$QUARTO_FORCE_VERSION" != "" ]; then
echo $QUARTO_FORCE_VERSION
exit 0
fi
echo `cat "$QUARTO_SHARE_PATH/version"`
exit 0
fi
fi
if [ "$1" == "--paths" ]; then
echo "$QUARTO_BIN_PATH"
echo "$QUARTO_SHARE_PATH"
exit 0
fi
if [[ $OSTYPE == 'darwin'* ]]; then
# We cannot use uname to determine the _machine_ architecture:
# https://github.com/quarto-dev/quarto-cli/issues/2420#issuecomment-1245768732
# However, sysctl can return unexpected values in sandboxed/virtualized environments.
# Use sysctl -n to get just the value, and check multiple possible patterns.
FULLARCH="$(/usr/sbin/sysctl -n machdep.cpu.brand_string 2>/dev/null)"
if [[ $FULLARCH == *"Intel"* ]] || [[ $FULLARCH == *"Xeon"* ]] || [[ $FULLARCH == *"Core"* ]]; then
ARCH_DIR=x86_64
elif [[ $FULLARCH == *"Apple"* ]] || [[ $FULLARCH == *"ARM"* ]]; then
ARCH_DIR=aarch64
else
# Fallback to uname -m if sysctl doesn't give us recognizable output
# This helps with sandboxed/virtualized environments
UNAME_ARCH=$(uname -m)
if [[ $UNAME_ARCH == "x86_64" ]]; then
ARCH_DIR=x86_64
elif [[ $UNAME_ARCH == "arm64" ]]; then
ARCH_DIR=aarch64
else
echo "quarto script failed: unrecognized architecture. sysctl returned: '${FULLARCH}', uname -m returned: '${UNAME_ARCH}'"
exit 1
fi
fi
else
NIXARCH=$(uname -m)
if [[ $NIXARCH == "x86_64" ]]; then
ARCH_DIR=x86_64
elif [[ $NIXARCH == "aarch64" ]]; then
ARCH_DIR=aarch64
else
echo "configure script failed: unrecognized architecture " ${NIXARCH}
exit 1
fi
fi
if [ "$QUARTO_DENO_DOM" != "" ]; then
export DENO_DOM_PLUGIN=$QUARTO_DENO_DOM
elif [ "$(uname)" = "Darwin" ]; then
export DENO_DOM_PLUGIN=$QUARTO_BIN_PATH/tools/${ARCH_DIR}/deno_dom/libplugin.dylib
else
export DENO_DOM_PLUGIN=$QUARTO_BIN_PATH/tools/${ARCH_DIR}/deno_dom/libplugin.so
fi
if [ "$QUARTO_DENO" == "" ]; then
DENO_ARCH_DIR=$ARCH_DIR
export QUARTO_DENO="${SCRIPT_PATH}/tools/${DENO_ARCH_DIR}/deno"
fi
export DENO_TLS_CA_STORE=system,mozilla
export DENO_NO_UPDATE_CHECK=1
# Be sure to include any already defined QUARTO_DENO_OPTIONS
## Using --allow-all as there is otherwise an issue in Deno 1.46.3 with --allow-read and --allow-write with network drives
## https://github.com/quarto-dev/quarto-cli/issues/11332
QUARTO_DENO_OPTIONS="--unstable-ffi --unstable-kv --no-config --no-lock ${QUARTO_CACHE_OPTIONS} --allow-all ${QUARTO_DENO_OPTIONS}"
# --enable-experimental-regexp-engine is required for /regex/l, https://github.com/quarto-dev/quarto-cli/issues/9737
if [ "$QUARTO_DENO_V8_OPTIONS" != "" ]; then
QUARTO_DENO_V8_OPTIONS="--enable-experimental-regexp-engine,--max-old-space-size=8192,--max-heap-size=8192,--stack-trace-limit=100,${QUARTO_DENO_V8_OPTIONS}"
else
QUARTO_DENO_V8_OPTIONS="--enable-experimental-regexp-engine,--max-old-space-size=8192,--max-heap-size=8192,--stack-trace-limit=100"
fi
if [ "$QUARTO_DENO_EXTRA_OPTIONS" == "" ]; then
QUARTO_DENO_EXTRA_OPTIONS="--v8-flags=${QUARTO_DENO_V8_OPTIONS}"
else
QUARTO_DENO_EXTRA_OPTIONS="--v8-flags=${QUARTO_DENO_V8_OPTIONS} ${QUARTO_DENO_EXTRA_OPTIONS}"
fi
if [ "$QUARTO_TS_PROFILE" != "" ]; then
QUARTO_DENO_EXTRA_OPTIONS="--inspect-brk ${QUARTO_DENO_EXTRA_OPTIONS}"
QUARTO_TS_PROFILE=true "${QUARTO_DENO}" ${QUARTO_ACTION} ${QUARTO_DENO_OPTIONS} ${QUARTO_DENO_EXTRA_OPTIONS} "${QUARTO_IMPORT_MAP_ARG}" "${QUARTO_TARGET}" "$@"
else
if [ "$QUARTO_DEV_MODE" == true ]; then
"${QUARTO_DENO}" ${QUARTO_ACTION} ${QUARTO_DENO_OPTIONS} ${QUARTO_DENO_EXTRA_OPTIONS} "${QUARTO_IMPORT_MAP_ARG}" "${QUARTO_TARGET}" "$@"
else
"${QUARTO_DENO}" ${QUARTO_ACTION} ${QUARTO_DENO_OPTIONS} ${QUARTO_DENO_EXTRA_OPTIONS} "${QUARTO_TARGET}" "$@"
fi
fi