summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Hartmann <sultan@gentoo.org>2022-05-06 11:54:02 +0200
committerStephan Hartmann <sultan@gentoo.org>2022-05-06 11:55:51 +0200
commiteb9734c60aff0ea27cf030a88b4779ae613f88dd (patch)
treeb17ab19a48fbf3270c3342b2e0abfbfc511e7936
parentRename bump_chrome.py to chrome-bump (diff)
downloadchromium-tools-eb9734c60aff0ea27cf030a88b4779ae613f88dd.tar.gz
chromium-tools-eb9734c60aff0ea27cf030a88b4779ae613f88dd.tar.bz2
chromium-tools-eb9734c60aff0ea27cf030a88b4779ae613f88dd.zip
Add opera-bump script
Signed-off-by: Stephan Hartmann <sultan@gentoo.org>
-rwxr-xr-xopera-bump397
1 files changed, 397 insertions, 0 deletions
diff --git a/opera-bump b/opera-bump
new file mode 100755
index 0000000..c1e3c46
--- /dev/null
+++ b/opera-bump
@@ -0,0 +1,397 @@
+#!/bin/env python3
+
+import argparse
+import json
+import os
+import shutil
+import sys
+import urllib.request
+import subprocess
+import functools
+import operator
+
+from bs4 import BeautifulSoup
+from debian import deb822
+from contextlib import closing
+
+from portage.dbapi.porttree import portdbapi
+from portage.versions import *
+from portage.package.ebuild import digestgen, config
+from portage.output import EOutput
+
+from git import Repo
+
+pkg_data = \
+{
+ "stable" :
+ {
+ "pkg" : "opera",
+ "suffix" : "stable",
+ "version" : [],
+ "dversion" : [],
+ "bversion" : [],
+ "stable" : True,
+ "count" : 1
+ },
+ "beta" :
+ {
+ "pkg" : "opera-beta",
+ "suffix" : None,
+ "version" : [],
+ "dversion" : [],
+ "bversion" : [],
+ "stable" : False,
+ "count" : 3
+ },
+ "dev" :
+ {
+ "pkg" : "opera-developer",
+ "suffix" : None,
+ "version" : [],
+ "dversion" : [],
+ "bversion" : [],
+ "stable" : False,
+ "count" : 3
+ }
+}
+
+def getOperaVersionInfo(base_url, archive, arch, version):
+ if not base_url.endswith("/"):
+ url = base_url + "/"
+ url += f"{version}/linux"
+ try:
+ req = urllib.request.urlopen(url)
+ except urllib.error.HTTPError:
+ return None
+ soup = BeautifulSoup(req, "html.parser")
+ base_fn = f"{archive}_{version}_{arch}."
+ rpm = False
+ for node in soup.find_all("a"):
+ v = node.get("href")
+ if v.startswith(base_fn):
+ if v.endswith("rpm"):
+ rpm = True
+ elif v.endswith("deb"):
+ return (version, "0", "deb")
+ if rpm:
+ return (version, "0", "rpm")
+ return None
+
+def getOperaVersionData(base_url, package, archive, arch, tversion,
+ platform=None):
+ if not base_url.endswith("/"):
+ url = base_url + "/"
+ url += package
+ if platform is not None:
+ url += f"/{platform}"
+
+ req = urllib.request.urlopen(url)
+ soup = BeautifulSoup(req, "html.parser")
+ versions = []
+ for node in soup.find_all("a"):
+ v = node.get("href")
+ if v.endswith("/"):
+ v = v[:-1]
+ if v != "..":
+ check = False
+ for tver in tversion:
+ c = vercmp(v, tver[0])
+ if c is not None and c >= 0:
+ check = True
+ if check:
+ ver = getOperaVersionInfo(base_url=url,
+ archive=archive,
+ arch=arch,
+ version=v)
+ if ver is not None:
+ versions.append(ver)
+ return versions
+
+def compareOperaVersion(item1, item2):
+ return -vercmp(item1[0], item2[0])
+
+def isMajorBump(channel, uversion, tversion):
+ uv_list = uversion.split(".")
+ tv_list = tversion.split(".")
+ if ( int(uv_list[0]) > int(tv_list[0]) and
+ getPrevChannel(channel=channel) != channel ):
+ return True
+ return False
+
+def getPrevChannel(channel):
+ channels = list(pkg_data.keys())
+ channel_list = channels + [channels[len(channels) - 1]]
+ for i in range(0, len(channel_list) - 1):
+ if channel_list[i] == channel:
+ return channel_list[i + 1]
+ raise ValueError(f"Unknown channel \"{channel}\".")
+
+def getEbuildVersion(version):
+ if version[1] == "r0":
+ return version[0]
+ return f"{version[0]}-{version[1]}"
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--dry-run", "-n", action="store_true")
+ args = parser.parse_args()
+
+ output = EOutput()
+
+ output.einfo("Looking up Opera versions information in tree ...")
+
+ db = portdbapi()
+ repo_path = db.getRepositoryPath(repository_id="gentoo")
+ for channel in pkg_data.keys():
+ pkg = pkg_data[channel]["pkg"]
+ cpvs = db.cp_list(mycp=f"www-client/{pkg}", mytree=repo_path)
+ for cpv in cpvs:
+ (cp, version, rev) = pkgsplit(mypkg=cpv)
+ pkg_data[channel]["version"].append((version,rev))
+ if len(pkg_data[channel]["version"]) == 0:
+ output.ewarn("Couldn't determine tree versions for "+
+ "www-client/{pkg}")
+ pkg_data[channel]["version"].sort(key=functools.cmp_to_key(compareOperaVersion))
+
+ opera_info = {}
+ for channel in pkg_data.keys():
+ archive = pkg_data[channel]["pkg"]
+ platform = None
+ if pkg_data[channel]["suffix"] is not None:
+ archive += "-" + pkg_data[channel]["suffix"]
+ platform = "desktop"
+ output.einfo(f"Fetching upstream version information \"{archive}\" ...")
+ versions = getOperaVersionData(base_url="https://download1.operacdn.com/pub",
+ package=pkg_data[channel]["pkg"],
+ archive=archive, arch="amd64",
+ tversion=pkg_data[channel]["version"],
+ platform=platform)
+ versions.sort(key=functools.cmp_to_key(compareOperaVersion))
+ opera_info[channel] = versions
+
+ output.einfo("Comparing Opera version informations ...")
+
+ for channel in pkg_data.keys():
+ versions = map(operator.itemgetter(0), opera_info[channel])
+ for ver in pkg_data[channel]["version"]:
+ if ver[0] not in versions:
+ output.ewarn("Upstream dropped version " +
+ f"{ver[0]} from channel " +
+ f"\"{channel}\" of www-client/" +
+ f"{pkg_data[channel]['pkg']}.")
+ pkg_data[channel]["dversion"].append(ver)
+
+ for channel in pkg_data.keys():
+ if len(opera_info[channel]) == 0:
+ output.ewarn(f"Upstream version unknown for channel \"{channel}\".")
+ else:
+ for uver in opera_info[channel]:
+ bump = None
+ for tver in pkg_data[channel]["version"]:
+ ver_info = vercmp(uver[0], getEbuildVersion(tver))
+ if ver_info is None:
+ output.ewarn("Cannot determine new version for " +
+ f"channel \"{channel}\" of " +
+ f"www-client/" +
+ f"{pkg_data[channel]['pkg']}.")
+ bump = False
+ break
+ elif ver_info > 0:
+ if bump is None:
+ bump = True
+ elif ver_info == 0:
+ bump = False
+ elif ver_info < 0:
+ bump = False
+ if bump:
+ pkg_data[channel]["bversion"].append((uver[0], "r0"))
+
+ if ( len(pkg_data[channel]["bversion"]) == 0 and
+ len(pkg_data[channel]["dversion"]) ==
+ len(pkg_data[channel]["version"]) ):
+ output.ewarn("Update would remove all versions " +
+ f"from tree for channel \"{channel}\" of " +
+ f"www-client/" +
+ f"{pkg_data[channel]['pkg']}.")
+ pkg_data[channel]["dversion"] = []
+ elif ( len(pkg_data[channel]["bversion"]) >=
+ pkg_data[channel]["count"] ):
+ count = pkg_data[channel]["count"]
+ pkg_data[channel]["bversion"] = \
+ pkg_data[channel]["bversion"][:count]
+ pkg_data[channel]["dversion"] = pkg_data[channel]["version"]
+ elif ( len(pkg_data[channel]["bversion"]) +
+ len(pkg_data[channel]["version"]) >
+ pkg_data[channel]["count"] ):
+ count = len(pkg_data[channel]["bversion"]) + \
+ len(pkg_data[channel]["version"]) - \
+ pkg_data[channel]["count"]
+ pkg_data[channel]["dversion"] = \
+ pkg_data[channel]["version"][-count:]
+
+ for channel in pkg_data.keys():
+ pkg = pkg_data[channel]["pkg"]
+ output.einfo(f"www-client/{pkg} version information:")
+ vstr = ""
+ for ver in reversed(pkg_data[channel]["version"]):
+ if ver in pkg_data[channel]["dversion"]:
+ vstr += f"({getEbuildVersion(ver)})\t"
+ else:
+ vstr += f"{getEbuildVersion(ver)}\t"
+ for ver in pkg_data[channel]["bversion"]:
+ vstr += f"{getEbuildVersion(ver)}*\t"
+ output.einfo(f"\t{channel}\t{vstr}")
+
+ if len(pkg_data[channel]["bversion"]) > 0:
+ output.einfo(f"\t\t==> bump")
+ elif len(pkg_data[channel]["dversion"]) > 0:
+ output.einfo(f"\t\t==> cleanup")
+ else:
+ output.einfo(f"\t\t==> unchanged")
+
+ if not args.dry_run:
+ repo = Repo(repo_path)
+ if repo.is_dirty():
+ output.eerror("Git Repository is dirty, can't continue.")
+ sys.exit(1)
+
+ index = repo.index
+
+ for channel in pkg_data.keys():
+ pkg = pkg_data[channel]["pkg"]
+ tver = pkg_data[channel]["version"][0]
+ tversion = getEbuildVersion(tver)
+ for uver in pkg_data[channel]["bversion"]:
+ uversion = getEbuildVersion(uver)
+ major_bump = isMajorBump(channel=channel,
+ uversion=uver[0],
+ tversion=tver[0])
+ output.einfo(f"Bumping www-client/{pkg}-{uversion} ...")
+ if major_bump:
+ prev_channel = getPrevChannel(channel=channel)
+ prev_pkg = pkg_data[prev_channel]["pkg"]
+ prev_version = getEbuildVersion(
+ pkg_data[prev_channel]["version"][0])
+ from_ebuild = os.path.join("www-client",
+ prev_pkg,
+ prev_pkg + "-" +
+ prev_version +
+ ".ebuild")
+ from_meta = os.path.join("www-client",
+ prev_pkg,
+ "metadata.xml")
+ to_meta = os.path.join("www-client",
+ pkg,
+ "metadata.xml")
+ else:
+ from_ebuild = os.path.join("www-client",
+ pkg,
+ pkg + "-" +
+ tversion +
+ ".ebuild")
+ to_ebuild = os.path.join("www-client",
+ pkg,
+ pkg + "-" +
+ uversion +
+ ".ebuild")
+
+ if args.dry_run:
+ print(f"cp {from_ebuild} {to_ebuild}")
+ if pkg_data[channel]["stable"]:
+ print(f"ekeyword ~amd64 {to_ebuild}")
+ print(f"git add {to_ebuild}")
+ if major_bump:
+ print(f"cp {from_meta} {to_meta}")
+ print(f"git add {to_meta}")
+ else:
+ to_ebuild = os.path.join(repo_path, to_ebuild)
+ from_ebuild = os.path.join(repo_path, from_ebuild)
+ shutil.copyfile(from_ebuild, to_ebuild)
+ if pkg_data[channel]["stable"]:
+ subprocess.check_call(["ekeyword", "~amd64", to_ebuild])
+ index.add(to_ebuild)
+ if major_bump:
+ to_meta = os.path.join(repo_path, to_meta)
+ from_meta = os.path.join(repo_path, from_meta)
+
+ if args.dry_run:
+ print(f"git add {os.path.join('www-client', pkg, 'Manifest')}")
+ print("git commit -m",
+ f"\"www-client/{pkg}: automated bump",
+ f"({uversion})",
+ "-s -S\"")
+ else:
+ to_path = os.path.dirname(to_ebuild)
+ cfg = config.config()
+ cfg["O"] = to_path
+
+ digestgen.digestgen(None, cfg, db)
+ index.add(os.path.join(to_path, "Manifest"))
+
+ repo.git.commit("-m",
+ f"www-client/{pkg}: automated bump ({uversion})",
+ "-s", "-S")
+
+ if pkg_data[channel]["stable"]:
+ for bver in pkg_data[channel]["bversion"]:
+ bversion = getEbuildVersion(bver)
+ output.einfo(f"Stabilizing www-client/{pkg}-{bversion} ...")
+ ebuild = os.path.join("www-client",
+ pkg,
+ pkg + "-" +
+ bversion +
+ ".ebuild")
+ if args.dry_run:
+ print(f"ekeyword amd64 {ebuild}")
+ print(f"git add {os.path.join('www-client', pkg, 'Manifest')}")
+ print("git commit -m",
+ f"\"www-client/{pkg}: amd64 stable ({bversion})\" -s -S")
+ else:
+ ebuild = os.path.join(repo_path, ebuild)
+ subprocess.check_call(["ekeyword", "amd64", ebuild])
+ index.add(ebuild)
+
+ to_path = os.path.dirname(ebuild)
+ cfg = config.config()
+ cfg["O"] = to_path
+
+ digestgen.digestgen(None, cfg, db)
+ index.add(os.path.join(to_path, "Manifest"))
+
+ repo.git.commit("-m",
+ f"www-client/{pkg}: amd64 stable ({bversion})",
+ "-s", "-S")
+
+ for dver in pkg_data[channel]["dversion"]:
+ dversion = getEbuildVersion(dver)
+ output.einfo(f"Removing www-client/{pkg}-{dversion} ...")
+ rm_ebuild = os.path.join("www-client",
+ pkg,
+ pkg + "-" +
+ dversion +
+ ".ebuild")
+ if args.dry_run:
+ print(f"git rm {os.path.relpath(rm_ebuild, repo_path)}")
+ else:
+ rm_ebuild = os.path.join(repo_path, rm_ebuild)
+ index.remove(rm_ebuild, working_tree=True)
+
+ if len(pkg_data[channel]["dversion"]) > 0:
+ if args.dry_run:
+ print(f"git add {os.path.join('www-client', pkg, 'Manifest')}")
+ print("git commit -m",
+ f"\"www-client/{pkg}: remove old\" -s -S")
+ else:
+ to_path = os.path.dirname(rm_ebuild)
+ cfg = config.config()
+ cfg["O"] = to_path
+
+ digestgen.digestgen(None, cfg, db)
+ index.add(os.path.join(to_path, "Manifest"))
+
+ repo.git.commit("-m",
+ f"www-client/{pkg}: remove old",
+ "-s", "-S")
+
+if __name__ == "__main__":
+ main()