diff --git a/gclient_scm.py b/gclient_scm.py index e2a0bdd65..95890a450 100644 --- a/gclient_scm.py +++ b/gclient_scm.py @@ -494,7 +494,7 @@ class GitWrapper(SCMWrapper): # to stdout print('') - clone_cmd = ['clone'] + clone_cmd = ['clone', '--progress'] if revision.startswith('refs/heads/'): clone_cmd.extend(['-b', revision.replace('refs/heads/', '')]) detach_head = False @@ -510,9 +510,20 @@ class GitWrapper(SCMWrapper): if not os.path.exists(parent_dir): os.makedirs(parent_dir) + percent_re = re.compile('.* ([0-9]{1,2})% .*') + def _GitFilter(line): + # git uses an escape sequence to clear the line; elide it. + esc = line.find(unichr(033)) + if esc > -1: + line = line[:esc] + match = percent_re.match(line) + if not match or not int(match.group(1)) % 10: + print '%s' % line + for _ in range(3): try: - self._Run(clone_cmd, options, cwd=self._root_dir) + self._Run(clone_cmd, options, cwd=self._root_dir, filter_fn=_GitFilter, + print_stdout=False) break except subprocess2.CalledProcessError, e: # Too bad we don't have access to the actual output yet. @@ -679,8 +690,11 @@ class GitWrapper(SCMWrapper): def _Run(self, args, options, **kwargs): kwargs.setdefault('cwd', self.checkout_path) - gclient_utils.CheckCallAndFilterAndHeader(['git'] + args, - always=options.verbose, **kwargs) + kwargs.setdefault('print_stdout', True) + stdout = kwargs.get('stdout', sys.stdout) + stdout.write('\n________ running \'git %s\' in \'%s\'\n' % ( + ' '.join(args), kwargs['cwd'])) + gclient_utils.CheckCallAndFilter(['git'] + args, **kwargs) class SVNWrapper(SCMWrapper): diff --git a/gclient_utils.py b/gclient_utils.py index 375dd576f..958034dfc 100644 --- a/gclient_utils.py +++ b/gclient_utils.py @@ -360,6 +360,9 @@ def CheckCallAndFilter(args, stdout=None, filter_fn=None, else: filter_fn(in_line) in_line = '' + else: + filter_fn(in_line) + in_line = '' in_byte = kid.stdout.read(1) # Flush the rest of buffered output. This is only an issue with # stdout/stderr not ending with a \n. diff --git a/tests/gclient_scm_test.py b/tests/gclient_scm_test.py index 21da096cf..6d5e380c0 100755 --- a/tests/gclient_scm_test.py +++ b/tests/gclient_scm_test.py @@ -571,13 +571,13 @@ class ManagedGitWrapperTestCase(BaseGitWrapperTestCase): file_list = [] scm.diff(options, self.args, file_list) self.assertEquals(file_list, []) - self.checkstdout( - ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n' + expectation = ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n' 'Fast-forward\n a | 1 +\n b | 1 +\n' ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n' '________ running \'git reset --hard origin/master\' in \'%s\'\n' - 'HEAD is now at a7142dc Personalized\n') % - join(self.root_dir, '.')) + 'HEAD is now at a7142dc Personalized\n') % join(self.root_dir, '.') + self.assertTrue(sys.stdout.getvalue().startswith(expectation)) + sys.stdout.close() def testRevertNone(self): if not self.enabled: @@ -618,13 +618,13 @@ class ManagedGitWrapperTestCase(BaseGitWrapperTestCase): self.assertEquals(file_list, []) self.assertEquals(scm.revinfo(options, self.args, None), 'a7142dc9f0009350b96a11f372b6ea658592aa95') - self.checkstdout( - ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n' + expectation = ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n' 'Fast-forward\n a | 1 +\n b | 1 +\n' ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n' '________ running \'git reset --hard origin/master\' in \'%s\'\n' - 'HEAD is now at a7142dc Personalized\n') % - join(self.root_dir, '.')) + 'HEAD is now at a7142dc Personalized\n') % join(self.root_dir, '.') + self.assertTrue(sys.stdout.getvalue().startswith(expectation)) + sys.stdout.close() def testRevertNew(self): if not self.enabled: @@ -648,13 +648,13 @@ class ManagedGitWrapperTestCase(BaseGitWrapperTestCase): self.assertEquals(file_list, []) self.assertEquals(scm.revinfo(options, self.args, None), 'a7142dc9f0009350b96a11f372b6ea658592aa95') - self.checkstdout( - ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n' + expectation = ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n' 'Fast-forward\n a | 1 +\n b | 1 +\n' ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n' '________ running \'git reset --hard origin/master\' in \'%s\'\n' - 'HEAD is now at a7142dc Personalized\n') % - join(self.root_dir, '.')) + 'HEAD is now at a7142dc Personalized\n') % join(self.root_dir, '.') + self.assertTrue(sys.stdout.getvalue().startswith(expectation)) + sys.stdout.close() def testStatusNew(self): if not self.enabled: @@ -713,7 +713,8 @@ class ManagedGitWrapperTestCase(BaseGitWrapperTestCase): rmtree(root_dir) msg1 = ( "\n_____ foo at refs/heads/master\n\n" - "________ running 'git clone -b master --verbose %s %s' in '%s'\n" + "________ running 'git clone --progress -b master --verbose %s %s' " + "in '%s'\n" "Initialized empty Git repository in %s\n") % ( join(self.root_dir, '.', '.git'), join(root_dir, 'foo'), @@ -721,7 +722,8 @@ class ManagedGitWrapperTestCase(BaseGitWrapperTestCase): join(gclient_scm.os.path.realpath(root_dir), 'foo', '.git') + '/') msg2 = ( "\n_____ foo at refs/heads/master\n\n" - "________ running 'git clone -b master --verbose %s %s' in '%s'\n" + "________ running 'git clone --progress -b master --verbose %s %s'" + " in '%s'\n" "Cloning into %s...\ndone.\n") % ( join(self.root_dir, '.', '.git'), join(root_dir, 'foo'), @@ -848,7 +850,8 @@ class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase): rmtree(root_dir) msg1 = ( "\n_____ foo at refs/heads/master\n\n" - "________ running 'git clone -b master --verbose %s %s' in '%s'\n" + "________ running 'git clone --progress -b master --verbose %s %s'" + " in '%s'\n" "Initialized empty Git repository in %s\n") % ( join(self.root_dir, '.', '.git'), join(root_dir, 'foo'), @@ -856,7 +859,8 @@ class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase): join(gclient_scm.os.path.realpath(root_dir), 'foo', '.git') + '/') msg2 = ( "\n_____ foo at refs/heads/master\n\n" - "________ running 'git clone -b master --verbose %s %s' in '%s'\n" + "________ running 'git clone --progress -b master --verbose %s %s'" + " in '%s'\n" "Cloning into %s...\ndone.\n") % ( join(self.root_dir, '.', '.git'), join(root_dir, 'foo'), diff --git a/tests/gclient_smoketest.py b/tests/gclient_smoketest.py index 473a5116c..b8673236b 100755 --- a/tests/gclient_smoketest.py +++ b/tests/gclient_smoketest.py @@ -808,10 +808,11 @@ class GClientSmokeGIT(GClientSmokeBase): os.remove(join(self.root_dir, 'src', 'git_hooked1')) # Test incremental versioned sync: sync backward. + diffdir = os.path.join(self.root_dir, 'src', 'repo2', 'repo_renamed') self.parseGclient(['sync', '--jobs', '1', '--revision', 'src@' + self.githash('repo_1', 1), '--deps', 'mac', '--delete_unversioned_trees'], - ['running', 'running', 'deleting']) + ['running', 'running', ('running', diffdir), 'deleting']) tree = self.mangle_git_tree(('repo_1@1', 'src'), ('repo_2@2', 'src/repo2'), ('repo_3@1', 'src/repo2/repo3'), @@ -819,8 +820,10 @@ class GClientSmokeGIT(GClientSmokeBase): tree['src/git_hooked2'] = 'git_hooked2' self.assertTree(tree) # Test incremental sync: delete-unversioned_trees isn't there. + expect3 = ('running', os.path.join(self.root_dir, 'src', 'repo2', 'repo3')) + expect4 = ('running', os.path.join(self.root_dir, 'src', 'repo4')) self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'], - ['running', 'running', 'running']) + ['running', 'running', 'running', expect3, expect4]) tree = self.mangle_git_tree(('repo_1@2', 'src'), ('repo_2@1', 'src/repo2'), ('repo_3@1', 'src/repo2/repo3'), @@ -885,10 +888,12 @@ class GClientSmokeGIT(GClientSmokeBase): os.remove(join(self.root_dir, 'src', 'git_hooked1')) # Test incremental versioned sync: sync backward. + expect3 = ('running', + os.path.join(self.root_dir, 'src', 'repo2', 'repo_renamed')) self.parseGclient( ['sync', '--revision', 'src@' + self.githash('repo_1', 1), '--deps', 'mac', '--delete_unversioned_trees', '--jobs', '8'], - ['running', 'running', 'deleting'], + ['running', 'running', expect3, 'deleting'], untangle=True) tree = self.mangle_git_tree(('repo_1@1', 'src'), ('repo_2@2', 'src/repo2'), @@ -897,8 +902,13 @@ class GClientSmokeGIT(GClientSmokeBase): tree['src/git_hooked2'] = 'git_hooked2' self.assertTree(tree) # Test incremental sync: delete-unversioned_trees isn't there. + expect4 = os.path.join(self.root_dir, 'src', 'repo2', 'repo3') + expect5 = os.path.join(self.root_dir, 'src', 'repo4') self.parseGclient(['sync', '--deps', 'mac', '--jobs', '8'], - ['running', 'running', 'running'], untangle=True) + ['running', 'running', 'running', + ('running', expect4), + ('running', expect5)], + untangle=True) tree = self.mangle_git_tree(('repo_1@2', 'src'), ('repo_2@1', 'src/repo2'), ('repo_3@1', 'src/repo2/repo3'), @@ -917,10 +927,14 @@ class GClientSmokeGIT(GClientSmokeBase): self.gclient(['sync', '--deps', 'mac']) write(join(self.root_dir, 'src', 'repo2', 'hi'), 'Hey!') - out = self.parseGclient(['status', '--deps', 'mac'], []) + expected1 = ('running', os.path.join(self.root_dir, 'src')) + expected2 = ('running', os.path.join(expected1[1], 'repo2')) + expected3 = ('running', os.path.join(expected2[1], 'repo_renamed')) + out = self.parseGclient(['status', '--deps', 'mac'], + [expected1, expected2, expected3]) # TODO(maruel): http://crosbug.com/3584 It should output the unversioned # files. - self.assertEquals(0, len(out)) + self.assertEquals(3, len(out)) # Revert implies --force implies running hooks without looking at pattern # matching. @@ -943,7 +957,7 @@ class GClientSmokeGIT(GClientSmokeBase): out = results[0].splitlines(False) # TODO(maruel): http://crosbug.com/3584 It should output the unversioned # files. - self.assertEquals(0, len(out)) + self.assertEquals(6, len(out)) def testRunHooks(self): if not self.enabled: