Bug 1400469 - Add ability to specify commit message to |mach try|, r?armenzg
MozReview-Commit-ID: LWkAEDWn8NC
--- a/tools/tryselect/cli.py
+++ b/tools/tryselect/cli.py
@@ -1,22 +1,32 @@
# 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/.
from __future__ import absolute_import, print_function, unicode_literals
+import os
+import subprocess
+import tempfile
from argparse import ArgumentParser
from .templates import all_templates
class BaseTryParser(ArgumentParser):
name = 'try'
common_arguments = [
+ [['-m', '--message'],
+ {'const': 'editor',
+ 'default': '{msg}',
+ 'nargs': '?',
+ 'help': 'Use the specified commit message, or create it in your '
+ '$EDITOR if blank. Defaults to computed message.',
+ }],
[['--no-push'],
{'dest': 'push',
'action': 'store_false',
'help': 'Do not push to try as a result of running this command (if '
'specified this command will only print calculated try '
'syntax and selection info).',
}],
[['--save'],
@@ -47,18 +57,31 @@ class BaseTryParser(ArgumentParser):
for cli, kwargs in self.common_arguments:
group.add_argument(*cli, **kwargs)
group = self.add_argument_group("template arguments")
self.templates = {t: all_templates[t]() for t in self.templates}
for template in self.templates.values():
template.add_arguments(group)
+ def validate(self, args):
+ if args.message == 'editor':
+ if 'EDITOR' not in os.environ:
+ self.error("must set the $EDITOR environment variable to use blank --message")
+
+ with tempfile.NamedTemporaryFile(mode='r') as fh:
+ subprocess.call([os.environ['EDITOR'], fh.name])
+ args.message = fh.read().strip()
+
+ if '{msg}' not in args.message:
+ args.message = '{}\n\n{}'.format(args.message, '{msg}')
+
def parse_known_args(self, *args, **kwargs):
args, remainder = ArgumentParser.parse_known_args(self, *args, **kwargs)
+ self.validate(args)
if self.templates:
args.templates = {}
for name, cls in self.templates.iteritems():
context = cls.context(**vars(args))
if context is not None:
args.templates[name] = context
--- a/tools/tryselect/selectors/fuzzy.py
+++ b/tools/tryselect/selectors/fuzzy.py
@@ -193,17 +193,18 @@ def format_header():
shortcuts = []
for action, key in sorted(fzf_header_shortcuts.iteritems()):
shortcuts.append('{t.white}{action}{t.normal}: {t.yellow}<{key}>{t.normal}'.format(
t=terminal, action=action, key=key))
return FZF_HEADER.format(shortcuts=', '.join(shortcuts), t=terminal)
def run_fuzzy_try(update=False, query=None, templates=None, full=False, parameters=None,
- save=False, preset=None, list_presets=False, push=True, **kwargs):
+ save=False, preset=None, list_presets=False, push=True, message='{msg}',
+ **kwargs):
if list_presets:
return pset.list_presets(section='fuzzy')
fzf = fzf_bootstrap(update)
if not fzf:
print(FZF_NOT_FOUND)
return
@@ -243,9 +244,9 @@ def run_fuzzy_try(update=False, query=No
print("no tasks selected")
return
if save:
pset.save('fuzzy', save, query)
query = " with query: {}".format(query) if query else ""
msg = "Fuzzy{}".format(query)
- return vcs.push_to_try('fuzzy', msg, selected, templates, push=push)
+ return vcs.push_to_try('fuzzy', message.format(msg=msg), selected, templates, push=push)
--- a/tools/tryselect/selectors/syntax.py
+++ b/tools/tryselect/selectors/syntax.py
@@ -633,14 +633,14 @@ class AutoTry(object):
if kwargs["verbose"] and paths_by_flavor:
print('The following tests will be selected: ')
for flavor, paths in paths_by_flavor.iteritems():
print("%s: %s" % (flavor, ",".join(paths)))
if kwargs["verbose"]:
print('The following try syntax was calculated:\n%s' % msg)
- self.vcs.push_to_try('syntax', msg, push=kwargs['push'])
+ self.vcs.push_to_try('syntax', kwargs["message"].format(msg=msg), push=kwargs['push'])
if kwargs["save"]:
assert msg.startswith("try: ")
msg = msg[len("try: "):]
preset.save('try', kwargs["save"], msg)
--- a/tools/tryselect/test/cram.ini
+++ b/tools/tryselect/test/cram.ini
@@ -1,2 +1,3 @@
[test_fuzzy.t]
+[test_message.t]
[test_preset.t]
--- a/tools/tryselect/test/setup.sh
+++ b/tools/tryselect/test/setup.sh
@@ -1,11 +1,17 @@
export topsrcdir=$TESTDIR/../../../
export MOZBUILD_STATE_PATH=$TMP/mozbuild
+export MACHRC=$TMP/machrc
+cat > $MACHRC << EOF
+[try]
+default=syntax
+EOF
+
cachedir=$MOZBUILD_STATE_PATH/cache/taskgraph
mkdir -p $cachedir
cat > $cachedir/target_task_set << EOF
test/foo-opt
test/foo-debug
build-baz
EOF
--- a/tools/tryselect/test/test_fuzzy.t
+++ b/tools/tryselect/test/test_fuzzy.t
@@ -1,73 +1,73 @@
$ . $TESTDIR/setup.sh
$ cd $topsrcdir
Test fuzzy selector
$ ./mach try fuzzy $testargs -q "'foo"
- Calculated try selector:
+ Commit message:
+ Fuzzy with query: 'foo
+
+ Pushed via `mach try fuzzy`
+ Calculated try_task_config.json:
{
"tasks":[
"test/foo-debug",
"test/foo-opt"
]
}
- Commit message:
- Fuzzy with query: 'foo
-
- Pushed via `mach try fuzzy`
$ ./mach try fuzzy $testargs -q "'bar"
no tasks selected
$ ./mach try fuzzy $testargs --full -q "'bar"
- Calculated try selector:
+ Commit message:
+ Fuzzy with query: 'bar
+
+ Pushed via `mach try fuzzy`
+ Calculated try_task_config.json:
{
"tasks":[
"test/bar-debug",
"test/bar-opt"
]
}
- Commit message:
- Fuzzy with query: 'bar
-
- Pushed via `mach try fuzzy`
Test templates
$ ./mach try fuzzy --no-push --artifact -q "'foo"
- Calculated try selector:
+ Commit message:
+ Fuzzy with query: 'foo
+
+ Pushed via `mach try fuzzy`
+ Calculated try_task_config.json:
{
"templates":{
"artifact":{
"enabled":"1"
}
},
"tasks":[
"test/foo-debug",
"test/foo-opt"
]
}
+ $ ./mach try fuzzy $testargs --env FOO=1 --env BAR=baz -q "'foo"
Commit message:
Fuzzy with query: 'foo
Pushed via `mach try fuzzy`
- $ ./mach try fuzzy $testargs --env FOO=1 --env BAR=baz -q "'foo"
- Calculated try selector:
+ Calculated try_task_config.json:
{
"templates":{
"env":{
"FOO":"1",
"BAR":"baz"
}
},
"tasks":[
"test/foo-debug",
"test/foo-opt"
]
}
- Commit message:
- Fuzzy with query: 'foo
-
- Pushed via `mach try fuzzy`
new file mode 100644
--- /dev/null
+++ b/tools/tryselect/test/test_message.t
@@ -0,0 +1,55 @@
+ $ . $TESTDIR/setup.sh
+ $ cd $topsrcdir
+
+Test custom commit messages with fuzzy selector
+
+ $ ./mach try fuzzy $testargs -q foo --message "Foobar"
+ Commit message:
+ Foobar
+
+ Fuzzy with query: foo
+
+ Pushed via `mach try fuzzy`
+ Calculated try_task_config.json:
+ {
+ "tasks":[
+ "test/foo-debug",
+ "test/foo-opt"
+ ]
+ }
+
+ $ ./mach try fuzzy $testargs -q foo -m "Foobar: {msg}"
+ Commit message:
+ Foobar: Fuzzy with query: foo
+
+ Pushed via `mach try fuzzy`
+ Calculated try_task_config.json:
+ {
+ "tasks":[
+ "test/foo-debug",
+ "test/foo-opt"
+ ]
+ }
+
+ $ unset EDITOR
+ $ ./mach try fuzzy $testargs -q foo -m > /dev/null 2>&1
+ [2]
+
+
+Test custom commit messages with syntax selector
+
+ $ ./mach try syntax $testargs -p linux -u mochitests --message "Foobar"
+ Commit message:
+ Foobar
+
+ try: -b do -p linux -u mochitests
+
+ Pushed via `mach try syntax`
+ $ ./mach try syntax $testargs -p linux -u mochitests -m "Foobar: {msg}"
+ Commit message:
+ Foobar: try: -b do -p linux -u mochitests
+
+ Pushed via `mach try syntax`
+ $ unset EDITOR
+ $ ./mach try syntax $testargs -p linux -u mochitests -m > /dev/null 2>&1
+ [2]
--- a/tools/tryselect/test/test_preset.t
+++ b/tools/tryselect/test/test_preset.t
@@ -1,99 +1,87 @@
$ . $TESTDIR/setup.sh
$ cd $topsrcdir
Test preset with no subcommand
$ ./mach try $testargs --save foo -b do -p linux -u mochitests -t none --tag foo
- Calculated try selector:
- try: -b do -p linux -u mochitests -t none --tag foo
Commit message:
try: -b do -p linux -u mochitests -t none --tag foo
Pushed via `mach try syntax`
preset saved, run with: --preset=foo
$ ./mach try $testargs --preset foo
- Calculated try selector:
- try: -b do -p linux -u mochitests -t none --tag foo
Commit message:
try: -b do -p linux -u mochitests -t none --tag foo
Pushed via `mach try syntax`
$ ./mach try syntax $testargs --preset foo
- Calculated try selector:
- try: -b do -p linux -u mochitests -t none --tag foo
Commit message:
try: -b do -p linux -u mochitests -t none --tag foo
Pushed via `mach try syntax`
$ ./mach try $testargs --list-presets
foo: -b do -p linux -u mochitests -t none --tag foo
Test preset with syntax subcommand
$ ./mach try syntax $testargs --save bar -b do -p win32 -u none -t all --tag bar
- Calculated try selector:
- try: -b do -p win32 -u none -t all --tag bar
Commit message:
try: -b do -p win32 -u none -t all --tag bar
Pushed via `mach try syntax`
preset saved, run with: --preset=bar
$ ./mach try syntax $testargs --preset bar
- Calculated try selector:
- try: -b do -p win32 -u none -t all --tag bar
Commit message:
try: -b do -p win32 -u none -t all --tag bar
Pushed via `mach try syntax`
$ ./mach try $testargs --preset bar
- Calculated try selector:
- try: -b do -p win32 -u none -t all --tag bar
Commit message:
try: -b do -p win32 -u none -t all --tag bar
Pushed via `mach try syntax`
$ ./mach try syntax $testargs --list-presets
foo: -b do -p linux -u mochitests -t none --tag foo
bar: -b do -p win32 -u none -t all --tag bar
Test preset with fuzzy subcommand
$ ./mach try fuzzy $testargs --save baz -q "'baz"
preset saved, run with: --preset=baz
- Calculated try selector:
- {
- "tasks":[
- "build-baz"
- ]
- }
-
Commit message:
Fuzzy with query: 'baz
Pushed via `mach try fuzzy`
- $ ./mach try fuzzy $testargs --preset baz
- Calculated try selector:
+ Calculated try_task_config.json:
{
"tasks":[
"build-baz"
]
}
+ $ ./mach try fuzzy $testargs --preset baz
Commit message:
Fuzzy with query: 'baz
Pushed via `mach try fuzzy`
- $ ./mach try $testargs --preset baz
- Calculated try selector:
+ Calculated try_task_config.json:
{
"tasks":[
"build-baz"
]
}
+ $ ./mach try $testargs --preset baz
Commit message:
Fuzzy with query: 'baz
Pushed via `mach try fuzzy`
+ Calculated try_task_config.json:
+ {
+ "tasks":[
+ "build-baz"
+ ]
+ }
+
$ ./mach try fuzzy $testargs --list-presets
baz: 'baz
--- a/tools/tryselect/vcs.py
+++ b/tools/tryselect/vcs.py
@@ -103,25 +103,22 @@ class VCSHelper(object):
self.check_working_directory(push)
config = None
if labels:
config = self.write_task_config(labels, templates)
try:
if not push:
- print("Calculated try selector:")
+ print("Commit message:")
+ print(commit_message)
if config:
+ print("Calculated try_task_config.json:")
with open(config) as fh:
print(fh.read())
- else:
- print(msg)
-
- print('Commit message:')
- print(commit_message)
return
self._push_to_try(commit_message, config)
finally:
if config and os.path.isfile(config):
os.remove(config)
@abstractmethod