mirror of
https://gerrit.googlesource.com/git-repo
synced 2025-06-28 20:17:26 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
ddab0604ee | |||
2ae44d7029 | |||
d1e4fa7015 | |||
323b113f55 | |||
8367096d02 | |||
d34af28ac2 | |||
a5b40a2845 |
@ -121,7 +121,7 @@ class Superproject(object):
|
|||||||
print('git fetch missing drectory: %s' % self._work_git,
|
print('git fetch missing drectory: %s' % self._work_git,
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
return False
|
return False
|
||||||
cmd = ['fetch', url, '--force', '--no-tags', '--filter', 'blob:none']
|
cmd = ['fetch', url, '--depth', '1', '--force', '--no-tags', '--filter', 'blob:none']
|
||||||
if self._branch:
|
if self._branch:
|
||||||
cmd += [self._branch + ':' + self._branch]
|
cmd += [self._branch + ':' + self._branch]
|
||||||
p = GitCommand(None,
|
p = GitCommand(None,
|
||||||
|
@ -132,6 +132,18 @@ class EventLog(object):
|
|||||||
exit_event['code'] = result
|
exit_event['code'] = result
|
||||||
self._log.append(exit_event)
|
self._log.append(exit_event)
|
||||||
|
|
||||||
|
def CommandEvent(self, name, subcommands):
|
||||||
|
"""Append a 'command' event to the current log.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: Name of the primary command (ex: repo, git)
|
||||||
|
subcommands: List of the sub-commands (ex: version, init, sync)
|
||||||
|
"""
|
||||||
|
command_event = self._CreateEventDict('command')
|
||||||
|
command_event['name'] = name
|
||||||
|
command_event['subcommands'] = subcommands
|
||||||
|
self._log.append(command_event)
|
||||||
|
|
||||||
def DefParamRepoEvents(self, config):
|
def DefParamRepoEvents(self, config):
|
||||||
"""Append a 'def_param' event for each repo.* config key to the current log.
|
"""Append a 'def_param' event for each repo.* config key to the current log.
|
||||||
|
|
||||||
|
1
main.py
1
main.py
@ -254,6 +254,7 @@ class _Repo(object):
|
|||||||
cmd_event = cmd.event_log.Add(name, event_log.TASK_COMMAND, start)
|
cmd_event = cmd.event_log.Add(name, event_log.TASK_COMMAND, start)
|
||||||
cmd.event_log.SetParent(cmd_event)
|
cmd.event_log.SetParent(cmd_event)
|
||||||
git_trace2_event_log.StartEvent()
|
git_trace2_event_log.StartEvent()
|
||||||
|
git_trace2_event_log.CommandEvent(name='repo', subcommands=[name])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cmd.ValidateOptions(copts, cargs)
|
cmd.ValidateOptions(copts, cargs)
|
||||||
|
@ -24,6 +24,7 @@ import subprocess
|
|||||||
|
|
||||||
from color import Coloring
|
from color import Coloring
|
||||||
from command import DEFAULT_LOCAL_JOBS, Command, MirrorSafeCommand, WORKER_BATCH_SIZE
|
from command import DEFAULT_LOCAL_JOBS, Command, MirrorSafeCommand, WORKER_BATCH_SIZE
|
||||||
|
from error import ManifestInvalidRevisionError
|
||||||
|
|
||||||
_CAN_COLOR = [
|
_CAN_COLOR = [
|
||||||
'branch',
|
'branch',
|
||||||
@ -44,7 +45,7 @@ class Forall(Command, MirrorSafeCommand):
|
|||||||
helpSummary = "Run a shell command in each project"
|
helpSummary = "Run a shell command in each project"
|
||||||
helpUsage = """
|
helpUsage = """
|
||||||
%prog [<project>...] -c <command> [<arg>...]
|
%prog [<project>...] -c <command> [<arg>...]
|
||||||
%prog -r str1 [str2] ... -c <command> [<arg>...]"
|
%prog -r str1 [str2] ... -c <command> [<arg>...]
|
||||||
"""
|
"""
|
||||||
helpDescription = """
|
helpDescription = """
|
||||||
Executes the same shell command in each project.
|
Executes the same shell command in each project.
|
||||||
@ -52,6 +53,11 @@ Executes the same shell command in each project.
|
|||||||
The -r option allows running the command only on projects matching
|
The -r option allows running the command only on projects matching
|
||||||
regex or wildcard expression.
|
regex or wildcard expression.
|
||||||
|
|
||||||
|
By default, projects are processed non-interactively in parallel. If you want
|
||||||
|
to run interactive commands, make sure to pass --interactive to force --jobs 1.
|
||||||
|
While the processing order of projects is not guaranteed, the order of project
|
||||||
|
output is stable.
|
||||||
|
|
||||||
# Output Formatting
|
# Output Formatting
|
||||||
|
|
||||||
The -p option causes '%prog' to bind pipes to the command's stdin,
|
The -p option causes '%prog' to bind pipes to the command's stdin,
|
||||||
@ -154,6 +160,9 @@ without iterating through the remaining projects.
|
|||||||
g.add_option('-v', '--verbose',
|
g.add_option('-v', '--verbose',
|
||||||
dest='verbose', action='store_true',
|
dest='verbose', action='store_true',
|
||||||
help='Show command error messages')
|
help='Show command error messages')
|
||||||
|
p.add_option('--interactive',
|
||||||
|
action='store_true',
|
||||||
|
help='force interactive usage')
|
||||||
|
|
||||||
def WantPager(self, opt):
|
def WantPager(self, opt):
|
||||||
return opt.project_header and opt.jobs == 1
|
return opt.project_header and opt.jobs == 1
|
||||||
@ -173,6 +182,11 @@ without iterating through the remaining projects.
|
|||||||
cmd.append(cmd[0])
|
cmd.append(cmd[0])
|
||||||
cmd.extend(opt.command[1:])
|
cmd.extend(opt.command[1:])
|
||||||
|
|
||||||
|
# Historically, forall operated interactively, and in serial. If the user
|
||||||
|
# has selected 1 job, then default to interacive mode.
|
||||||
|
if opt.jobs == 1:
|
||||||
|
opt.interactive = True
|
||||||
|
|
||||||
if opt.project_header \
|
if opt.project_header \
|
||||||
and not shell \
|
and not shell \
|
||||||
and cmd[0] == 'git':
|
and cmd[0] == 'git':
|
||||||
@ -239,7 +253,7 @@ without iterating through the remaining projects.
|
|||||||
rc = rc or errno.EINTR
|
rc = rc or errno.EINTR
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Catch any other exceptions raised
|
# Catch any other exceptions raised
|
||||||
print('Got an error, terminating the pool: %s: %s' %
|
print('forall: unhandled error, terminating the pool: %s: %s' %
|
||||||
(type(e).__name__, e),
|
(type(e).__name__, e),
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
rc = rc or getattr(e, 'errno', 1)
|
rc = rc or getattr(e, 'errno', 1)
|
||||||
@ -282,7 +296,13 @@ def DoWork(project, mirror, opt, cmd, shell, cnt, config):
|
|||||||
setenv('REPO_PROJECT', project.name)
|
setenv('REPO_PROJECT', project.name)
|
||||||
setenv('REPO_PATH', project.relpath)
|
setenv('REPO_PATH', project.relpath)
|
||||||
setenv('REPO_REMOTE', project.remote.name)
|
setenv('REPO_REMOTE', project.remote.name)
|
||||||
setenv('REPO_LREV', '' if mirror else project.GetRevisionId())
|
try:
|
||||||
|
# If we aren't in a fully synced state and we don't have the ref the manifest
|
||||||
|
# wants, then this will fail. Ignore it for the purposes of this code.
|
||||||
|
lrev = '' if mirror else project.GetRevisionId()
|
||||||
|
except ManifestInvalidRevisionError:
|
||||||
|
lrev = ''
|
||||||
|
setenv('REPO_LREV', lrev)
|
||||||
setenv('REPO_RREV', project.revisionExpr)
|
setenv('REPO_RREV', project.revisionExpr)
|
||||||
setenv('REPO_UPSTREAM', project.upstream)
|
setenv('REPO_UPSTREAM', project.upstream)
|
||||||
setenv('REPO_DEST_BRANCH', project.dest_branch)
|
setenv('REPO_DEST_BRANCH', project.dest_branch)
|
||||||
@ -313,10 +333,12 @@ def DoWork(project, mirror, opt, cmd, shell, cnt, config):
|
|||||||
else:
|
else:
|
||||||
stderr = subprocess.DEVNULL
|
stderr = subprocess.DEVNULL
|
||||||
|
|
||||||
|
stdin = None if opt.interactive else subprocess.DEVNULL
|
||||||
|
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
cmd, cwd=cwd, shell=shell, env=env, check=False,
|
cmd, cwd=cwd, shell=shell, env=env, check=False,
|
||||||
encoding='utf-8', errors='replace',
|
encoding='utf-8', errors='replace',
|
||||||
stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=stderr)
|
stdin=stdin, stdout=subprocess.PIPE, stderr=stderr)
|
||||||
|
|
||||||
output = result.stdout
|
output = result.stdout
|
||||||
if opt.project_header:
|
if opt.project_header:
|
||||||
|
@ -20,7 +20,7 @@ class List(Command, MirrorSafeCommand):
|
|||||||
helpSummary = "List projects and their associated directories"
|
helpSummary = "List projects and their associated directories"
|
||||||
helpUsage = """
|
helpUsage = """
|
||||||
%prog [-f] [<project>...]
|
%prog [-f] [<project>...]
|
||||||
%prog [-f] -r str1 [str2]..."
|
%prog [-f] -r str1 [str2]...
|
||||||
"""
|
"""
|
||||||
helpDescription = """
|
helpDescription = """
|
||||||
List all projects; pass '.' to list the project for the cwd.
|
List all projects; pass '.' to list the project for the cwd.
|
||||||
|
@ -44,7 +44,8 @@ revision specified in the manifest.
|
|||||||
help='begin branch in all projects')
|
help='begin branch in all projects')
|
||||||
p.add_option('-r', '--rev', '--revision', dest='revision',
|
p.add_option('-r', '--rev', '--revision', dest='revision',
|
||||||
help='point branch at this revision instead of upstream')
|
help='point branch at this revision instead of upstream')
|
||||||
p.add_option('--head', dest='revision', action='store_const', const='HEAD',
|
p.add_option('--head', '--HEAD',
|
||||||
|
dest='revision', action='store_const', const='HEAD',
|
||||||
help='abbreviation for --rev HEAD')
|
help='abbreviation for --rev HEAD')
|
||||||
|
|
||||||
def ValidateOptions(self, opt, args):
|
def ValidateOptions(self, opt, args):
|
||||||
|
@ -277,6 +277,16 @@ later is required to fix a server side protocol bug.
|
|||||||
branch = branch[len(R_HEADS):]
|
branch = branch[len(R_HEADS):]
|
||||||
return branch
|
return branch
|
||||||
|
|
||||||
|
def _UseSuperproject(self, opt):
|
||||||
|
"""Returns True if use-superproject option is enabled"""
|
||||||
|
return (opt.use_superproject or
|
||||||
|
self.manifest.manifestProject.config.GetBoolean(
|
||||||
|
'repo.superproject'))
|
||||||
|
|
||||||
|
def _GetCurrentBranchOnly(self, opt):
|
||||||
|
"""Returns True if current-branch or use-superproject options are enabled."""
|
||||||
|
return opt.current_branch_only or self._UseSuperproject(opt)
|
||||||
|
|
||||||
def _UpdateProjectsRevisionId(self, opt, args):
|
def _UpdateProjectsRevisionId(self, opt, args):
|
||||||
"""Update revisionId of every project with the SHA from superproject.
|
"""Update revisionId of every project with the SHA from superproject.
|
||||||
|
|
||||||
@ -363,7 +373,7 @@ later is required to fix a server side protocol bug.
|
|||||||
quiet=opt.quiet,
|
quiet=opt.quiet,
|
||||||
verbose=opt.verbose,
|
verbose=opt.verbose,
|
||||||
output_redir=buf,
|
output_redir=buf,
|
||||||
current_branch_only=opt.current_branch_only,
|
current_branch_only=self._GetCurrentBranchOnly(opt),
|
||||||
force_sync=opt.force_sync,
|
force_sync=opt.force_sync,
|
||||||
clone_bundle=opt.clone_bundle,
|
clone_bundle=opt.clone_bundle,
|
||||||
tags=opt.tags, archive=self.manifest.IsArchive,
|
tags=opt.tags, archive=self.manifest.IsArchive,
|
||||||
@ -735,7 +745,7 @@ later is required to fix a server side protocol bug.
|
|||||||
if not opt.local_only:
|
if not opt.local_only:
|
||||||
start = time.time()
|
start = time.time()
|
||||||
success = mp.Sync_NetworkHalf(quiet=opt.quiet, verbose=opt.verbose,
|
success = mp.Sync_NetworkHalf(quiet=opt.quiet, verbose=opt.verbose,
|
||||||
current_branch_only=opt.current_branch_only,
|
current_branch_only=self._GetCurrentBranchOnly(opt),
|
||||||
force_sync=opt.force_sync,
|
force_sync=opt.force_sync,
|
||||||
tags=opt.tags,
|
tags=opt.tags,
|
||||||
optimized_fetch=opt.optimized_fetch,
|
optimized_fetch=opt.optimized_fetch,
|
||||||
@ -830,9 +840,7 @@ later is required to fix a server side protocol bug.
|
|||||||
else:
|
else:
|
||||||
self._UpdateManifestProject(opt, mp, manifest_name)
|
self._UpdateManifestProject(opt, mp, manifest_name)
|
||||||
|
|
||||||
if (opt.use_superproject or
|
if self._UseSuperproject(opt):
|
||||||
self.manifest.manifestProject.config.GetBoolean(
|
|
||||||
'repo.superproject')):
|
|
||||||
manifest_name = self._UpdateProjectsRevisionId(opt, args)
|
manifest_name = self._UpdateProjectsRevisionId(opt, args)
|
||||||
|
|
||||||
if self.gitc_manifest:
|
if self.gitc_manifest:
|
||||||
|
@ -161,6 +161,30 @@ class EventLogTestCase(unittest.TestCase):
|
|||||||
self.assertIn('code', exit_event)
|
self.assertIn('code', exit_event)
|
||||||
self.assertEqual(exit_event['code'], 2)
|
self.assertEqual(exit_event['code'], 2)
|
||||||
|
|
||||||
|
def test_command_event(self):
|
||||||
|
"""Test and validate 'command' event data is valid.
|
||||||
|
|
||||||
|
Expected event log:
|
||||||
|
<version event>
|
||||||
|
<command event>
|
||||||
|
"""
|
||||||
|
name = 'repo'
|
||||||
|
subcommands = ['init' 'this']
|
||||||
|
self._event_log_module.CommandEvent(name='repo', subcommands=subcommands)
|
||||||
|
with tempfile.TemporaryDirectory(prefix='event_log_tests') as tempdir:
|
||||||
|
log_path = self._event_log_module.Write(path=tempdir)
|
||||||
|
self._log_data = self.readLog(log_path)
|
||||||
|
|
||||||
|
self.assertEqual(len(self._log_data), 2)
|
||||||
|
command_event = self._log_data[1]
|
||||||
|
self.verifyCommonKeys(self._log_data[0], expected_event_name='version')
|
||||||
|
self.verifyCommonKeys(command_event, expected_event_name='command')
|
||||||
|
# Check for 'command' event specific fields.
|
||||||
|
self.assertIn('name', command_event)
|
||||||
|
self.assertIn('subcommands', command_event)
|
||||||
|
self.assertEqual(command_event['name'], name)
|
||||||
|
self.assertEqual(command_event['subcommands'], subcommands)
|
||||||
|
|
||||||
def test_def_params_event_repo_config(self):
|
def test_def_params_event_repo_config(self):
|
||||||
"""Test 'def_params' event data outputs only repo config keys.
|
"""Test 'def_params' event data outputs only repo config keys.
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user