Bug 1385055 - Add some taskgraph parameters for dealing with comm-central and related repositories. draft
authorTom Prince <mozilla@hocat.ca>
Thu, 27 Jul 2017 12:26:48 -0600
changeset 617038 1df712effa58ad4f676ff17225a0ce5fb63e078d
parent 615176 32d9d1e81cc607320a36391845917f645f7a7f72
child 617039 74c6b50f249260384f0c3515f5a49149e918413a
child 648028 76e7a65e71401cd8405d83edf9820d6897b44bea
push id70893
push userbmo:mozilla@hocat.ca
push dateThu, 27 Jul 2017 18:52:17 +0000
bugs1385055
milestone56.0a1
Bug 1385055 - Add some taskgraph parameters for dealing with comm-central and related repositories. MozReview-Commit-ID: 4tdxfJcx8Fz
taskcluster/docs/parameters.rst
taskcluster/mach_commands.py
taskcluster/taskgraph/decision.py
taskcluster/taskgraph/parameters.py
taskcluster/taskgraph/test/test_parameters.py
--- a/taskcluster/docs/parameters.rst
+++ b/taskcluster/docs/parameters.rst
@@ -97,8 +97,21 @@ syntax or reading a project-specific con
     The method to use to determine the target task set.  This is the suffix of
     one of the functions in ``taskcluster/taskgraph/target_tasks.py``.
 
 ``optimize_target_tasks``
    If true, then target tasks are eligible for optimization.
 
 ``include_nightly``
    If true, then nightly tasks are eligible for optimization.
+
+Comm Push Information
+---------------------
+
+These parameters correspond to the repository and revision of the comm
+repository to checkout. Their meaning is the same as the corresponding
+parameters for the gecko repository above. They are optional, but if any of
+them are specified, they must all be specified.
+
+``comm_base_repository``
+``comm_head_repository``
+``comm_head_rev``
+``comm_head_ref``
--- a/taskcluster/mach_commands.py
+++ b/taskcluster/mach_commands.py
@@ -113,16 +113,28 @@ class MachCommands(MachCommandBase):
                      required=True,
                      help='URL for "head" repository to fetch revision from')
     @CommandArgument('--head-ref',
                      required=True,
                      help='Reference (this is same as rev usually for hg)')
     @CommandArgument('--head-rev',
                      required=True,
                      help='Commit revision to use from head repository')
+    @CommandArgument('--comm-base-repository',
+                     required=False,
+                     help='URL for "base" comm-* repository to clone')
+    @CommandArgument('--comm-head-repository',
+                     required=False,
+                     help='URL for "head" comm-* repository to fetch revision from')
+    @CommandArgument('--comm-head-ref',
+                     required=False,
+                     help='comm-* Reference (this is same as rev usually for hg)')
+    @CommandArgument('--comm-head-rev',
+                     required=False,
+                     help='Commit revision to use from head comm-* repository')
     @CommandArgument('--message',
                      required=True,
                      help='Commit message to be parsed. Example: "try: -b do -p all -u all"')
     @CommandArgument('--project',
                      required=True,
                      help='Project to use for creating task graph. Example: --project=try')
     @CommandArgument('--pushlog-id',
                      dest='pushlog_id',
--- a/taskcluster/taskgraph/decision.py
+++ b/taskcluster/taskgraph/decision.py
@@ -155,16 +155,25 @@ def get_decision_parameters(options):
         'project',
         'pushlog_id',
         'pushdate',
         'owner',
         'level',
         'target_tasks_method',
     ] if n in options}
 
+    for n in (
+        'comm_base_repository',
+        'comm_head_repository',
+        'comm_head_rev',
+        'comm_head_ref',
+    ):
+        if n in options:
+            parameters[n] = options[n]
+
     # Define default filter list, as most configurations shouldn't need
     # custom filters.
     parameters['filters'] = [
         'check_servo',
         'target_tasks_method',
     ]
 
     # owner must be an email, but sometimes (e.g., for ffxbld) it is not, in which
--- a/taskcluster/taskgraph/parameters.py
+++ b/taskcluster/taskgraph/parameters.py
@@ -25,36 +25,51 @@ PARAMETER_NAMES = set([
     'optimize_target_tasks',
     'owner',
     'project',
     'pushdate',
     'pushlog_id',
     'target_tasks_method',
 ])
 
+COMM_PARAMETER_NAMES = set([
+    'comm_base_repository',
+    'comm_head_ref',
+    'comm_head_repository',
+    'comm_head_rev',
+])
+
 
 class Parameters(ReadOnlyDict):
     """An immutable dictionary with nicer KeyError messages on failure"""
     def check(self):
         names = set(self)
         msg = []
 
         missing = PARAMETER_NAMES - names
         if missing:
             msg.append("missing parameters: " + ", ".join(missing))
 
         extra = names - PARAMETER_NAMES
+
+        if extra & COMM_PARAMETER_NAMES:
+            # If any comm_* parameters are specified, ensure all of them are specified.
+            missing = COMM_PARAMETER_NAMES - extra
+            if missing:
+                msg.append("missing parameters: " + ", ".join(missing))
+            extra = extra - COMM_PARAMETER_NAMES
+
         if extra:
             msg.append("extra parameters: " + ", ".join(extra))
 
         if msg:
             raise Exception("; ".join(msg))
 
     def __getitem__(self, k):
-        if k not in PARAMETER_NAMES:
+        if k not in PARAMETER_NAMES | COMM_PARAMETER_NAMES:
             raise KeyError("no such parameter {!r}".format(k))
         try:
             return super(Parameters, self).__getitem__(k)
         except KeyError:
             raise KeyError("taskgraph parameter {!r} not found".format(k))
 
 
 def load_parameters_file(filename):
--- a/taskcluster/taskgraph/test/test_parameters.py
+++ b/taskcluster/taskgraph/test/test_parameters.py
@@ -1,17 +1,19 @@
 # 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 unittest
 
-from taskgraph.parameters import Parameters, load_parameters_file, PARAMETER_NAMES
+from taskgraph.parameters import (
+    Parameters, load_parameters_file, PARAMETER_NAMES, COMM_PARAMETER_NAMES,
+)
 from mozunit import main, MockedOpen
 
 
 class TestParameters(unittest.TestCase):
 
     vals = {n: n for n in PARAMETER_NAMES}
 
     def test_Parameters_immutable(self):
@@ -54,10 +56,38 @@ class TestParameters(unittest.TestCase):
 
     def test_load_parameters_file_json(self):
         with MockedOpen({"params.json": '{"some": "data"}'}):
             self.assertEqual(
                     load_parameters_file('params.json'),
                     {'some': 'data'})
 
 
+class TestCommParameters(unittest.TestCase):
+    vals = {n: n for n in PARAMETER_NAMES | COMM_PARAMETER_NAMES}
+
+    def test_Parameters_check(self):
+        """
+        Specifying all of the gecko and comm parameters doesn't result in an error.
+        """
+        p = Parameters(**self.vals)
+        p.check()  # should not raise
+
+    def test_Parameters_check_missing(self):
+        """
+        If any of the comm parameters are specified, all of them must be specified.
+        """
+        vals = self.vals.copy()
+        del vals[next(iter(COMM_PARAMETER_NAMES))]
+        p = Parameters(**vals)
+        self.assertRaises(Exception, p.check)
+
+    def test_Parameters_check_extra(self):
+        """
+        If parameters other than the global and comm parameters are specified,
+        an error is reported.
+        """
+        p = Parameters(extra="data", **self.vals)
+        self.assertRaises(Exception, p.check)
+
+
 if __name__ == '__main__':
     main()