Skip to content

Commit

Permalink
resources: add various util python scripts
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Stewart <christian@aperture.us>
  • Loading branch information
paralin committed Dec 3, 2024
1 parent 7cda2f0 commit a8420dc
Show file tree
Hide file tree
Showing 5 changed files with 443 additions and 0 deletions.
57 changes: 57 additions & 0 deletions resources/utils/buildroot-commitmsg-go.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!env python3
import os
import re
import requests
import subprocess
from bs4 import BeautifulSoup

# Step 0: switch to root of repo
git_root = subprocess.check_output(
['git', 'rev-parse', '--show-toplevel'],
universal_newlines=True
).strip()
os.chdir(git_root)

# Step 1: Determine the Go version from the file `./package/go/go.mk`
go_version = None
with open('./package/go/go.mk', 'r') as file:
for line in file:
match = re.match(r'^GO_VERSION\s*=\s*(\S+)', line)
if match:
go_version = match.group(1)
break

if not go_version:
print("Go version not found in go.mk file.")
exit(1)

# Step 2: Download the latest version release description page
url = 'https://go.dev/doc/devel/release'
response = requests.get(url)
if response.status_code != 200:
print("Failed to download release description page.")
exit(1)

# Step 3: Extract the version description for the current Go version
soup = BeautifulSoup(response.text, 'html.parser')
version_div = soup.find(id = f'go{go_version}')
if not version_div:
print(f"Version description for Go {go_version} not found.")
exit(1)
version_description = ' '.join(version_div.text.split())
version_description = re.sub(f'See the Go {go_version} milestone on our issue tracker for details\.', '', version_description)
version_description = version_description.strip()

# Step 4: Write the commit message following the format shown above
# commit_message = f"""package/go: security bump to version {go_version}
commit_message = f"""package/go: bump to version {go_version}
{version_description}
https://go.dev/doc/devel/release#go{go_version}
https://github.com/golang/go/issues?q=milestone%3AGo{go_version}+label%3ACherryPickApproved
Signed-off-by: Christian Stewart <christian@aperture.us>
"""

print(commit_message.strip())
33 changes: 33 additions & 0 deletions resources/utils/buildroot-reformat-gocve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!env python3
import sys
import re
import pyperclip

def reformat_vulnerabilities(input_data):
cve_pattern = r"This is (CVE-\d{4}-\d+)"
title_pattern = r"^\s*(.+):\s+(.+)$"

cve_list = []
titles = []

for line in input_data.splitlines():
cve_match = re.search(cve_pattern, line)
title_match = re.search(title_pattern, line)

if cve_match:
cve_list.append(cve_match.group(1))
elif title_match:
titles.append(title_match.group(1) + ": " + title_match.group(2))

reformatted = []
for cve, title in zip(cve_list, titles):
reformatted.append(f"{cve}: {title}")

return "\n".join(reformatted)

if __name__ == "__main__":
# input_data = sys.stdin.read()
input_data = pyperclip.paste()
reformatted_data = reformat_vulnerabilities(input_data)
print(reformatted_data)

102 changes: 102 additions & 0 deletions resources/utils/buildroot-update-go.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!env python3
import json
import sys
import requests
import re
import os

use_version = ""
if len(sys.argv) > 1:
use_version = sys.argv[1]
print(f"Using version from command line: {use_version}")

# Get the latest Go version and its hash
print("Downloading Go version information...")
url = "https://go.dev/dl/?mode=json"
response = requests.get(url)
data = json.loads(response.text)

if use_version:
selected_version = next((item for item in data if item["version"] == use_version), None)
if selected_version:
print(f"Using specified version: {use_version}")
version_info = selected_version
else:
print(f"Error: Specified version {use_version} not found.")
sys.exit(1)
else:
version_info = data[0]
print(f"Using latest version: {version_info['version']}")

selected_version = version_info["version"]
src_file = [f for f in version_info["files"] if f["kind"] == "source"][0]
selected_hash = src_file["sha256"]

print(f"Selected version is {selected_version}")

# Update go.mk
go_mk_path = "package/go/go.mk"
with open(go_mk_path, "r") as file:
go_mk_content = file.read()

selected_version_br = selected_version.lstrip('go')
go_mk_content = re.sub(r"GO_VERSION = .+", f"GO_VERSION = {selected_version_br}", go_mk_content)

with open(go_mk_path, "w") as file:
file.write(go_mk_content)

# Update go.hash
go_hash_path = "package/go/go-src/go-src.hash"
with open(go_hash_path, "r") as file:
go_hash_content = file.read()

go_hash_content = re.sub(r"sha256\s+\w+\s+go\d+\.\d+(\.\d+)?\.src\.tar\.gz",
f"sha256 {selected_hash} {src_file['filename']}", go_hash_content)

with open(go_hash_path, "w") as file:
file.write(go_hash_content)

print(f"Updated {go_hash_path} with Go version: {selected_version}")

# Update go-bin.hash
go_bin_hash_path = "package/go/go-bin/go-bin.hash"
with open(go_bin_hash_path, "r") as file:
go_bin_hash_lines = file.readlines()

updated_go_bin_hash_lines = []
for line in go_bin_hash_lines:
if line.strip().startswith('sha256') and 'LICENSE' not in line:
parts = line.strip().split()
if len(parts) >= 3:
old_hash = parts[1]
old_filename = parts[2]

# Extract old version from filename
old_version_pattern = r'go\d+\.\d+(\.\d+)?'
match = re.search(old_version_pattern, old_filename)
if match:
old_version_str = match.group()
new_filename = old_filename.replace(old_version_str, selected_version)

# Find the corresponding file in version_info
file_entry = next((f for f in version_info["files"] if f["filename"] == new_filename), None)
if file_entry:
new_hash = file_entry["sha256"]
updated_line = f"sha256 {new_hash} {new_filename}\n"
else:
print(f"Error: File {new_filename} not found in version info.")
sys.exit(1)
else:
print(f"Error: Could not extract version from filename {old_filename}")
sys.exit(1)
else:
updated_line = line
else:
updated_line = line
updated_go_bin_hash_lines.append(updated_line)

with open(go_bin_hash_path, "w") as file:
file.writelines(updated_go_bin_hash_lines)

print(f"Updated {go_bin_hash_path} with Go version: {selected_version}")
print("Buildroot files updated successfully.")
153 changes: 153 additions & 0 deletions resources/utils/buildroot-update-pkg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#!env python3

import os
import re
import sys
import requests
import subprocess
from github import Github


def drop_version_prefix(site, version):
version_pattern = re.compile(r"\(call (.+),(.+),(.+),(.+)\)")
version_match = version_pattern.search(site)
old_version_dl = version_match.group(4)

# if we add a "v" prefix to the download filename, strip it from VERSION
if old_version_dl.startswith("v") and version.startswith("v"):
version = version[1:]

return version

def add_version_prefix(site, version):
version_pattern = re.compile(r"\(call (.+),(.+),(.+),(.+)\)")
version_match = version_pattern.search(site)
old_version_dl = version_match.group(4)

# if we add a "v" prefix to the download filename, strip it from VERSION
if old_version_dl.startswith("v") and not version.startswith("v"):
version = "v" + version

return version

def get_package_info(package_name):
mk_path = f"./package/{package_name}/{package_name}.mk"
with open(mk_path, "r") as mk_file:
mk_content = mk_file.read()
package_name_upper = package_name.upper().replace("-", "_")
version_pattern = re.compile(rf"{package_name_upper}_VERSION\s*=\s*(.+)")
site_pattern = re.compile(rf"{package_name_upper}_SITE\s*=\s*(.+)")

version = version_pattern.search(mk_content).group(1)
site = site_pattern.search(mk_content).group(1)
version = add_version_prefix(site, version)

return version, site


def get_latest_version(site, force_version=None):
github_pattern = re.compile(r"call github,(.+),(.+),")
github_match = github_pattern.search(site)
if not github_match:
print("This script only works on GitHub packages.")
os.exit(1)

github_repo = github_match.group(1) + "/" + github_match.group(2)

latest_version = force_version
if not latest_version:
gh = Github()
repo = gh.get_repo(github_repo)
latest_release = repo.get_latest_release()
latest_version = latest_release.tag_name

return github_repo, latest_version


def update_mk_file(package_name, site, new_version):
mk_path = f"./package/{package_name}/{package_name}.mk"
package_name_upper = package_name.upper().replace("-", "_")
with open(mk_path, "r") as mk_file:
mk_content = mk_file.read()

new_version = drop_version_prefix(site, new_version)
site_pattern = re.compile(rf"{package_name_upper}_SITE\s*=\s*(.+)")
site = site_pattern.search(mk_content).group(1)

version_pattern = re.compile(
rf"{package_name.upper().replace('-', '_')}_VERSION\s*=\s*(.+)"
)
new_mk_content = version_pattern.sub(
rf"{package_name.upper().replace('-', '_')}_VERSION = {new_version}", mk_content
)

with open(mk_path, "w") as mk_file:
mk_file.write(new_mk_content)


def download_and_update_hash(package_name, site, github_repo, new_version):
hash_path = f"./package/{package_name}/{package_name}.hash"
with open(hash_path, "r") as hash_file:
hash_content = hash_file.read()

new_version = drop_version_prefix(site, new_version)
tar_path = f"dl/{package_name}/{package_name}-{new_version}.tar.gz"

tar_dir = os.path.dirname(tar_path)
if not os.path.exists(tar_dir):
os.makedirs(tar_dir)

# tar_url = f"https://github.com/{github_repo}/archive/refs/tags/{new_version}.tar.gz"
tar_url = f"https://github.com/{github_repo}/archive/v{new_version}/{package_name}-{new_version}.tar.gz"
tar_file = requests.get(tar_url)
with open(tar_path, "wb") as f:
f.write(tar_file.content)

sha256_hash = os.popen(f"sha256sum {tar_path}").read().split()[0]

# os.remove(f"{package_name}-{new_version}.tar.gz")

hash_pattern = re.compile(r"sha256\s+(\w+)\s+" + package_name + r"-(.+?).tar.gz")
new_hash_content = hash_pattern.sub(
rf"sha256 {sha256_hash} {package_name}-{new_version}.tar.gz", hash_content
)

with open(hash_path, "w") as hash_file:
hash_file.write(new_hash_content)


if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python update_buildroot_package.py <package_name>")
sys.exit(1)

package_name = sys.argv[1]
force_version = None
if len(sys.argv) >= 3:
force_version = sys.argv[2]

current_version, site = get_package_info(package_name)
print(f"Package version: {current_version}")
print(f"Package site: {site}")

github_repo, latest_version = get_latest_version(site, force_version)
print(f"Looked up latest version: {latest_version}")

if current_version == latest_version:
print(
f"The package {package_name} is already at the latest version {latest_version}."
)
else:
print(
f"Updating {package_name} from version {current_version} to {latest_version}..."
)

# Step 8: Edit the mk file to update the version number
update_mk_file(package_name, site, latest_version)

# Step 9: Update the hash line in the hash file
download_and_update_hash(package_name, site, github_repo, latest_version)

print(f"Successfully updated {package_name} to version {latest_version}.")

print(f"https://github.com/{github_repo}/releases/tag/{latest_version}")
Loading

0 comments on commit a8420dc

Please sign in to comment.