From 625ff838cb6490fa9cffa66491c09f51eadbff7f Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 9 Apr 2021 17:46:27 -0400 Subject: [PATCH] Add go-mods-to-bundled-provides.py --- go-mods-to-bundled-provides.py | 84 ++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100755 go-mods-to-bundled-provides.py diff --git a/go-mods-to-bundled-provides.py b/go-mods-to-bundled-provides.py new file mode 100755 index 0000000..3de621a --- /dev/null +++ b/go-mods-to-bundled-provides.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 + +''' + Tiny dumb script that generates virtual bundled `Provides` from a repo that + uses go modules and vendoring. +''' + +import sys +import re + + +def main(): + repos = get_repos_from_go_mod() + print_provides_from_modules_txt(repos) + + +def get_repos_from_go_mod(): + repos = {} + in_reqs = False + for line in open('go.mod'): + line = line.strip() + if in_reqs and line.startswith(')'): + break + if not in_reqs: + if line.startswith('require ('): + in_reqs = True + continue + req = line.split() + + repo = req[0] + tag = req[1] + + repos[repo] = go_mod_tag_to_rpm_provides_version(tag) + + return repos + + +def go_mod_tag_to_rpm_provides_version(tag): + + # go.mod tags are either exact git tags, or may be "pseudo-versions". We + # want to convert these tags to something resembling a version string that + # RPM won't fail on. For more information, see + # https://golang.org/cmd/go/#hdr-Pseudo_versions and following sections. + + # trim off any +incompatible + if tag.endswith('+incompatible'): + tag = tag[:-len('+incompatible')] + + # git tags are normally of the form v$VERSION + if tag.startswith('v'): + tag = tag[1:] + + # is this a pseudo-version? e.g. v0.0.0-20181031085051-9002847aa142 + m = re.match("(.*)-([0-9]{14})-([a-f0-9]{12})", tag) + if m: + # rpm doesn't like multiple dashes in the version, so just merge the + # timestamp and the commit checksum into the "release" field + tag = f"{m.group(1)}-{m.group(2)}.git{m.group(3)}" + + return tag + + +def print_provides_from_modules_txt(repos): + + for line in open('vendor/modules.txt'): + if line.startswith('#'): + continue + gopkg = line.strip() + repo = lookup_repo_for_pkg(repos, gopkg) + if not repo: + # must be a pkg for tests only; ignore + continue + tag = repos[repo] + print(f"Provides: bundled(golang({gopkg})) = {tag}") + + +def lookup_repo_for_pkg(repos, gopkg): + for repo in repos: + if gopkg.startswith(repo): + return repo + + +if __name__ == '__main__': + sys.exit(main())