#!/usr/bin/python3 import argparse,os,git,re,semver folder = "install" p = re.compile('^((.{1,2}) )?(.+): (.+)$') def parse_version(v): v = v.removeprefix("v").split(".") pre = None if len(v) > 3: pre = v[3] return semver.Version(major=v[0], minor=v[1], patch=v[2], prerelease=pre) def parse_rule(rule): m = p.match(rule) op = m.group(2) if op is None: op = '<=' v = m.group(3) ref = m.group(4) return op, v, ref def get_rev(discourse_version, rules, kept_rev): rule = next(rules, None) if rule is None: return kept_rev op, v, rev = parse_rule(rule) version = parse_version(v) r = discourse_version.compare(version) if r == 1 or (r == 0 and op == "<"): return kept_rev return get_rev(discourse_version, rules, rev) def get_rules(repo): try: blob = repo.head.commit.tree[".discourse-compatibility"] except: return iter([]) rules = [ line.decode() for line in blob.data_stream.read().splitlines() ] return iter(rules) def main(args): discourse_version = parse_version(args.version) print("Updating plugins for Discourse %s" % discourse_version) for d in os.listdir(folder): try: repo = git.Repo(folder + "/" + d) repo.remotes.origin.pull() rules = get_rules(repo) ref = get_rev(discourse_version, rules, repo.head.commit.hexsha) repo.head.reset(commit=ref, working_tree=True) log = d.ljust(40) + ref repo.active_branch if ref == repo.remotes.origin.refs.HEAD.commit.hexsha: log += " (head)" print(log) except Exception as e: print(d.ljust(40)+"failed") print(e) exit(1) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Helper script to manage Discourse plugins.') parser.add_argument("version") args = parser.parse_args() main(args)