mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1695272: Move --no-interactive
to global mach args r=firefox-build-system-reviewers,glandium
Updates `./mach bootstrap` to use `--no-interactive` from global args. Ensures all bootstrap prompts have a default option. Differential Revision: https://phabricator.services.mozilla.com/D106814
This commit is contained in:
parent
8133abcb41
commit
b7e0dfe1d1
1
mach
1
mach
@ -62,6 +62,7 @@ get_command() {
|
||||
shift 2
|
||||
fi
|
||||
;;
|
||||
--no-interactive) shift;;
|
||||
--log-interval) shift;;
|
||||
--log-no-times) shift;;
|
||||
-h) shift;;
|
||||
|
@ -55,7 +55,7 @@ argument to automatically accept any license agreements.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
./mach bootstrap [ --no-interactive]
|
||||
./mach [--no-interactive] bootstrap
|
||||
|
||||
- Choose option \`4. Firefox for Android\` for GeckoView development.
|
||||
This will give you a version of Gecko configured for Android that has
|
||||
|
@ -23,6 +23,7 @@ class CommandContext(object):
|
||||
self.settings = settings
|
||||
self.log_manager = log_manager
|
||||
self.commands = commands
|
||||
self.is_interactive = None # Filled in after args are parsed
|
||||
self.telemetry = telemetry
|
||||
self.command_attrs = {}
|
||||
|
||||
|
@ -447,6 +447,12 @@ To see more help for a specific command, run:
|
||||
if not hasattr(args, "mach_handler"):
|
||||
raise MachError("ArgumentParser result missing mach handler info.")
|
||||
|
||||
context.is_interactive = (
|
||||
args.is_interactive
|
||||
and sys.__stdout__.isatty()
|
||||
and sys.__stderr__.isatty()
|
||||
and not os.environ.get("MOZ_AUTOMATION", None)
|
||||
)
|
||||
handler = getattr(args, "mach_handler")
|
||||
report_invocation_metrics(context.telemetry, handler.name)
|
||||
|
||||
@ -643,6 +649,14 @@ To see more help for a specific command, run:
|
||||
"than relative time. Note that this is NOT execution time "
|
||||
"if there are parallel operations.",
|
||||
)
|
||||
global_group.add_argument(
|
||||
"--no-interactive",
|
||||
dest="is_interactive",
|
||||
action="store_false",
|
||||
help="Automatically selects the default option on any "
|
||||
"interactive prompts. If the output is not a terminal, "
|
||||
"then --no-interactive is assumed.",
|
||||
)
|
||||
suppress_log_by_default = False
|
||||
if "INSIDE_EMACS" in os.environ:
|
||||
suppress_log_by_default = True
|
||||
|
@ -285,13 +285,20 @@ def clone(vcs, no_interactive):
|
||||
|
||||
|
||||
def bootstrap(srcdir, application_choice, no_interactive, no_system_changes):
|
||||
args = [sys.executable, os.path.join(srcdir, "mach"), "bootstrap"]
|
||||
args = [sys.executable, os.path.join(srcdir, "mach")]
|
||||
|
||||
if no_interactive:
|
||||
# --no-interactive is a global argument, not a command argument,
|
||||
# so it needs to be specified before "bootstrap" is appended.
|
||||
args += ["--no-interactive"]
|
||||
|
||||
args += ["bootstrap"]
|
||||
|
||||
if application_choice:
|
||||
args += ["--application-choice", application_choice]
|
||||
if no_interactive:
|
||||
args += ["--no-interactive"]
|
||||
if no_system_changes:
|
||||
args += ["--no-system-changes"]
|
||||
|
||||
print("Running `%s`" % " ".join(args))
|
||||
return subprocess.call(args, cwd=srcdir)
|
||||
|
||||
|
@ -466,11 +466,30 @@ class BaseBootstrapper(object):
|
||||
|
||||
self.run_as_root(command)
|
||||
|
||||
def prompt_int(self, prompt, low, high):
|
||||
""" Prompts the user with prompt and requires an integer between low and high. """
|
||||
def prompt_int(self, prompt, low, high, default=None):
|
||||
"""Prompts the user with prompt and requires an integer between low and high.
|
||||
|
||||
If the user doesn't select an option and a default isn't provided, then
|
||||
the lowest option is used. This is because some option must be implicitly
|
||||
selected if mach is invoked with "--no-interactive"
|
||||
"""
|
||||
if default is not None:
|
||||
assert isinstance(default, int)
|
||||
assert low <= default <= high
|
||||
else:
|
||||
default = low
|
||||
|
||||
if self.no_interactive:
|
||||
print(prompt)
|
||||
print('Selecting "{}" because context is not interactive.'.format(default))
|
||||
return default
|
||||
|
||||
while True:
|
||||
choice = input(prompt)
|
||||
if choice == "" and default is not None:
|
||||
return default
|
||||
try:
|
||||
choice = int(input(prompt))
|
||||
choice = int(choice)
|
||||
if low <= choice <= high:
|
||||
return choice
|
||||
except ValueError:
|
||||
@ -479,18 +498,20 @@ class BaseBootstrapper(object):
|
||||
|
||||
def prompt_yesno(self, prompt):
|
||||
""" Prompts the user with prompt and requires a yes/no answer."""
|
||||
valid = False
|
||||
while not valid:
|
||||
if self.no_interactive:
|
||||
print(prompt)
|
||||
print('Selecting "Y" because context is not interactive.')
|
||||
return True
|
||||
|
||||
while True:
|
||||
choice = input(prompt + " (Yn): ").strip().lower()[:1]
|
||||
if choice == "":
|
||||
choice = "y"
|
||||
if choice not in ("y", "n"):
|
||||
print("ERROR! Please enter y or n!")
|
||||
else:
|
||||
valid = True
|
||||
|
||||
return True
|
||||
elif choice in ("y", "n"):
|
||||
return choice == "y"
|
||||
|
||||
print("ERROR! Please enter y or n!")
|
||||
|
||||
def _ensure_package_manager_updated(self):
|
||||
if self.package_manager_updated:
|
||||
return
|
||||
|
@ -365,11 +365,13 @@ class Bootstrapper(object):
|
||||
labels = [
|
||||
"%s. %s" % (i, name) for i, name in enumerate(APPLICATIONS.keys(), 1)
|
||||
]
|
||||
prompt = APPLICATION_CHOICE % "\n".join(
|
||||
" {}".format(label) for label in labels
|
||||
)
|
||||
choices = [" {} [default]".format(labels[0])]
|
||||
choices += [" {}".format(label) for label in labels[1:]]
|
||||
prompt = APPLICATION_CHOICE % "\n".join(choices)
|
||||
prompt_choice = self.instance.prompt_int(
|
||||
prompt=prompt, low=1, high=len(APPLICATIONS)
|
||||
prompt=prompt,
|
||||
low=1,
|
||||
high=len(APPLICATIONS),
|
||||
)
|
||||
name, application = list(APPLICATIONS.items())[prompt_choice - 1]
|
||||
elif self.choice in APPLICATIONS.keys():
|
||||
@ -428,7 +430,6 @@ class Bootstrapper(object):
|
||||
# Possibly configure Mercurial, but not if the current checkout or repo
|
||||
# type is Git.
|
||||
if hg_installed and checkout_type == "hg":
|
||||
configure_hg = False
|
||||
if not self.instance.no_interactive:
|
||||
configure_hg = self.instance.prompt_yesno(prompt=CONFIGURE_MERCURIAL)
|
||||
else:
|
||||
|
@ -20,7 +20,7 @@ Mercurial via the "pip" Python packaging utility. This will likely result
|
||||
in files being placed in /usr/local/bin and /usr/local/lib.
|
||||
|
||||
How would you like to continue?
|
||||
1. Install a modern Mercurial via pip (recommended)
|
||||
1. Install a modern Mercurial via pip [default]
|
||||
2. Install a legacy Mercurial via apt
|
||||
3. Do not install Mercurial
|
||||
Your choice: """
|
||||
|
@ -32,26 +32,18 @@ class Bootstrap(MachCommandBase):
|
||||
help="Pass in an application choice instead of using the default "
|
||||
"interactive prompt.",
|
||||
)
|
||||
@CommandArgument(
|
||||
"--no-interactive",
|
||||
dest="no_interactive",
|
||||
action="store_true",
|
||||
help="Answer yes to any (Y/n) interactive prompts.",
|
||||
)
|
||||
@CommandArgument(
|
||||
"--no-system-changes",
|
||||
dest="no_system_changes",
|
||||
action="store_true",
|
||||
help="Only execute actions that leave the system " "configuration alone.",
|
||||
)
|
||||
def bootstrap(
|
||||
self, application_choice=None, no_interactive=False, no_system_changes=False
|
||||
):
|
||||
def bootstrap(self, application_choice=None, no_system_changes=False):
|
||||
from mozboot.bootstrap import Bootstrapper
|
||||
|
||||
bootstrapper = Bootstrapper(
|
||||
choice=application_choice,
|
||||
no_interactive=no_interactive,
|
||||
no_interactive=not self._mach_context.is_interactive,
|
||||
no_system_changes=no_system_changes,
|
||||
mach_context=self._mach_context,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user