summaryrefslogtreecommitdiffstats
path: root/meta/classes-recipe/go-mod-update-modules.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'meta/classes-recipe/go-mod-update-modules.bbclass')
-rw-r--r--meta/classes-recipe/go-mod-update-modules.bbclass146
1 files changed, 0 insertions, 146 deletions
diff --git a/meta/classes-recipe/go-mod-update-modules.bbclass b/meta/classes-recipe/go-mod-update-modules.bbclass
deleted file mode 100644
index 0083588a25..0000000000
--- a/meta/classes-recipe/go-mod-update-modules.bbclass
+++ /dev/null
@@ -1,146 +0,0 @@
1addtask do_update_modules after do_configure
2do_update_modules[nostamp] = "1"
3do_update_modules[network] = "1"
4
5# This class maintains two files, BPN-go-mods.inc and BPN-licenses.inc.
6#
7# -go-mods.inc will append SRC_URI with all of the Go modules that are
8# dependencies of this recipe.
9#
10# -licenses.inc will append LICENSE and LIC_FILES_CHKSUM with the found licenses
11# in the modules.
12#
13# These files are machine-generated and should not be modified.
14
15python do_update_modules() {
16 import subprocess, tempfile, json, re, urllib.parse
17 from oe.license import tidy_licenses
18 from oe.license_finder import find_licenses_up
19
20 def unescape_path(path):
21 """Unescape capital letters using exclamation points."""
22 return re.sub(r'!([a-z])', lambda m: m.group(1).upper(), path)
23
24 def fold_uri(uri):
25 """Fold URI for sorting shorter module paths before longer."""
26 return uri.replace(';', ' ').replace('/', '!')
27
28 def parse_existing_licenses():
29 hashes = {}
30 for url in d.getVar("LIC_FILES_CHKSUM").split():
31 (method, host, path, user, pswd, parm) = bb.fetch.decodeurl(url)
32 if "spdx" in parm and parm["spdx"] != "Unknown":
33 hashes[parm["md5"]] = urllib.parse.unquote_plus(parm["spdx"])
34 return hashes
35
36 bpn = d.getVar("BPN")
37 thisdir = d.getVar("THISDIR")
38 s_dir = d.getVar("S")
39
40 with tempfile.TemporaryDirectory(prefix='go-mod-') as mod_cache_dir:
41 notice = """
42# This file has been generated by go-mod-update-modules.bbclass
43#
44# Do not modify it by hand, as the contents will be replaced when
45# running the update-modules task.
46
47"""
48
49 env = dict(os.environ, GOMODCACHE=mod_cache_dir)
50 source = d.expand("${UNPACKDIR}/${GO_SRCURI_DESTSUFFIX}")
51 go_install = d.getVar("GO_INSTALL").split()
52 output = subprocess.check_output(("go", "list", "-json=Dir,Module", "-deps", *go_install),
53 cwd=source, env=env, text=True)
54
55 #
56 # Licenses
57 #
58
59 # load hashes from the existing licenses.inc
60 extra_hashes = parse_existing_licenses()
61
62 # The output of this isn't actually valid JSON, but a series of dicts.
63 # Wrap in [] and join the dicts with ,
64 # Very frustrating that the json parser in python can't repeatedly
65 # parse from a stream.
66 pkgs = json.loads('[' + output.replace('}\n{', '},\n{') + ']')
67
68 # Collect licenses for the dependencies.
69 lic_files = {}
70 for pkg in pkgs:
71 pkg_dir = pkg['Dir']
72 if not pkg_dir.startswith(mod_cache_dir):
73 continue
74
75 mod_dir = pkg['Module']['Dir']
76 path = os.path.relpath(mod_dir, mod_cache_dir)
77
78 for name, file, md5 in find_licenses_up(pkg_dir, mod_dir, d, first_only=True, extra_hashes=extra_hashes):
79 lic_files[os.path.join(path, file)] = (name, md5)
80
81 licenses = set()
82 lic_files_chksum = []
83 for lic_file in lic_files:
84 license_name, license_md5 = lic_files[lic_file]
85 if license_name == "Unknown":
86 bb.warn(f"Unknown license: {lic_file} {license_md5}")
87
88 licenses.add(lic_files[lic_file][0])
89 lic_files_chksum.append(
90 f'file://pkg/mod/{lic_file};md5={license_md5};spdx={urllib.parse.quote_plus(license_name)}')
91
92 licenses_filename = os.path.join(thisdir, f"{bpn}-licenses.inc")
93 with open(licenses_filename, "w") as f:
94 f.write(notice)
95 f.write(f'LICENSE += "& {" & ".join(tidy_licenses(licenses))}"\n\n')
96 f.write('LIC_FILES_CHKSUM += "\\\n')
97 for lic in sorted(lic_files_chksum, key=fold_uri):
98 f.write(' ' + lic + ' \\\n')
99 f.write('"\n')
100
101 #
102 # Sources
103 #
104
105 # Collect the module cache files downloaded by the go list command as
106 # the go list command knows best what the go list command needs and it
107 # needs more files in the module cache than the go install command as
108 # it doesn't do the dependency pruning mentioned in the Go module
109 # reference, https://go.dev/ref/mod, for go 1.17 or higher.
110 src_uris = []
111 downloaddir = os.path.join(mod_cache_dir, 'cache', 'download')
112 for dirpath, _, filenames in os.walk(downloaddir):
113 # We want to process files under @v directories
114 path, base = os.path.split(os.path.relpath(dirpath, downloaddir))
115 if base != '@v':
116 continue
117
118 path = unescape_path(path)
119 zipver = None
120 for name in filenames:
121 ver, ext = os.path.splitext(name)
122 if ext == '.zip':
123 chksum = bb.utils.sha256_file(os.path.join(dirpath, name))
124 src_uris.append(f'gomod://{path};version={ver};sha256sum={chksum}')
125 zipver = ver
126 break
127 for name in filenames:
128 ver, ext = os.path.splitext(name)
129 if ext == '.mod' and ver != zipver:
130 chksum = bb.utils.sha256_file(os.path.join(dirpath, name))
131 src_uris.append(f'gomod://{path};version={ver};mod=1;sha256sum={chksum}')
132
133
134 go_mods_filename = os.path.join(thisdir, f"{bpn}-go-mods.inc")
135 with open(go_mods_filename, "w") as f:
136 f.write(notice)
137 f.write('SRC_URI += "\\\n')
138 for uri in sorted(src_uris, key=fold_uri):
139 f.write(' ' + uri + ' \\\n')
140 f.write('"\n')
141
142 subprocess.check_output(("go", "clean", "-modcache"), cwd=source, env=env, text=True)
143}
144
145# This doesn't work as we need to wipe the inc files first so we don't try looking for LICENSE files that don't yet exist
146# RECIPE_UPGRADE_EXTRA_TASKS += "do_update_modules"