2 # This Source Code Form is subject to the terms of the Mozilla Public
3 # License, v. 2.0. If a copy of the MPL was not distributed with this
4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 # The beginning of this script is both valid POSIX shell and valid Python,
7 # such that the script starts with the shell and is reexecuted with
10 # Embeds a shell script inside a Python triple quote. This pattern is valid
11 # shell because `''':'`, `':'` and `:` are all equivalent, and `:` is a no-op.
15 # Parse the name of the mach command out of the arguments. This is necessary
16 # in the presence of global mach arguments that come before the name of the
17 # command, e.g. `mach -v build`. We dispatch to the correct Python
18 # interpreter depending on the command.
31 --no-interactive) shift;;
32 --log-interval) shift;;
33 --log-no-times) shift;;
35 --debug-command) shift;;
37 py_profile_command
="1"
52 return ${py_profile_command}
55 command=$
(get_command
"$@")
58 if [ ${py_profile_command} -eq 0 ]
60 py_profile_command_args
=""
62 # We would prefer to use an array variable here, but we're limited to POSIX.
63 # None of our arguments have quoting or spaces so we can safely interpolate
65 py_profile_command_args
="-m cProfile -o mach_profile_${command}.cProfile"
66 echo "Running with --profile-command. To visualize, use snakeviz:"
67 echo "python3 -m pip install snakeviz"
68 echo "python3 -m snakeviz mach_profile_${command}.cProfile"
71 if command -v python3
> /dev
/null
73 exec python3
$py_profile_command_args "$0" "$@"
75 echo "This mach command requires 'python3', which wasn't found on the system!"
80 from __future__ import absolute_import, print_function, unicode_literals
86 def load_mach(dir_path, mach_path):
88 spec = importlib.util.spec_from_file_location('mach_initialize
', mach_path)
89 mach_initialize = importlib.util.module_from_spec(spec)
90 spec.loader.exec_module(mach_initialize)
91 return mach_initialize.initialize(dir_path)
94 def check_and_get_mach(dir_path):
96 # Run Thunderbird's mach_initialize.py
if it exists
97 'comm/build/mach_initialize.py',
98 'build/mach_initialize.py',
99 # test package initialize
100 'tools/mach_initialize.py',
102 for initialize_path
in initialize_paths
:
103 mach_path
= os.path.
join(dir_path
, initialize_path
)
104 if os.path.isfile
(mach_path
):
105 return load_mach
(dir_path
, mach_path
)
110 # XCode python sets __PYVENV_LAUNCHER__, which overrides the executable
111 # used when a python subprocess is created. This is an issue when we want
112 # to run using our virtualenv python executables.
113 # In future Python relases, __PYVENV_LAUNCHER__ will be cleared before
114 # application code (mach) is started.
115 # https://github.com/python/cpython/pull/9516
116 os.environ.pop
("__PYVENV_LAUNCHER__", None
)
118 mach
= check_and_get_mach
(os.path.
dirname(os.path.realpath
(__file__
)))
120 print
('Could not run mach: No mach source directory found.')
122 sys.
exit(mach.run
(args
))
125 if __name__
== '__main__':