diff --git a/gclient.py b/gclient.py index ef77cd4b7..f568662ba 100644 --- a/gclient.py +++ b/gclient.py @@ -224,13 +224,14 @@ class Dependency(GClientKeywords, gclient_utils.WorkItem): if isinstance(self.url, self.FromImpl): self.requirements.add(self.url.module_name) - if self.name: + if self.name and self.should_process: def yield_full_tree(root): """Depth-first recursion.""" yield root for i in root.dependencies: for j in yield_full_tree(i): - yield j + if j.should_process: + yield j for obj in yield_full_tree(self.root_parent()): if obj is self or not obj.name: diff --git a/gclient_utils.py b/gclient_utils.py index 350de22e8..d668c5372 100644 --- a/gclient_utils.py +++ b/gclient_utils.py @@ -454,10 +454,11 @@ def GetGClientRootAndEntries(path=None): class WorkItem(object): """One work item.""" - # A list of string, each being a WorkItem name. - requirements = [] - # A unique string representing this work item. - name = None + def __init__(self): + # A list of string, each being a WorkItem name. + self.requirements = [] + # A unique string representing this work item. + self.name = None def run(self, work_queue): """work_queue is passed as keyword argument so it should be @@ -548,7 +549,20 @@ class ExecutionQueue(object): # We're done. break # We need to poll here otherwise Ctrl-C isn't processed. - self.ready_cond.wait(10) + try: + self.ready_cond.wait(10) + except KeyboardInterrupt: + # Help debugging by printing some information: + print >> sys.stderr, ( + ('\nAllowed parallel jobs: %d\n# queued: %d\nRan: %s\n' + 'Running: %d') % ( + self.jobs, + len(self.queued), + ', '.join(self.ran), + len(self.running))) + for i in self.queued: + print >> sys.stderr, '%s: %s' % (i.name, ', '.join(i.requirements)) + raise # Something happened: self.enqueue() or a thread terminated. Loop again. finally: self.ready_cond.release() diff --git a/tests/gclient_test.py b/tests/gclient_test.py index c136dc271..0a5da250f 100755 --- a/tests/gclient_test.py +++ b/tests/gclient_test.py @@ -88,6 +88,8 @@ class GclientTest(trial_dir.TestCase): # fetched until 'src' is done. # jobs is the number of parallel jobs simulated. reverse is to reshuffle the # list to see if it is still processed in order correctly. + # Also test that a From() dependency that should not be processed is listed + # as a requirement. parser = gclient.Parser() options, args = parser.parse_args(['--jobs', jobs]) write( @@ -101,9 +103,11 @@ class GclientTest(trial_dir.TestCase): os.path.join('foo', 'DEPS'), 'deps = {\n' ' "foo/dir1": "/dir1",\n' + # This one will depend on dir1/dir2 in bar. ' "foo/dir1/dir2/dir3": "/dir1/dir2/dir3",\n' - ' "foo/dir1/dir4": "/dir1/dir4",\n' ' "foo/dir1/dir2/dir3/dir4": "/dir1/dir2/dir3/dir4",\n' + ' "foo/dir1/dir2/dir5/dir6":\n' + ' From("foo/dir1/dir2/dir3/dir4", "foo/dir1/dir2"),\n' '}') write( os.path.join('bar', 'DEPS'), @@ -114,6 +118,14 @@ class GclientTest(trial_dir.TestCase): os.path.join('bar/empty', 'DEPS'), 'deps = {\n' '}') + # Test From() + write( + os.path.join('foo/dir1/dir2/dir3/dir4', 'DEPS'), + 'deps = {\n' + # This one should not be fetched or set as a requirement. + ' "foo/dir1/dir2/dir5": "svn://example.com/x",\n' + ' "foo/dir1/dir2": "/dir1/another",\n' + '}') obj = gclient.GClient.LoadCurrentConfig(options) self._check_requirements(obj.dependencies[0], {}) @@ -139,9 +151,10 @@ class GclientTest(trial_dir.TestCase): self.assertEquals( [ 'svn://example.com/foo/dir1', - 'svn://example.com/foo/dir1/dir4', 'svn://example.com/foo/dir1/dir2/dir3', 'svn://example.com/foo/dir1/dir2/dir3/dir4', + # TODO(maruel): This is probably wrong. + 'svn://example.com/foo/dir1/dir2/dir3/dir4/dir1/another', ], actual) self._check_requirements( @@ -151,7 +164,8 @@ class GclientTest(trial_dir.TestCase): 'foo/dir1/dir2/dir3': ['foo', 'foo/dir1', 'foo/dir1/dir2'], 'foo/dir1/dir2/dir3/dir4': ['foo', 'foo/dir1', 'foo/dir1/dir2', 'foo/dir1/dir2/dir3'], - 'foo/dir1/dir4': ['foo', 'foo/dir1'], + 'foo/dir1/dir2/dir5/dir6': + ['foo', 'foo/dir1', 'foo/dir1/dir2', 'foo/dir1/dir2/dir3/dir4'], }) self._check_requirements( obj.dependencies[1],