Last active
January 10, 2025 17:09
-
-
Save fmoessbauer/3447e5eee62f874f2ceb59da384d4c4c to your computer and use it in GitHub Desktop.
Revisions
-
fmoessbauer revised this gist
Jan 10, 2025 . 1 changed file with 46 additions and 19 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -17,6 +17,9 @@ # repo manifest spec # https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.md#Element-default # TODO: this requires a kas schema addition LINKFILES_SUPPRTED = False def get_defaults(el): defaults = { @@ -50,31 +53,43 @@ def get_projects(el): projects = {} for child in el: if child.tag == 'project': name = child.attrib.get('name') projects[name] = { 'path': child.attrib.get('path'), 'remote': child.attrib.get('remote'), 'revision': child.attrib.get('revision'), 'upstream': child.attrib.get('upstream'), } for po in child: if po.tag == 'linkfile': if 'linkfiles' not in projects[name]: projects[name]['linkfiles'] = [] projects[name]['linkfiles'].append( {'src': po.attrib.get('src'), 'dest': po.attrib.get('dest')}) continue print(f'warning: {po.tag} on "{name}" ignored', file=sys.stderr) return projects def _triage_revision(rev, upstream): if rev and re.match(r'^[0-9a-f]{40}|[0-9a-f]{64}$', rev): return (rev, None, upstream) if rev and rev.startswith('refs/tags/'): return (None, rev[11:], upstream) return (None, None, rev) def get_kas_defaults(defaults): _, tag, branch = _triage_revision(defaults.get('revision'), defaults.get('upstream')) defaults = {} if tag: defaults['repos'] = {'tag': tag} if branch: defaults['repos'] = {'branch': branch} return defaults def get_kas_repos(defaults, remotes, projects): @@ -92,7 +107,7 @@ def get_kas_repos(defaults, remotes, projects): if not revision: raise ValueError(f'No revision specified for project {name}') commit, tag, branch = _triage_revision(revision, upstream) repos[name] = { 'url': f'{remote_url}/{name}', @@ -102,8 +117,19 @@ def get_kas_repos(defaults, remotes, projects): repos[name]['path'] = path if commit: repos[name]['commit'] = commit repos[name]['branch'] = None repos[name]['tag'] = None if tag: repos[name]['tag'] = tag repos[name]['branch'] = None if branch: repos[name]['branch'] = branch repos[name]['tag'] = None # disable importing layers repos[name]['layers'] = {'.': False} if 'linkfiles' in project and LINKFILES_SUPPRTED: repos[name]['linkfiles'] = project['linkfiles'] return repos @@ -128,16 +154,17 @@ def parseManifestXML(xmlfile): return manifest def get_kas_representation(manifest): defaults = manifest['defaults'] remotes = manifest['remotes'] projects = manifest['projects'] spec = { 'header': {'version': 18}, 'defaults': get_kas_defaults(defaults), 'repos': get_kas_repos(defaults, remotes, projects) } return spec @@ -149,5 +176,5 @@ def get_kas_represenation(manifest): infile = sys.argv[1] manifest = parseManifestXML(infile) kas = get_kas_representation(manifest) yaml.dump(kas, sys.stdout, sort_keys=False) -
fmoessbauer created this gist
Oct 11, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,153 @@ # SPDX-License-Identifier: MIT # SPDX-Copyright-Notice: Copyright 2024 Siemens AG # # Author: Felix Moessbauer <felix.moessbauer@siemens.com> # # Convert a repo manifest XML file to a kas YAML file # Example: # repoManifest2kasYml.py default.xml > kas.yml # kas checkout kas.yml import xml.etree.ElementTree as ET import yaml import sys import re # repo manifest spec # https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.md#Element-default def get_defaults(el): defaults = { 'remote': None, 'revision': None, 'upstream': None } if len(el) > 1: raise ValueError('Too many default elements') for child in el: if child.tag == 'default': defaults['remote'] = child.attrib.get('remote') defaults['revision'] = child.attrib.get('revision') defaults['upstream'] = child.attrib.get('upstream') return defaults def get_remotes(el): remotes = {} for child in el: if child.tag == 'remote': remotes[child.attrib.get('name')] = { 'fetch': child.attrib.get('fetch'), 'revision': child.attrib.get('revision') } return remotes def get_projects(el): projects = {} for child in el: if child.tag == 'project': projects[child.attrib.get('name')] = { 'path': child.attrib.get('path'), 'remote': child.attrib.get('remote'), 'revision': child.attrib.get('revision'), 'upstream': child.attrib.get('upstream') } return projects def _triage_revision(rev, upstream): if re.match(r'^[0-9a-f]{40}|[0-9a-f]{64}$', rev): return (rev, upstream) return (None, rev) def get_kas_defaults(defaults): _, branch = _triage_revision(defaults.get('revision'), defaults.get('upstream')) if not branch: return {} return { 'repos': { 'branch': branch } } def get_kas_repos(defaults, remotes, projects): repos = {} for name, project in projects.items(): remote = project.get('remote') or defaults.get('remote') if not remote: raise ValueError(f'No remote specified for project {name}') remote_url = remotes[remote]['fetch'] # only branches can be defaulted, but we don't know if the revision # is a branch or a commit (yet) revision = project.get('revision') or defaults.get('revision') upstream = project.get('upstream') if not revision: raise ValueError(f'No revision specified for project {name}') commit, branch = _triage_revision(revision, upstream) repos[name] = { 'url': f'{remote_url}/{name}', } path = project.get('path') if path: repos[name]['path'] = path if commit: repos[name]['commit'] = commit if branch: repos[name]['branch'] = branch return repos def parseManifestXML(xmlfile): ''' Parse a repo manifest XML file and return a dictionary of the manifest with all relevant information. ''' tree = ET.parse(xmlfile) root = tree.getroot() default = root.findall('default') remotes = root.findall('remote') projects = root.findall('project') # TODO: include manifest support manifest = { 'defaults': get_defaults(default), 'remotes': get_remotes(remotes), 'projects': get_projects(projects) } return manifest def get_kas_represenation(manifest): defaults = manifest['defaults'] remotes = manifest['remotes'] projects = manifest['projects'] spec = { 'header': {'version': 17}, 'defaults': get_kas_defaults(defaults), 'repos': get_kas_repos(defaults, remotes, projects) } return spec if __name__ == '__main__': if (len(sys.argv) != 2): print('Usage: ' + sys.argv[0] + ' infile') sys.exit(0) infile = sys.argv[1] manifest = parseManifestXML(infile) kas = get_kas_represenation(manifest) yaml.dump(kas, sys.stdout)