Bug 1357238 - Allow apostrophes in try commit messages draft
authorBrian Stack <bstack@mozilla.com>
Thu, 01 Jun 2017 17:49:02 -0700
changeset 587986 f7a5de5c3227f561af937ca34dfbf752cf18bbcd
parent 587980 6ff0dd2d87d1899dfea7abdf5f0dde9b7f28aa45
child 631431 19a6be2be026fa03e427a96ad914607300f8bc84
push id61877
push userbstack@mozilla.com
push dateFri, 02 Jun 2017 00:52:54 +0000
bugs1357238
milestone55.0a1
Bug 1357238 - Allow apostrophes in try commit messages This copies the behavior of mozilla-taskcluster when it submits try pushes. This will allow us to eventually stop using mozilla-taskcluster. MozReview-Commit-ID: J9zC92AE7HZ
taskcluster/taskgraph/test/test_try_option_syntax.py
taskcluster/taskgraph/try_option_syntax.py
--- a/taskcluster/taskgraph/test/test_try_option_syntax.py
+++ b/taskcluster/taskgraph/test/test_try_option_syntax.py
@@ -95,16 +95,21 @@ class TestTryOptionSyntax(unittest.TestC
 
     def test_unknown_args(self):
         "unknown arguments are ignored"
         tos = TryOptionSyntax('try: --doubledash -z extra', graph_with_jobs)
         # equilvant to "try:"..
         self.assertEqual(tos.build_types, [])
         self.assertEqual(tos.jobs, None)
 
+    def test_apostrophe_in_message(self):
+        "apostrophe does not break parsing"
+        tos = TryOptionSyntax('Increase spammy log\'s log level. try: -b do', graph_with_jobs)
+        self.assertEqual(sorted(tos.build_types), ['debug', 'opt'])
+
     def test_b_do(self):
         "-b do should produce both build_types"
         tos = TryOptionSyntax('try: -b do', graph_with_jobs)
         self.assertEqual(sorted(tos.build_types), ['debug', 'opt'])
 
     def test_b_d(self):
         "-b d should produce build_types=['debug']"
         tos = TryOptionSyntax('try: -b d', graph_with_jobs)
--- a/taskcluster/taskgraph/try_option_syntax.py
+++ b/taskcluster/taskgraph/try_option_syntax.py
@@ -189,30 +189,28 @@ def escape_whitespace_in_brackets(input_
             result += '\ '
             continue
 
         result += char
 
     return result
 
 
-def find_try_idx(message):
+def split_try_msg(message):
+    try:
+        try_idx = message.index('try:')
+    except ValueError:
+        return []
+    message = message[try_idx:].split('\n')[0]
     # shlex used to ensure we split correctly when giving values to argparse.
-    parts = shlex.split(escape_whitespace_in_brackets(message))
-    try_idx = None
-    for idx, part in enumerate(parts):
-        if part == TRY_DELIMITER:
-            try_idx = idx
-            break
-
-    return try_idx, parts
+    return shlex.split(escape_whitespace_in_brackets(message))
 
 
 def parse_message(message):
-    try_idx, parts = find_try_idx(message)
+    parts = split_try_msg(message)
 
     # Argument parser based on try flag flags
     parser = argparse.ArgumentParser()
     parser.add_argument('-b', '--build', dest='build_types')
     parser.add_argument('-p', '--platform', nargs='?',
                         dest='platforms', const='all', default='all')
     parser.add_argument('-u', '--unittests', nargs='?',
                         dest='unittests', const='all', default='all')
@@ -235,17 +233,16 @@ def parse_message(message):
     # While we are transitioning from BB to TC, we want to push jobs to tc-worker
     # machines but not overload machines with every try push. Therefore, we add
     # this temporary option to be able to push jobs to tc-worker.
     parser.add_argument('-w', '--taskcluster-worker',
                         dest='taskcluster_worker', action='store_true', default=False)
 
     # In order to run test jobs multiple times
     parser.add_argument('--rebuild', dest='trigger_tests', type=int, default=1)
-    parts = parts[try_idx:] if try_idx is not None else []
     args, _ = parser.parse_known_args(parts)
     return args
 
 
 class TryOptionSyntax(object):
 
     def __init__(self, message, full_task_graph):
         """
@@ -285,18 +282,18 @@ class TryOptionSyntax(object):
         self.interactive = False
         self.notifications = None
         self.talos_trigger_tests = 0
         self.env = []
         self.profile = False
         self.tag = None
         self.no_retry = False
 
-        try_idx, _ = find_try_idx(message)
-        if try_idx is None:
+        parts = split_try_msg(message)
+        if not parts:
             return None
 
         args = parse_message(message)
         assert args is not None
 
         self.jobs = self.parse_jobs(args.jobs)
         self.build_types = self.parse_build_types(args.build_types, full_task_graph)
         self.platforms = self.parse_platforms(args.platforms, full_task_graph)