mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
manifest: add a --json output option
Sometimes parsing JSON is easier than parsing XML, especially when the XML format is limited (which ours is). Add a --json option to the manifest command to quickly emit that form. Bug: https://crbug.com/gerrit/11743 Change-Id: Ia2bb254a78ae2b70a851638b4545fcafe8c1a76b Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/280436 Reviewed-by: Michael Mortensen <mmortensen@google.com> Tested-by: Mike Frysinger <vapier@google.com>
This commit is contained in:
parent
160748f828
commit
23411d3f9c
@ -283,9 +283,8 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
|
|||||||
def _ParseGroups(self, groups):
|
def _ParseGroups(self, groups):
|
||||||
return [x for x in re.split(r'[,\s]+', groups) if x]
|
return [x for x in re.split(r'[,\s]+', groups) if x]
|
||||||
|
|
||||||
def Save(self, fd, peg_rev=False, peg_rev_upstream=True, peg_rev_dest_branch=True, groups=None):
|
def ToXml(self, peg_rev=False, peg_rev_upstream=True, peg_rev_dest_branch=True, groups=None):
|
||||||
"""Write the current manifest out to the given file descriptor.
|
"""Return the current manifest XML."""
|
||||||
"""
|
|
||||||
mp = self.manifestProject
|
mp = self.manifestProject
|
||||||
|
|
||||||
if groups is None:
|
if groups is None:
|
||||||
@ -459,6 +458,56 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
|
|||||||
' '.join(self._repo_hooks_project.enabled_repo_hooks))
|
' '.join(self._repo_hooks_project.enabled_repo_hooks))
|
||||||
root.appendChild(e)
|
root.appendChild(e)
|
||||||
|
|
||||||
|
return doc
|
||||||
|
|
||||||
|
def ToDict(self, **kwargs):
|
||||||
|
"""Return the current manifest as a dictionary."""
|
||||||
|
# Elements that may only appear once.
|
||||||
|
SINGLE_ELEMENTS = {
|
||||||
|
'notice',
|
||||||
|
'default',
|
||||||
|
'manifest-server',
|
||||||
|
'repo-hooks',
|
||||||
|
}
|
||||||
|
# Elements that may be repeated.
|
||||||
|
MULTI_ELEMENTS = {
|
||||||
|
'remote',
|
||||||
|
'remove-project',
|
||||||
|
'project',
|
||||||
|
'extend-project',
|
||||||
|
'include',
|
||||||
|
# These are children of 'project' nodes.
|
||||||
|
'annotation',
|
||||||
|
'project',
|
||||||
|
'copyfile',
|
||||||
|
'linkfile',
|
||||||
|
}
|
||||||
|
|
||||||
|
doc = self.ToXml(**kwargs)
|
||||||
|
ret = {}
|
||||||
|
|
||||||
|
def append_children(ret, node):
|
||||||
|
for child in node.childNodes:
|
||||||
|
if child.nodeType == xml.dom.Node.ELEMENT_NODE:
|
||||||
|
attrs = child.attributes
|
||||||
|
element = dict((attrs.item(i).localName, attrs.item(i).value)
|
||||||
|
for i in range(attrs.length))
|
||||||
|
if child.nodeName in SINGLE_ELEMENTS:
|
||||||
|
ret[child.nodeName] = element
|
||||||
|
elif child.nodeName in MULTI_ELEMENTS:
|
||||||
|
ret.setdefault(child.nodeName, []).append(element)
|
||||||
|
else:
|
||||||
|
raise ManifestParseError('Unhandled element "%s"' % (child.nodeName,))
|
||||||
|
|
||||||
|
append_children(element, child)
|
||||||
|
|
||||||
|
append_children(ret, doc.firstChild)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def Save(self, fd, **kwargs):
|
||||||
|
"""Write the current manifest out to the given file descriptor."""
|
||||||
|
doc = self.ToXml(**kwargs)
|
||||||
doc.writexml(fd, '', ' ', '\n', 'UTF-8')
|
doc.writexml(fd, '', ' ', '\n', 'UTF-8')
|
||||||
|
|
||||||
def _output_manifest_project_extras(self, p, e):
|
def _output_manifest_project_extras(self, p, e):
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -68,6 +70,10 @@ to indicate the remote ref to push changes to via 'repo upload'.
|
|||||||
help='If in -r mode, do not write the dest-branch field. '
|
help='If in -r mode, do not write the dest-branch field. '
|
||||||
'Only of use if the branch names for a sha1 manifest are '
|
'Only of use if the branch names for a sha1 manifest are '
|
||||||
'sensitive.')
|
'sensitive.')
|
||||||
|
p.add_option('--json', default=False, action='store_true',
|
||||||
|
help='Output manifest in JSON format (experimental).')
|
||||||
|
p.add_option('--pretty', default=False, action='store_true',
|
||||||
|
help='Format output for humans to read.')
|
||||||
p.add_option('-o', '--output-file',
|
p.add_option('-o', '--output-file',
|
||||||
dest='output_file',
|
dest='output_file',
|
||||||
default='-',
|
default='-',
|
||||||
@ -83,6 +89,22 @@ to indicate the remote ref to push changes to via 'repo upload'.
|
|||||||
fd = sys.stdout
|
fd = sys.stdout
|
||||||
else:
|
else:
|
||||||
fd = open(opt.output_file, 'w')
|
fd = open(opt.output_file, 'w')
|
||||||
|
if opt.json:
|
||||||
|
print('warning: --json is experimental!', file=sys.stderr)
|
||||||
|
doc = self.manifest.ToDict(peg_rev=opt.peg_rev,
|
||||||
|
peg_rev_upstream=opt.peg_rev_upstream,
|
||||||
|
peg_rev_dest_branch=opt.peg_rev_dest_branch)
|
||||||
|
|
||||||
|
json_settings = {
|
||||||
|
# JSON style guide says Uunicode characters are fully allowed.
|
||||||
|
'ensure_ascii': False,
|
||||||
|
# We use 2 space indent to match JSON style guide.
|
||||||
|
'indent': 2 if opt.pretty else None,
|
||||||
|
'separators': (',', ': ') if opt.pretty else (',', ':'),
|
||||||
|
'sort_keys': True,
|
||||||
|
}
|
||||||
|
fd.write(json.dumps(doc, **json_settings))
|
||||||
|
else:
|
||||||
self.manifest.Save(fd,
|
self.manifest.Save(fd,
|
||||||
peg_rev=opt.peg_rev,
|
peg_rev=opt.peg_rev,
|
||||||
peg_rev_upstream=opt.peg_rev_upstream,
|
peg_rev_upstream=opt.peg_rev_upstream,
|
||||||
|
Loading…
Reference in New Issue
Block a user