mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
ee18f66aca
Backed out changeset e62f3effd132 (bug 1617748) Backed out changeset 14968570b2f5 (bug 1623701) Backed out changeset 60ac25427773 (bug 1625014)
262 lines
7.2 KiB
Bash
Executable File
262 lines
7.2 KiB
Bash
Executable File
#!/bin/sh
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
# The beginning of this script is both valid POSIX shell and valid Python,
|
|
# such that the script starts with the shell and is reexecuted with
|
|
# the right Python.
|
|
|
|
# Embeds a shell script inside a Python triple quote. This pattern is valid
|
|
# shell because `''':'`, `':'` and `:` are all equivalent, and `:` is a no-op.
|
|
''':'
|
|
py2commands="
|
|
analyze
|
|
android
|
|
android-emulator
|
|
artifact
|
|
awsy-test
|
|
browsertime
|
|
build
|
|
build-backend
|
|
buildsymbols
|
|
cargo
|
|
check-spidermonkey
|
|
clang-format
|
|
compileflags
|
|
configure
|
|
cppunittest
|
|
cramtest
|
|
crashtest
|
|
devtools-css-db
|
|
doctor
|
|
empty-makefiles
|
|
file-info
|
|
firefox-ui-functional
|
|
geckodriver
|
|
geckodriver-test
|
|
geckoview-junit
|
|
gradle
|
|
gtest
|
|
hazards
|
|
ide
|
|
install
|
|
jsapi-tests
|
|
jsshell-bench
|
|
jstestbrowser
|
|
jstests
|
|
marionette-test
|
|
mochitest
|
|
mozbuild-reference
|
|
mozharness
|
|
package
|
|
package-multi-locale
|
|
pastebin
|
|
power
|
|
prettier-format
|
|
puppeteer-test
|
|
python
|
|
python-test
|
|
raptor
|
|
raptor-test
|
|
reftest
|
|
release
|
|
release-history
|
|
remote
|
|
repackage
|
|
resource-usage
|
|
robocop
|
|
run
|
|
rusttests
|
|
show-log
|
|
static-analysis
|
|
talos-test
|
|
taskcluster-build-image
|
|
taskcluster-load-image
|
|
taskgraph
|
|
telemetry-tests-client
|
|
test
|
|
test-info
|
|
tps-build
|
|
try
|
|
valgrind-test
|
|
visualmetrics
|
|
warnings-list
|
|
web-platform-tests
|
|
web-platform-tests-update
|
|
webidl-example
|
|
webidl-parser-test
|
|
webrtc-gtest
|
|
wpt
|
|
wpt-manifest-update
|
|
wpt-metadata-merge
|
|
wpt-metadata-summary
|
|
wpt-serve
|
|
wpt-test-paths
|
|
wpt-unittest
|
|
wpt-update
|
|
xpcshell-test
|
|
"
|
|
|
|
run_py() {
|
|
# Try to run a specific Python interpreter. Fall back to the system
|
|
# default Python if the specific interpreter couldn't be found.
|
|
py_executable="$1"
|
|
shift
|
|
if which "$py_executable" > /dev/null
|
|
then
|
|
exec "$py_executable" "$0" "$@"
|
|
elif [ "$py_executable" = "python2.7" ]; then
|
|
exec python "$0" "$@"
|
|
else
|
|
echo "This mach command requires $py_executable, which wasn't found on the system!"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
first_arg=$1
|
|
if [ "$first_arg" = "help" ]; then
|
|
# When running `./mach help <command>`, the correct Python for <command>
|
|
# needs to be used.
|
|
first_arg=$2
|
|
elif [ "$first_arg" = "mach-completion" ]; then
|
|
# When running `./mach mach-completion /path/to/mach <command>`, the
|
|
# correct Python for <command> needs to be used.
|
|
first_arg=$3
|
|
fi
|
|
|
|
if [ -z "$first_arg" ]; then
|
|
# User ran `./mach` or `./mach help`, use Python 3.
|
|
run_py python3 "$@"
|
|
fi
|
|
|
|
case "${first_arg}" in
|
|
"-"*)
|
|
# We have global arguments which are tricky to parse from this shell
|
|
# script. So invoke `mach` with a special --print-command argument to
|
|
# return the name of the command. This adds extra overhead when using
|
|
# global arguments, but global arguments are an edge case and this hack
|
|
# is only needed temporarily for the Python 3 migration. We use Python
|
|
# 2.7 because using Python 3 hits this error in build tasks:
|
|
# https://searchfox.org/mozilla-central/rev/c7e8bc4996f9/build/moz.configure/init.configure#319
|
|
command=`run_py python2.7 --print-command "$@" | tail -n1`
|
|
;;
|
|
*)
|
|
# In the common case, the first argument is the command.
|
|
command=${first_arg};
|
|
;;
|
|
esac
|
|
|
|
# Check for the mach subcommand in the Python 2 commands list and run it
|
|
# with the correct interpreter.
|
|
case " $(echo $py2commands) " in
|
|
*\ $command\ *)
|
|
run_py python2.7 "$@"
|
|
;;
|
|
*)
|
|
run_py python3 "$@"
|
|
;;
|
|
esac
|
|
|
|
# Run Python 3 for everything else.
|
|
run_py python3 "$@"
|
|
'''
|
|
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
import os
|
|
import sys
|
|
|
|
def ancestors(path):
|
|
while path:
|
|
yield path
|
|
(path, child) = os.path.split(path)
|
|
if child == "":
|
|
break
|
|
|
|
def load_mach(dir_path, mach_path):
|
|
if sys.version_info < (3, 5):
|
|
import imp
|
|
mach_bootstrap = imp.load_source('mach_bootstrap', mach_path)
|
|
else:
|
|
import importlib.util
|
|
spec = importlib.util.spec_from_file_location('mach_bootstrap', mach_path)
|
|
mach_bootstrap = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(mach_bootstrap)
|
|
|
|
return mach_bootstrap.bootstrap(dir_path)
|
|
|
|
|
|
def check_and_get_mach(dir_path):
|
|
bootstrap_paths = (
|
|
'build/mach_bootstrap.py',
|
|
# test package bootstrap
|
|
'tools/mach_bootstrap.py',
|
|
)
|
|
for bootstrap_path in bootstrap_paths:
|
|
mach_path = os.path.join(dir_path, bootstrap_path)
|
|
if os.path.isfile(mach_path):
|
|
return load_mach(dir_path, mach_path)
|
|
return None
|
|
|
|
|
|
def setdefaultenv(key, value):
|
|
"""Compatibility shim to ensure the proper string type is used with
|
|
os.environ for the version of Python being used.
|
|
"""
|
|
encoding = "mbcs" if sys.platform == "win32" else "utf-8"
|
|
|
|
if sys.version_info[0] == 2:
|
|
if isinstance(key, unicode):
|
|
key = key.encode(encoding)
|
|
if isinstance(value, unicode):
|
|
value = value.encode(encoding)
|
|
else:
|
|
if isinstance(key, bytes):
|
|
key = key.decode(encoding)
|
|
if isinstance(value, bytes):
|
|
value = value.decode(encoding)
|
|
|
|
os.environ.setdefault(key, value)
|
|
|
|
|
|
def get_mach():
|
|
# Check whether the current directory is within a mach src or obj dir.
|
|
for dir_path in ancestors(os.getcwd()):
|
|
# If we find a "config.status" and "mozinfo.json" file, we are in the objdir.
|
|
config_status_path = os.path.join(dir_path, 'config.status')
|
|
mozinfo_path = os.path.join(dir_path, 'mozinfo.json')
|
|
if os.path.isfile(config_status_path) and os.path.isfile(mozinfo_path):
|
|
import json
|
|
info = json.load(open(mozinfo_path))
|
|
if 'mozconfig' in info:
|
|
# If the MOZCONFIG environment variable is not already set, set it
|
|
# to the value from mozinfo.json. This will tell the build system
|
|
# to look for a config file at the path in $MOZCONFIG rather than
|
|
# its default locations.
|
|
setdefaultenv('MOZCONFIG', info['mozconfig'])
|
|
|
|
if 'topsrcdir' in info:
|
|
# Continue searching for mach_bootstrap in the source directory.
|
|
dir_path = info['topsrcdir']
|
|
|
|
mach = check_and_get_mach(dir_path)
|
|
if mach:
|
|
return mach
|
|
|
|
# If we didn't find a source path by scanning for a mozinfo.json, check
|
|
# whether the directory containing this script is a source directory. We
|
|
# follow symlinks so mach can be run even if cwd is outside the srcdir.
|
|
return check_and_get_mach(os.path.dirname(os.path.realpath(__file__)))
|
|
|
|
def main(args):
|
|
mach = get_mach()
|
|
if not mach:
|
|
print('Could not run mach: No mach source directory found.')
|
|
sys.exit(1)
|
|
sys.exit(mach.run(args))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main(sys.argv[1:])
|