flutter/bin/flutter

178 lines
6.8 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# ---------------------------------- NOTE ---------------------------------- #
#
# Please keep the logic in this file consistent with the logic in the
# `flutter.bat` script in the same directory to ensure that Flutter continues
# to work across all platforms!
#
# -------------------------------------------------------------------------- #
set -e
unset CDPATH
function follow_links() {
cd -P "${1%/*}"
local file="$PWD/${1##*/}"
while [[ -h "$file" ]]; do
# On Mac OS, readlink -f doesn't work.
cd -P "${file%/*}"
file="$(readlink "$file")"
cd -P "${file%/*}"
file="$PWD/${file##*/}"
done
echo "$PWD/${file##*/}"
}
# Convert a filesystem path to a format usable by Dart's URI parser.
function path_uri() {
# Reduce multiple leading slashes to a single slash.
echo "$1" | sed -E -e "s,^/+,/,"
}
function _rmlock () {
[ -n "$FLUTTER_UPGRADE_LOCK" ] && rm -f "$FLUTTER_UPGRADE_LOCK"
}
function retry_upgrade {
local total_tries="10"
local remaining_tries=$(($total_tries - 1))
while [[ "$remaining_tries" > 0 ]]; do
(cd "$FLUTTER_TOOLS_DIR" && "$PUB" upgrade "$VERBOSITY") && break
echo "Error: Unable to 'pub upgrade' flutter tool. Retrying in five seconds... ($remaining_tries tries left)"
remaining_tries=$(($remaining_tries - 1))
sleep 5
done
if [[ "$remaining_tries" == 0 ]]; then
echo "Command 'pub upgrade' still failed after $total_tries tries, giving up."
return 1
fi
return 0
}
function upgrade_flutter () {
mkdir -p "$FLUTTER_ROOT/bin/cache"
# This function is executed with a redirect that pipes the source of
# this script into file descriptor 3.
#
# To ensure that we don't simultaneously update Dart in multiple
# parallel instances, we try to obtain an exclusive lock on this
# file descriptor (and thus this script's source file) while we are
# updating Dart and compiling the script. To do this, we try to use
# the command line program "flock", which is available on many
# Unix-like platforms, in particular on most Linux distributions.
# You give it a file descriptor, and it locks the corresponding
# file, having inherited the file descriptor from the shell.
#
# Complicating matters, there are two major scenarios where this
# will not work.
#
# The first is if the platform doesn't have "flock", for example on Mac.
# There is not a direct equivalent, so on platforms that don't have flock,
# we fall back to using a lockfile and spinlock with "shlock". This
# doesn't work as well over NFS as it relies on PIDs. Any platform
# without either of these tools has no locking at all. To determine if we
# have "flock" or "shlock" available, we abuse the "hash" shell built-in.
#
# The second complication is NFS. On NFS, to obtain an exclusive
# lock you need a file descriptor that is open for writing, because
# NFS implements exclusive locks by writing, or some such. Thus, we
# ignore errors from flock. We do so by using the '|| true' trick,
# since we are running in a 'set -e' environment wherein all errors
# are fatal, and by redirecting all output to /dev/null, since
# users will typically not care about errors from flock and are
# more likely to be confused by them than helped.
#
# For "flock", the lock is released when the file descriptor goes out of
# scope, i.e. when this function returns. The lock is released via
# a trap when using "shlock".
if hash flock 2>/dev/null; then
flock 3 2>/dev/null || true
elif hash shlock 2>/dev/null; then
FLUTTER_UPGRADE_LOCK="$FLUTTER_ROOT/bin/cache/.upgrade_lock"
while ! shlock -f "$FLUTTER_UPGRADE_LOCK" -p $$ ; do sleep .1 ; done
trap _rmlock EXIT
fi
local revision="$(cd "$FLUTTER_ROOT"; git rev-parse HEAD)"
if [[ ! -f "$SNAPSHOT_PATH" || ! -s "$STAMP_PATH" || "$(cat "$STAMP_PATH")" != "$revision" || "$FLUTTER_TOOLS_DIR/pubspec.yaml" -nt "$FLUTTER_TOOLS_DIR/pubspec.lock" ]]; then
rm -f "$FLUTTER_ROOT/version"
touch "$FLUTTER_ROOT/bin/cache/.dartignore"
"$FLUTTER_ROOT/bin/internal/update_dart_sdk.sh"
VERBOSITY="--verbosity=error"
echo Building flutter tool...
if [[ "$CI" == "true" || "$BOT" == "true" || "$CONTINUOUS_INTEGRATION" == "true" || "$CHROME_HEADLESS" == "1" ]]; then
PUB_ENVIRONMENT="$PUB_ENVIRONMENT:flutter_bot"
VERBOSITY="--verbosity=normal"
fi
export PUB_ENVIRONMENT="$PUB_ENVIRONMENT:flutter_install"
if [[ -d "$FLUTTER_ROOT/.pub-cache" ]]; then
export PUB_CACHE="${PUB_CACHE:-"$FLUTTER_ROOT/.pub-cache"}"
fi
retry_upgrade
"$DART" --snapshot="$SNAPSHOT_PATH" --packages="$FLUTTER_TOOLS_DIR/.packages" "$SCRIPT_PATH"
echo "$revision" > "$STAMP_PATH"
fi
# The exit here is duplicitous since the function is run in a subshell,
# but this serves as documentation that running the function in a
# subshell is required to make sure any lockfile created by shlock
# is cleaned up.
exit $?
}
PROG_NAME="$(path_uri "$(follow_links "$BASH_SOURCE")")"
BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
export FLUTTER_ROOT="$(cd "${BIN_DIR}/.." ; pwd -P)"
FLUTTER_TOOLS_DIR="$FLUTTER_ROOT/packages/flutter_tools"
SNAPSHOT_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.snapshot"
STAMP_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.stamp"
SCRIPT_PATH="$FLUTTER_TOOLS_DIR/bin/flutter_tools.dart"
DART_SDK_PATH="$FLUTTER_ROOT/bin/cache/dart-sdk"
DART="$DART_SDK_PATH/bin/dart"
PUB="$DART_SDK_PATH/bin/pub"
# Test if running as superuser but don't warn if running within Docker
if [[ "$EUID" == "0" && ! -f /.dockerenv ]]; then
echo " Woah! You appear to be trying to run flutter as root."
echo " We strongly recommend running the flutter tool without superuser privileges."
echo " /"
echo "📎"
fi
# Test if Git is available on the Host
if ! hash git 2>/dev/null; then
echo "Error: Unable to find git in your PATH."
exit 1
fi
# Test if the flutter directory is a git clone (otherwise git rev-parse HEAD would fail)
if [[ ! -e "$FLUTTER_ROOT/.git" ]]; then
echo "Error: The Flutter directory is not a clone of the GitHub project."
echo " The flutter tool requires Git in order to operate properly;"
echo " to set up Flutter, run the following command:"
echo " git clone -b stable https://github.com/flutter/flutter.git"
exit 1
fi
# To debug the tool, you can uncomment the following lines to enable checked mode and set an observatory port:
# FLUTTER_TOOL_ARGS="--checked $FLUTTER_TOOL_ARGS"
# FLUTTER_TOOL_ARGS="$FLUTTER_TOOL_ARGS --observe=65432"
(upgrade_flutter) 3< "$PROG_NAME"
# FLUTTER_TOOL_ARGS isn't quoted below, because it is meant to be considered as
# separate space-separated args.
"$DART" $FLUTTER_TOOL_ARGS "$SNAPSHOT_PATH" "$@"