| # Copyright 2022 Google LLC |
| # |
| # This program is free software; you can redistribute it and/or |
| # modify it under the terms of the GNU General Public License |
| # version 2 as published by the Free Software Foundation. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| |
| # This script is used to find go dependencies |
| # of a go pacakge. It reads 'go.mod', 'vendor.mod' |
| # or 'vendor.conf' in the source code. |
| |
| import os |
| import re |
| import subprocess |
| import tarfile |
| import requests |
| |
| # REGEX_GO_MOD_DEP finds |
| # `require ( |
| # go-pkg1 v1.2.3 |
| # go-pkg2 v4.5.6 ... |
| # )` in go.mod or other mod file. |
| REGEX_GO_MOD_DEP = "require \((.*?)\)" |
| GO_MOD_DEP_FILE = ["go.mod", "vendor.mod", "vendor.conf"] |
| |
| |
| def download_src_code(url, build_info_dir): |
| filepath = os.path.join(build_info_dir, os.path.basename(url)) |
| if url.startswith("gs://"): |
| subprocess.run(["gsutil", "cp", url, filepath]) |
| else: |
| if url.startswith("https://github.com"): |
| url = f'{url.replace("@","/archive/")}.tar.gz' |
| else: |
| url = f'{url.replace("@","/+archive/").replace("#","/")}.tar.gz' |
| response = requests.get(url) |
| open(filepath, "wb").write(response.content) |
| return filepath |
| |
| |
| def get_go_dep(download_url, build_info_dir): |
| res = set() |
| for url in download_url.split(","): |
| if url.endswith(".gn"): |
| continue |
| filepath = download_src_code(url, build_info_dir) |
| try: |
| t = tarfile.open(filepath, "r:gz") |
| for filename in t.getnames(): |
| if os.path.basename(filename) not in GO_MOD_DEP_FILE: |
| continue |
| f = t.extractfile(filename) |
| content = f.read() |
| match = re.findall(REGEX_GO_MOD_DEP, content.decode("utf-8"), re.DOTALL) |
| for req in match: |
| deps = req.strip().split("\n") |
| for dep in deps: |
| # remove comments. |
| dep = dep.split("//")[0].strip() |
| if dep: |
| res.add(dep) |
| except: |
| print(f"{url} is not a .gz file.") |
| os.remove(filepath) |
| return ",".join(res) |