mirror of
https://gerrit.googlesource.com/git-repo
synced 2025-06-26 20:17:52 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
0458faa502 | |||
68d5d4dfe5 | |||
a3794e9c6f | |||
080877e413 | |||
9888accb0c | |||
5a4c8fde17 | |||
835a34bdb9 |
@ -178,9 +178,7 @@ class Command(object):
|
|||||||
mp = manifest.manifestProject
|
mp = manifest.manifestProject
|
||||||
|
|
||||||
if not groups:
|
if not groups:
|
||||||
groups = mp.config.GetString('manifest.groups')
|
groups = manifest.GetGroupsStr()
|
||||||
if not groups:
|
|
||||||
groups = 'default,platform-' + platform.system().lower()
|
|
||||||
groups = [x for x in re.split(r'[,\s]+', groups) if x]
|
groups = [x for x in re.split(r'[,\s]+', groups) if x]
|
||||||
|
|
||||||
if not args:
|
if not args:
|
||||||
|
@ -252,12 +252,25 @@ name will be prefixed by the parent's.
|
|||||||
The project name must match the name Gerrit knows, if Gerrit is
|
The project name must match the name Gerrit knows, if Gerrit is
|
||||||
being used for code reviews.
|
being used for code reviews.
|
||||||
|
|
||||||
|
"name" must not be empty, and may not be an absolute path or use "." or ".."
|
||||||
|
path components. It is always interpreted relative to the remote's fetch
|
||||||
|
settings, so if a different base path is needed, declare a different remote
|
||||||
|
with the new settings needed.
|
||||||
|
These restrictions are not enforced for [Local Manifests].
|
||||||
|
|
||||||
Attribute `path`: An optional path relative to the top directory
|
Attribute `path`: An optional path relative to the top directory
|
||||||
of the repo client where the Git working directory for this project
|
of the repo client where the Git working directory for this project
|
||||||
should be placed. If not supplied the project name is used.
|
should be placed. If not supplied the project "name" is used.
|
||||||
If the project has a parent element, its path will be prefixed
|
If the project has a parent element, its path will be prefixed
|
||||||
by the parent's.
|
by the parent's.
|
||||||
|
|
||||||
|
"path" may not be an absolute path or use "." or ".." path components.
|
||||||
|
These restrictions are not enforced for [Local Manifests].
|
||||||
|
|
||||||
|
If you want to place files into the root of the checkout (e.g. a README or
|
||||||
|
Makefile or another build script), use the [copyfile] or [linkfile] elements
|
||||||
|
instead.
|
||||||
|
|
||||||
Attribute `remote`: Name of a previously defined remote element.
|
Attribute `remote`: Name of a previously defined remote element.
|
||||||
If not supplied the remote given by the default element is used.
|
If not supplied the remote given by the default element is used.
|
||||||
|
|
||||||
@ -419,12 +432,15 @@ target manifest to include - it must be a usable manifest on its own.
|
|||||||
Attribute `name`: the manifest to include, specified relative to
|
Attribute `name`: the manifest to include, specified relative to
|
||||||
the manifest repository's root.
|
the manifest repository's root.
|
||||||
|
|
||||||
|
"name" may not be an absolute path or use "." or ".." path components.
|
||||||
|
These restrictions are not enforced for [Local Manifests].
|
||||||
|
|
||||||
Attribute `groups`: List of additional groups to which all projects
|
Attribute `groups`: List of additional groups to which all projects
|
||||||
in the included manifest belong. This appends and recurses, meaning
|
in the included manifest belong. This appends and recurses, meaning
|
||||||
all projects in sub-manifests carry all parent include groups.
|
all projects in sub-manifests carry all parent include groups.
|
||||||
Same syntax as the corresponding element of `project`.
|
Same syntax as the corresponding element of `project`.
|
||||||
|
|
||||||
## Local Manifests
|
## Local Manifests {#local-manifests}
|
||||||
|
|
||||||
Additional remotes and projects may be added through local manifest
|
Additional remotes and projects may be added through local manifest
|
||||||
files stored in `$TOP_DIR/.repo/local_manifests/*.xml`.
|
files stored in `$TOP_DIR/.repo/local_manifests/*.xml`.
|
||||||
@ -452,3 +468,8 @@ Manifest files stored in `$TOP_DIR/.repo/local_manifests/*.xml` will
|
|||||||
be loaded in alphabetical order.
|
be loaded in alphabetical order.
|
||||||
|
|
||||||
The legacy `$TOP_DIR/.repo/local_manifest.xml` path is no longer supported.
|
The legacy `$TOP_DIR/.repo/local_manifest.xml` path is no longer supported.
|
||||||
|
|
||||||
|
|
||||||
|
[copyfile]: #Element-copyfile
|
||||||
|
[linkfile]: #Element-linkfile
|
||||||
|
[Local Manifests]: #local-manifests
|
||||||
|
@ -145,6 +145,21 @@ class GitConfig(object):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def DumpConfigDict(self):
|
||||||
|
"""Returns the current configuration dict.
|
||||||
|
|
||||||
|
Configuration data is information only (e.g. logging) and
|
||||||
|
should not be considered a stable data-source.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict of {<key>, <value>} for git configuration cache.
|
||||||
|
<value> are strings converted by GetString.
|
||||||
|
"""
|
||||||
|
config_dict = {}
|
||||||
|
for key in self._cache:
|
||||||
|
config_dict[key] = self.GetString(key)
|
||||||
|
return config_dict
|
||||||
|
|
||||||
def GetBoolean(self, name):
|
def GetBoolean(self, name):
|
||||||
"""Returns a boolean from the configuration file.
|
"""Returns a boolean from the configuration file.
|
||||||
None : The value was not defined, or is not a boolean.
|
None : The value was not defined, or is not a boolean.
|
||||||
|
@ -235,7 +235,7 @@ class Superproject(object):
|
|||||||
self._superproject_path,
|
self._superproject_path,
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
return None
|
return None
|
||||||
manifest_str = self._manifest.ToXml().toxml()
|
manifest_str = self._manifest.ToXml(groups=self._manifest.GetGroupsStr()).toxml()
|
||||||
manifest_path = self._manifest_path
|
manifest_path = self._manifest_path
|
||||||
try:
|
try:
|
||||||
with open(manifest_path, 'w', encoding='utf-8') as fp:
|
with open(manifest_path, 'w', encoding='utf-8') as fp:
|
||||||
|
@ -132,6 +132,21 @@ class EventLog(object):
|
|||||||
exit_event['code'] = result
|
exit_event['code'] = result
|
||||||
self._log.append(exit_event)
|
self._log.append(exit_event)
|
||||||
|
|
||||||
|
def DefParamRepoEvents(self, config):
|
||||||
|
"""Append a 'def_param' event for each repo.* config key to the current log.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config: Repo configuration dictionary
|
||||||
|
"""
|
||||||
|
# Only output the repo.* config parameters.
|
||||||
|
repo_config = {k: v for k, v in config.items() if k.startswith('repo.')}
|
||||||
|
|
||||||
|
for param, value in repo_config.items():
|
||||||
|
def_param_event = self._CreateEventDict('def_param')
|
||||||
|
def_param_event['param'] = param
|
||||||
|
def_param_event['value'] = value
|
||||||
|
self._log.append(def_param_event)
|
||||||
|
|
||||||
def _GetEventTargetPath(self):
|
def _GetEventTargetPath(self):
|
||||||
"""Get the 'trace2.eventtarget' path from git configuration.
|
"""Get the 'trace2.eventtarget' path from git configuration.
|
||||||
|
|
||||||
|
@ -77,22 +77,6 @@ def _set_project_revisions(projects):
|
|||||||
project.revisionExpr = revisionExpr
|
project.revisionExpr = revisionExpr
|
||||||
|
|
||||||
|
|
||||||
def _manifest_groups(manifest):
|
|
||||||
"""Returns the manifest group string that should be synced
|
|
||||||
|
|
||||||
This is the same logic used by Command.GetProjects(), which is used during
|
|
||||||
repo sync
|
|
||||||
|
|
||||||
Args:
|
|
||||||
manifest: The XmlManifest object
|
|
||||||
"""
|
|
||||||
mp = manifest.manifestProject
|
|
||||||
groups = mp.config.GetString('manifest.groups')
|
|
||||||
if not groups:
|
|
||||||
groups = 'default,platform-' + platform.system().lower()
|
|
||||||
return groups
|
|
||||||
|
|
||||||
|
|
||||||
def generate_gitc_manifest(gitc_manifest, manifest, paths=None):
|
def generate_gitc_manifest(gitc_manifest, manifest, paths=None):
|
||||||
"""Generate a manifest for shafsd to use for this GITC client.
|
"""Generate a manifest for shafsd to use for this GITC client.
|
||||||
|
|
||||||
@ -107,7 +91,7 @@ def generate_gitc_manifest(gitc_manifest, manifest, paths=None):
|
|||||||
if paths is None:
|
if paths is None:
|
||||||
paths = list(manifest.paths.keys())
|
paths = list(manifest.paths.keys())
|
||||||
|
|
||||||
groups = [x for x in re.split(r'[,\s]+', _manifest_groups(manifest)) if x]
|
groups = [x for x in re.split(r'[,\s]+', manifest.GetGroupsStr()) if x]
|
||||||
|
|
||||||
# Convert the paths to projects, and filter them to the matched groups.
|
# Convert the paths to projects, and filter them to the matched groups.
|
||||||
projects = [manifest.paths[p] for p in paths]
|
projects = [manifest.paths[p] for p in paths]
|
||||||
@ -166,7 +150,7 @@ def save_manifest(manifest, client_dir=None):
|
|||||||
else:
|
else:
|
||||||
manifest_file = os.path.join(client_dir, '.manifest')
|
manifest_file = os.path.join(client_dir, '.manifest')
|
||||||
with open(manifest_file, 'w') as f:
|
with open(manifest_file, 'w') as f:
|
||||||
manifest.Save(f, groups=_manifest_groups(manifest))
|
manifest.Save(f, groups=manifest.GetGroupsStr())
|
||||||
# TODO(sbasi/jorg): Come up with a solution to remove the sleep below.
|
# TODO(sbasi/jorg): Come up with a solution to remove the sleep below.
|
||||||
# Give the GITC filesystem time to register the manifest changes.
|
# Give the GITC filesystem time to register the manifest changes.
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
2
main.py
2
main.py
@ -297,6 +297,8 @@ class _Repo(object):
|
|||||||
|
|
||||||
cmd.event_log.FinishEvent(cmd_event, finish,
|
cmd.event_log.FinishEvent(cmd_event, finish,
|
||||||
result is None or result == 0)
|
result is None or result == 0)
|
||||||
|
git_trace2_event_log.DefParamRepoEvents(
|
||||||
|
cmd.manifest.manifestProject.config.DumpConfigDict())
|
||||||
git_trace2_event_log.ExitEvent(result)
|
git_trace2_event_log.ExitEvent(result)
|
||||||
|
|
||||||
if gopts.event_log:
|
if gopts.event_log:
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
@ -604,6 +605,17 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
|
|||||||
def HasSubmodules(self):
|
def HasSubmodules(self):
|
||||||
return self.manifestProject.config.GetBoolean('repo.submodules')
|
return self.manifestProject.config.GetBoolean('repo.submodules')
|
||||||
|
|
||||||
|
def GetDefaultGroupsStr(self):
|
||||||
|
"""Returns the default group string for the platform."""
|
||||||
|
return 'default,platform-' + platform.system().lower()
|
||||||
|
|
||||||
|
def GetGroupsStr(self):
|
||||||
|
"""Returns the manifest group string that should be synced."""
|
||||||
|
groups = self.manifestProject.config.GetString('manifest.groups')
|
||||||
|
if not groups:
|
||||||
|
groups = self.GetDefaultGroupsStr()
|
||||||
|
return groups
|
||||||
|
|
||||||
def _Unload(self):
|
def _Unload(self):
|
||||||
self._loaded = False
|
self._loaded = False
|
||||||
self._projects = {}
|
self._projects = {}
|
||||||
@ -1027,7 +1039,8 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
|
|||||||
if not path:
|
if not path:
|
||||||
path = name
|
path = name
|
||||||
else:
|
else:
|
||||||
msg = self._CheckLocalPath(path, dir_ok=True)
|
# NB: The "." project is handled specially in Project.Sync_LocalHalf.
|
||||||
|
msg = self._CheckLocalPath(path, dir_ok=True, cwd_dot_ok=True)
|
||||||
if msg:
|
if msg:
|
||||||
raise ManifestInvalidPathError(
|
raise ManifestInvalidPathError(
|
||||||
'<project> invalid "path": %s: %s' % (path, msg))
|
'<project> invalid "path": %s: %s' % (path, msg))
|
||||||
@ -1215,7 +1228,9 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
|
|||||||
# our constructed logic here. Especially since manifest authors only use
|
# our constructed logic here. Especially since manifest authors only use
|
||||||
# / in their paths.
|
# / in their paths.
|
||||||
resep = re.compile(r'[/%s]' % re.escape(os.path.sep))
|
resep = re.compile(r'[/%s]' % re.escape(os.path.sep))
|
||||||
parts = resep.split(path)
|
# Strip off trailing slashes as those only produce '' elements, and we use
|
||||||
|
# parts to look for individual bad components.
|
||||||
|
parts = resep.split(path.rstrip('/'))
|
||||||
|
|
||||||
# Some people use src="." to create stable links to projects. Lets allow
|
# Some people use src="." to create stable links to projects. Lets allow
|
||||||
# that but reject all other uses of "." to keep things simple.
|
# that but reject all other uses of "." to keep things simple.
|
||||||
|
19
project.py
19
project.py
@ -863,7 +863,7 @@ class Project(object):
|
|||||||
out.nl()
|
out.nl()
|
||||||
out.project('project %s/' % self.relpath)
|
out.project('project %s/' % self.relpath)
|
||||||
out.nl()
|
out.nl()
|
||||||
out.write(p.stdout)
|
out.write('%s', p.stdout)
|
||||||
return p.Wait() == 0
|
return p.Wait() == 0
|
||||||
|
|
||||||
# Publish / Upload ##
|
# Publish / Upload ##
|
||||||
@ -1227,6 +1227,18 @@ class Project(object):
|
|||||||
self.CleanPublishedCache(all_refs)
|
self.CleanPublishedCache(all_refs)
|
||||||
revid = self.GetRevisionId(all_refs)
|
revid = self.GetRevisionId(all_refs)
|
||||||
|
|
||||||
|
# Special case the root of the repo client checkout. Make sure it doesn't
|
||||||
|
# contain files being checked out to dirs we don't allow.
|
||||||
|
if self.relpath == '.':
|
||||||
|
PROTECTED_PATHS = {'.repo'}
|
||||||
|
paths = set(self.work_git.ls_tree('-z', '--name-only', '--', revid).split('\0'))
|
||||||
|
bad_paths = paths & PROTECTED_PATHS
|
||||||
|
if bad_paths:
|
||||||
|
syncbuf.fail(self,
|
||||||
|
'Refusing to checkout project that writes to protected '
|
||||||
|
'paths: %s' % (', '.join(bad_paths),))
|
||||||
|
return
|
||||||
|
|
||||||
def _doff():
|
def _doff():
|
||||||
self._FastForward(revid)
|
self._FastForward(revid)
|
||||||
self._CopyAndLinkFiles()
|
self._CopyAndLinkFiles()
|
||||||
@ -1698,6 +1710,11 @@ class Project(object):
|
|||||||
if cb is None or name != cb:
|
if cb is None or name != cb:
|
||||||
kill.append(name)
|
kill.append(name)
|
||||||
|
|
||||||
|
# Minor optimization: If there's nothing to prune, then don't try to read
|
||||||
|
# any project state.
|
||||||
|
if not kill and not cb:
|
||||||
|
return []
|
||||||
|
|
||||||
rev = self.GetRevisionId(left)
|
rev = self.GetRevisionId(left)
|
||||||
if cb is not None \
|
if cb is not None \
|
||||||
and not self._revlist(HEAD + '...' + rev) \
|
and not self._revlist(HEAD + '...' + rev) \
|
||||||
|
2
repo
2
repo
@ -318,7 +318,7 @@ def GetParser(gitc_init=False):
|
|||||||
help='filter for use with --partial-clone '
|
help='filter for use with --partial-clone '
|
||||||
'[default: %default]')
|
'[default: %default]')
|
||||||
group.add_option('--worktree', action='store_true',
|
group.add_option('--worktree', action='store_true',
|
||||||
help=optparse.SUPPRESS_HELP)
|
help='use git-worktree to manage projects')
|
||||||
group.add_option('--archive', action='store_true',
|
group.add_option('--archive', action='store_true',
|
||||||
help='checkout an archive instead of a git repository for '
|
help='checkout an archive instead of a git repository for '
|
||||||
'each project. See git archive.')
|
'each project. See git archive.')
|
||||||
|
@ -127,10 +127,8 @@ to update the working directory files.
|
|||||||
g.add_option('--clone-filter', action='store', default='blob:none',
|
g.add_option('--clone-filter', action='store', default='blob:none',
|
||||||
dest='clone_filter',
|
dest='clone_filter',
|
||||||
help='filter for use with --partial-clone [default: %default]')
|
help='filter for use with --partial-clone [default: %default]')
|
||||||
# TODO(vapier): Expose option with real help text once this has been in the
|
|
||||||
# wild for a while w/out significant bug reports. Goal is by ~Sep 2020.
|
|
||||||
g.add_option('--worktree', action='store_true',
|
g.add_option('--worktree', action='store_true',
|
||||||
help=optparse.SUPPRESS_HELP)
|
help='use git-worktree to manage projects')
|
||||||
g.add_option('--archive',
|
g.add_option('--archive',
|
||||||
dest='archive', action='store_true',
|
dest='archive', action='store_true',
|
||||||
help='checkout an archive instead of a git repository for '
|
help='checkout an archive instead of a git repository for '
|
||||||
@ -269,7 +267,7 @@ to update the working directory files.
|
|||||||
|
|
||||||
groups = [x for x in groups if x]
|
groups = [x for x in groups if x]
|
||||||
groupstr = ','.join(groups)
|
groupstr = ','.join(groups)
|
||||||
if opt.platform == 'auto' and groupstr == 'default,platform-' + platform.system().lower():
|
if opt.platform == 'auto' and groupstr == self.manifest.GetDefaultGroupsStr():
|
||||||
groupstr = None
|
groupstr = None
|
||||||
m.config.SetString('manifest.groups', groupstr)
|
m.config.SetString('manifest.groups', groupstr)
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"""Unittests for the git_superproject.py module."""
|
"""Unittests for the git_superproject.py module."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
@ -34,6 +35,7 @@ class SuperprojectTestCase(unittest.TestCase):
|
|||||||
self.manifest_file = os.path.join(
|
self.manifest_file = os.path.join(
|
||||||
self.repodir, manifest_xml.MANIFEST_FILE_NAME)
|
self.repodir, manifest_xml.MANIFEST_FILE_NAME)
|
||||||
os.mkdir(self.repodir)
|
os.mkdir(self.repodir)
|
||||||
|
self.platform = platform.system().lower()
|
||||||
|
|
||||||
# The manifest parsing really wants a git repo currently.
|
# The manifest parsing really wants a git repo currently.
|
||||||
gitdir = os.path.join(self.repodir, 'manifests.git')
|
gitdir = os.path.join(self.repodir, 'manifests.git')
|
||||||
@ -48,8 +50,8 @@ class SuperprojectTestCase(unittest.TestCase):
|
|||||||
<remote name="default-remote" fetch="http://localhost" />
|
<remote name="default-remote" fetch="http://localhost" />
|
||||||
<default remote="default-remote" revision="refs/heads/main" />
|
<default remote="default-remote" revision="refs/heads/main" />
|
||||||
<superproject name="superproject"/>
|
<superproject name="superproject"/>
|
||||||
<project path="art" name="platform/art" />
|
<project path="art" name="platform/art" groups="notdefault,platform-""" + self.platform + """
|
||||||
</manifest>
|
" /></manifest>
|
||||||
""")
|
""")
|
||||||
self._superproject = git_superproject.Superproject(manifest, self.repodir)
|
self._superproject = git_superproject.Superproject(manifest, self.repodir)
|
||||||
|
|
||||||
@ -142,7 +144,8 @@ class SuperprojectTestCase(unittest.TestCase):
|
|||||||
'<?xml version="1.0" ?><manifest>' +
|
'<?xml version="1.0" ?><manifest>' +
|
||||||
'<remote name="default-remote" fetch="http://localhost"/>' +
|
'<remote name="default-remote" fetch="http://localhost"/>' +
|
||||||
'<default remote="default-remote" revision="refs/heads/main"/>' +
|
'<default remote="default-remote" revision="refs/heads/main"/>' +
|
||||||
'<project name="platform/art" path="art" revision="ABCDEF"/>' +
|
'<project name="platform/art" path="art" revision="ABCDEF" ' +
|
||||||
|
'groups="notdefault,platform-' + self.platform + '"/>' +
|
||||||
'<superproject name="superproject"/>' +
|
'<superproject name="superproject"/>' +
|
||||||
'</manifest>')
|
'</manifest>')
|
||||||
|
|
||||||
@ -169,7 +172,8 @@ class SuperprojectTestCase(unittest.TestCase):
|
|||||||
'<remote name="default-remote" fetch="http://localhost"/>' +
|
'<remote name="default-remote" fetch="http://localhost"/>' +
|
||||||
'<default remote="default-remote" revision="refs/heads/main"/>' +
|
'<default remote="default-remote" revision="refs/heads/main"/>' +
|
||||||
'<project name="platform/art" path="art" ' +
|
'<project name="platform/art" path="art" ' +
|
||||||
'revision="2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea"/>' +
|
'revision="2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea" ' +
|
||||||
|
'groups="notdefault,platform-' + self.platform + '"/>' +
|
||||||
'<superproject name="superproject"/>' +
|
'<superproject name="superproject"/>' +
|
||||||
'</manifest>')
|
'</manifest>')
|
||||||
|
|
||||||
|
@ -161,6 +161,55 @@ 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_def_params_event_repo_config(self):
|
||||||
|
"""Test 'def_params' event data outputs only repo config keys.
|
||||||
|
|
||||||
|
Expected event log:
|
||||||
|
<version event>
|
||||||
|
<def_param event>
|
||||||
|
<def_param event>
|
||||||
|
"""
|
||||||
|
config = {
|
||||||
|
'git.foo': 'bar',
|
||||||
|
'repo.partialclone': 'true',
|
||||||
|
'repo.partialclonefilter': 'blob:none',
|
||||||
|
}
|
||||||
|
self._event_log_module.DefParamRepoEvents(config)
|
||||||
|
|
||||||
|
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), 3)
|
||||||
|
def_param_events = self._log_data[1:]
|
||||||
|
self.verifyCommonKeys(self._log_data[0], expected_event_name='version')
|
||||||
|
|
||||||
|
for event in def_param_events:
|
||||||
|
self.verifyCommonKeys(event, expected_event_name='def_param')
|
||||||
|
# Check for 'def_param' event specific fields.
|
||||||
|
self.assertIn('param', event)
|
||||||
|
self.assertIn('value', event)
|
||||||
|
self.assertTrue(event['param'].startswith('repo.'))
|
||||||
|
|
||||||
|
def test_def_params_event_no_repo_config(self):
|
||||||
|
"""Test 'def_params' event data won't output non-repo config keys.
|
||||||
|
|
||||||
|
Expected event log:
|
||||||
|
<version event>
|
||||||
|
"""
|
||||||
|
config = {
|
||||||
|
'git.foo': 'bar',
|
||||||
|
'git.core.foo2': 'baz',
|
||||||
|
}
|
||||||
|
self._event_log_module.DefParamRepoEvents(config)
|
||||||
|
|
||||||
|
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), 1)
|
||||||
|
self.verifyCommonKeys(self._log_data[0], expected_event_name='version')
|
||||||
|
|
||||||
def test_write_with_filename(self):
|
def test_write_with_filename(self):
|
||||||
"""Test Write() with a path to a file exits with None."""
|
"""Test Write() with a path to a file exits with None."""
|
||||||
self.assertIsNone(self._event_log_module.Write(path='path/to/file'))
|
self.assertIsNone(self._event_log_module.Write(path='path/to/file'))
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"""Unittests for the manifest_xml.py module."""
|
"""Unittests for the manifest_xml.py module."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
@ -31,6 +32,7 @@ INVALID_FS_PATHS = (
|
|||||||
'..',
|
'..',
|
||||||
'../',
|
'../',
|
||||||
'./',
|
'./',
|
||||||
|
'.//',
|
||||||
'foo/',
|
'foo/',
|
||||||
'./foo',
|
'./foo',
|
||||||
'../foo',
|
'../foo',
|
||||||
@ -377,6 +379,11 @@ class ProjectElementTests(ManifestParseTestCase):
|
|||||||
self.assertCountEqual(
|
self.assertCountEqual(
|
||||||
result['extras'],
|
result['extras'],
|
||||||
['g1', 'g2', 'g1', 'name:extras', 'all', 'path:path'])
|
['g1', 'g2', 'g1', 'name:extras', 'all', 'path:path'])
|
||||||
|
groupstr = 'default,platform-' + platform.system().lower()
|
||||||
|
self.assertEqual(groupstr, manifest.GetGroupsStr())
|
||||||
|
groupstr = 'g1,g2,g1'
|
||||||
|
manifest.manifestProject.config.SetString('manifest.groups', groupstr)
|
||||||
|
self.assertEqual(groupstr, manifest.GetGroupsStr())
|
||||||
|
|
||||||
def test_set_revision_id(self):
|
def test_set_revision_id(self):
|
||||||
"""Check setting of project's revisionId."""
|
"""Check setting of project's revisionId."""
|
||||||
@ -421,6 +428,28 @@ class ProjectElementTests(ManifestParseTestCase):
|
|||||||
self.assertEqual(manifest.projects[0].objdir,
|
self.assertEqual(manifest.projects[0].objdir,
|
||||||
os.path.join(self.tempdir, '.repo/project-objects/a/path.git'))
|
os.path.join(self.tempdir, '.repo/project-objects/a/path.git'))
|
||||||
|
|
||||||
|
manifest = parse('a/path', 'foo//////')
|
||||||
|
self.assertEqual(manifest.projects[0].gitdir,
|
||||||
|
os.path.join(self.tempdir, '.repo/projects/foo.git'))
|
||||||
|
self.assertEqual(manifest.projects[0].objdir,
|
||||||
|
os.path.join(self.tempdir, '.repo/project-objects/a/path.git'))
|
||||||
|
|
||||||
|
def test_toplevel_path(self):
|
||||||
|
"""Check handling of path=. specially."""
|
||||||
|
def parse(name, path):
|
||||||
|
return self.getXmlManifest(f"""
|
||||||
|
<manifest>
|
||||||
|
<remote name="default-remote" fetch="http://localhost" />
|
||||||
|
<default remote="default-remote" revision="refs/heads/main" />
|
||||||
|
<project name="{name}" path="{path}" />
|
||||||
|
</manifest>
|
||||||
|
""")
|
||||||
|
|
||||||
|
for path in ('.', './', './/', './//'):
|
||||||
|
manifest = parse('server/path', path)
|
||||||
|
self.assertEqual(manifest.projects[0].gitdir,
|
||||||
|
os.path.join(self.tempdir, '.repo/projects/..git'))
|
||||||
|
|
||||||
def test_bad_path_name_checks(self):
|
def test_bad_path_name_checks(self):
|
||||||
"""Check handling of bad path & name attributes."""
|
"""Check handling of bad path & name attributes."""
|
||||||
def parse(name, path):
|
def parse(name, path):
|
||||||
@ -448,6 +477,9 @@ class ProjectElementTests(ManifestParseTestCase):
|
|||||||
|
|
||||||
with self.assertRaises(error.ManifestInvalidPathError):
|
with self.assertRaises(error.ManifestInvalidPathError):
|
||||||
parse(path, 'ok')
|
parse(path, 'ok')
|
||||||
|
|
||||||
|
# We have a dedicated test for path=".".
|
||||||
|
if path not in {'.'}:
|
||||||
with self.assertRaises(error.ManifestInvalidPathError):
|
with self.assertRaises(error.ManifestInvalidPathError):
|
||||||
parse('ok', path)
|
parse('ok', path)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user