1#! /usr/bin/env python3 2 3import json 4import re 5import os 6import subprocess 7import sys 8import types 9import urllib.parse 10 11 12def resolve_commit(repo, ref): 13 # If it looks like a SHA, just return that 14 if re.match(r"[a-z0-9]{40}", ref): 15 return ref 16 17 # Otherwise it's probably a tag name so resolve it 18 cmd = ("git", "ls-remote", "--tags", "--exit-code", repo, ref) 19 ret = subprocess.run(cmd, check=True, text=True, capture_output=True) 20 sha = ret.stdout.split(maxsplit=1)[0] 21 assert len(sha) == 40 22 return sha 23 24 25def transform_git(repo_url, repo_ref, destination): 26 parts = urllib.parse.urlparse(repo_url) 27 protocol = parts.scheme 28 parts = parts._replace(scheme="git") 29 url = urllib.parse.urlunparse(parts) 30 # Resolve the commit reference to a SHA 31 sha = resolve_commit(repo_url, repo_ref) 32 33 return url + f";protocol={protocol};nobranch=1;destsuffix={destination};rev={sha}" 34 35 36def load_module(filename): 37 import importlib.util 38 39 spec = importlib.util.spec_from_file_location("fetchmodule", filename) 40 module = importlib.util.module_from_spec(spec) 41 spec.loader.exec_module(module) 42 return module 43 44 45def convert_fetch(basedir): 46 """ 47 Convert the external/fetch_sources.py data 48 """ 49 fetch = load_module(os.path.join(basedir, "fetch_sources.py")) 50 lines = [] 51 for p in fetch.PACKAGES: 52 if isinstance(p, fetch.SourcePackage): 53 # Ignore these as so far we can use the system copies 54 pass 55 elif isinstance(p, fetch.SourceFile): 56 dest = "/".join(["git/external", p.baseDir, p.extractDir]) 57 url = f"{p.url};subdir={dest};sha256sum={p.checksum}" 58 lines.append(f" {url} \\") 59 elif isinstance(p, fetch.GitRepo): 60 dest = "/".join(["git/external", p.baseDir, p.extractDir]) 61 url = transform_git(p.httpsUrl, p.revision, dest) 62 lines.append(f" {url} \\") 63 else: 64 assert f"Unexpected {p=}" 65 return lines 66 67 68def convert_knowngood(basedir, destination): 69 """ 70 Convert the """ 71 filename = os.path.join(basedir, "vulkan-validationlayers/src/scripts/known_good.json") 72 try: 73 with open(filename) as fp: 74 data = json.load(fp, object_hook=lambda x: types.SimpleNamespace(**x)) 75 except FileNotFoundError: 76 return [] 77 78 lines = [] 79 for repo in data.repos: 80 # Skip repositories that are not needed on Linux (TODO: assumes linux target) 81 if hasattr(repo, "build_platforms") and repo.build_platforms != "linux": 82 continue 83 84 # Switch the URL to use git: and save the original protocol 85 parts = urllib.parse.urlparse(repo.url) 86 protocol = parts.scheme 87 parts = parts._replace(scheme="git") 88 url = urllib.parse.urlunparse(parts) 89 # Resolve the commit reference to a SHA 90 sha = resolve_commit(repo.url, repo.commit) 91 92 destsuffix = destination + "/" + repo.sub_dir 93 94 url += f";protocol={protocol};nobranch=1;destsuffix={destsuffix};rev={sha}" 95 lines.append(f" {url} \\") 96 return lines 97 98 99def main(): 100 pv = sys.argv[1] 101 basedir = sys.argv[2] 102 103 print(""" 104# 105# Generated by generate-srcuri.py, don't update manually") 106# 107 108RECIPE_UPGRADE_EXTRA_TASKS += "do_refresh_srcuri" 109 110python __anonymous() { 111 if d.getVar("PV") != "%s": 112 bb.warn("-sources.inc out of date, run refresh_srcuri task") 113} 114""" % (pv)) 115 116 print('SRC_URI += " \\') 117 lines = convert_fetch(basedir) 118 print("\n".join(lines)) 119 print('"') 120 121 #lines = convert_knowngood(sys.argv[1], "git/external/validation") 122 #if lines: 123 # print('SRC_URI += " \\') 124 # print("\n".join(lines)) 125 # print('"') 126 #else: 127 # print("# Re-run") 128 129 130if __name__ == "__main__": 131 main() 132