@PYTHON@ # vim: ts=4 et: import os import re import argparse import textwrap from datetime import datetime from collections import defaultdict from distutils.version import StrictVersion import yaml def find_repo_root(): path = os.getcwd() while ".git" not in set(os.listdir(path)) and path != "/": path = os.path.dirname(path) if path == "/": raise Exception("No repo found, stopping at /") return path class ReleaseReadmeUpdater: SECTION_TPL = textwrap.dedent(""" ### Alpine Linux {release} ({date})
click to show/hide

{rows}

""") AMI_TPL = ( " [{id}](https://{r}.console.aws.amazon.com/ec2/home" "#Images:visibility=public-images;imageId={id}) " "([launch](https://{r}.console.aws.amazon.com/ec2/home" "#launchAmi={id})) |" ) def __init__(self, profile, archs=None): self.profile = profile self.archs = archs or ["x86_64", "aarch64"] def get_sorted_releases(self, release_data): sections = defaultdict(lambda: { "release": "", "built": {}, "name": {}, "ami": defaultdict(dict) }) for build, releases in release_data.items(): for release, amis in releases.items(): for name, info in amis.items(): arch = info["arch"] built = info["build_time"] ver = sections[info["version"]] if arch not in ver["built"] or ver["built"][arch] < built: ver["release"] = release ver["name"][arch] = name ver["built"][arch] = built for region, ami in info["artifacts"].items(): ver["ami"][region][arch] = ami extract_ver = lambda x: StrictVersion( "0.0" if x["release"] == "edge" else x["release"]) return sorted(sections.values(), key=extract_ver, reverse=True) def make_ami_list(self, sorted_releases): ami_list = "## AMIs\n" for info in sorted_releases: rows = ["| Region |", "| ------ |"] for arch in self.archs: if arch in info["name"]: rows[0] += f" {info['name'][arch]} |" rows[1] += " --- |" for region, amis in info["ami"].items(): row = f"| {region} |" for arch in self.archs: if arch in amis: row += self.AMI_TPL.format(r=region, id=amis[arch]) rows.append(row) ami_list += self.SECTION_TPL.format( release=info["release"].capitalize(), date=datetime.utcfromtimestamp( max(info["built"].values())).date(), rows="\n".join(rows)) return ami_list def update_markdown(self): release_dir = os.path.join(find_repo_root(), "releases") profile_file = os.path.join(release_dir, f"{self.profile}.yaml") with open(profile_file, "r") as data: sorted_releases = self.get_sorted_releases(yaml.safe_load(data)) readme_md = os.path.join(release_dir, "README.md") with open(readme_md, "r") as file: readme = file.read() with open(readme_md, "w") as file: file.write( re.sub("## AMIs.*\Z", self.make_ami_list(sorted_releases), readme, flags=re.S)) def main(): parser = argparse.ArgumentParser(description="Update release README") parser.add_argument("profile", help="name of profile to update") args = parser.parse_args() ReleaseReadmeUpdater(args.profile).update_markdown() if __name__ == "__main__": main()