Browse Source

[gclient] Support per-object GCS condition

llvm-build GCS dependency needs to place one GCS object based on
platform. We can't have multiple top-level GCS llvm-build dependencies
as the pathname is used as a key.

This extends object property of GCS dependency to have `condition`.
The `condition` field will be AND with the top level condition.

R=jojwang@google.com, kimstephanie@google.com

Change-Id: I06a6281140a8057d598a6eac2b07c7577f0ea86c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/5527474
Reviewed-by: Stephanie Kim <kimstephanie@google.com>
Commit-Queue: Josip Sokcevic <sokcevic@chromium.org>
Josip Sokcevic 1 năm trước cách đây
mục cha
commit
96dfd2e757
4 tập tin đã thay đổi với 45 bổ sung8 xóa
  1. 4 1
      gclient.py
  2. 14 5
      gclient_eval.py
  3. 15 2
      gclient_utils.py
  4. 12 0
      tests/gclient_utils_test.py

+ 4 - 1
gclient.py

@@ -780,6 +780,9 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
                                     'dependency.'.format(name))
                 gcs_root = self.GetGcsRoot()
                 for obj in dep_value['objects']:
+                    merged_condition = gclient_utils.merge_conditions(
+                        condition, obj.get('condition'))
+
                     deps_to_add.append(
                         GcsDependency(parent=self,
                                       name=name,
@@ -792,7 +795,7 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
                                       custom_vars=self.custom_vars,
                                       should_process=should_process,
                                       relative=use_relative_paths,
-                                      condition=condition))
+                                      condition=merged_condition))
             else:
                 url = dep_value.get('url')
                 deps_to_add.append(

+ 14 - 5
gclient_eval.py

@@ -137,11 +137,20 @@ _GCLIENT_DEPS_SCHEMA = _NodeDictSchema({
             str,
             'objects': [
                 _NodeDictSchema({
-                    'object_name': str,
-                    'sha256sum': str,
-                    'size_bytes': int,
-                    'generation': int,
-                    schema.Optional('output_file'): str,
+                    'object_name':
+                    str,
+                    'sha256sum':
+                    str,
+                    'size_bytes':
+                    int,
+                    'generation':
+                    int,
+                    schema.Optional('output_file'):
+                    str,
+                    # The object will only be processed if the condition
+                    # evaluates to True. This is AND with the parent condition.
+                    schema.Optional('condition'):
+                    str,
                 })
             ],
             schema.Optional('condition'):

+ 15 - 2
gclient_utils.py

@@ -56,7 +56,7 @@ def reraise(typ, value, tb=None):
 class Error(Exception):
     """gclient exception class."""
     def __init__(self, msg, *args, **kwargs):
-        index = getattr(threading.currentThread(), 'index', 0)
+        index = getattr(threading.current_thread(), 'index', 0)
         if index:
             msg = '\n'.join('%d> %s' % (index, l) for l in msg.splitlines())
         super(Error, self).__init__(msg, *args, **kwargs)
@@ -433,7 +433,7 @@ class Annotated(Wrapper):
         if not isinstance(out, bytes):
             out = out.encode('utf-8')
 
-        index = getattr(threading.currentThread(), 'index', 0)
+        index = getattr(threading.current_thread(), 'index', 0)
         if not index and not self.__include_zero:
             # Unindexed threads aren't buffered.
             return self._wrapped_write(out)
@@ -1386,3 +1386,16 @@ class FrozenDict(collections.abc.Mapping):
 
     def __repr__(self):
         return 'FrozenDict(%r)' % (self._d.items(), )
+
+
+def merge_conditions(*conditions):
+    """combine multiple conditions into one expression"""
+    condition = None
+    for current_condition in conditions:
+        if not current_condition:
+            continue
+        if not condition:
+            condition = current_condition
+            continue
+        condition = f'({condition}) AND ({current_condition})'
+    return condition

+ 12 - 0
tests/gclient_utils_test.py

@@ -401,6 +401,18 @@ class GClientUtilsTest(trial_dir.TestCase):
             self.assertEqual('test', gclient_utils.FileRead(tmp))
         self.assertFalse(os.path.exists(tmp))
 
+    def testMergeConditions(self):
+        self.assertEqual(None, gclient_utils.merge_conditions(None, None))
+
+        self.assertEqual('foo', gclient_utils.merge_conditions('foo', None))
+
+        self.assertEqual('foo', gclient_utils.merge_conditions(None, 'foo'))
+
+        self.assertEqual('(foo) AND (bar)',
+                         gclient_utils.merge_conditions('foo', 'bar'))
+
+        self.assertEqual('(foo or bar) AND (baz)',
+                         gclient_utils.merge_conditions('foo or bar', 'baz'))
 
 if __name__ == '__main__':
     unittest.main()