forked from albertlauncher/albert
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetatool
executable file
·158 lines (113 loc) · 5.97 KB
/
metatool
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#! /usr/bin/env python3
import re
import sys
import argparse
import datetime
import tempfile
from pathlib import Path
from subprocess import run
def create_changelog(args) -> str:
plugins_root = f"{args.root}/plugins"
modules_root = f"{args.root}/plugins/python/share/modules"
latest = run(["git", "describe", "--tags", "--abbrev=0"], capture_output=True).stdout.decode().strip()
albert_log = run(["git", "log", "--pretty=format:* %B", f"{latest}..dev"], capture_output=True).stdout.decode().strip()
begin = run(["git", "ls-tree", latest, plugins_root], capture_output=True).stdout.decode().strip().split()[2]
plugin_log = run(["git", "-C", plugins_root, "log", "--pretty=format:* %B", f"{begin}..master"], capture_output=True).stdout.decode().strip()
begin = run(["git", "-C", plugins_root, "ls-tree", begin, modules_root], capture_output=True).stdout.decode().strip().split()[2]
python_log = run(["git", "-C", modules_root, "log", "--pretty=format:* %B", f"{begin}..master"], capture_output=True).stdout.decode().strip()
return f"[albert]\n{albert_log}\n\n[plugins]\n{plugin_log}\n\n[python]\n{python_log}"
def test_build(args):
files = list((Path(args.root) / ".docker").iterdir())
for i, f in enumerate(files):
print(f"{i}: {f.name}")
default = list(range(len(files)))
indices = input(f"Which to build? [{' '.join(str(i) for i in default)}] ")
indices = [int(s) for s in filter(None, indices.split())]
indices = indices if indices else default
for index in indices:
tag = files[index].name.replace("Dockerfile", "albert")
run(["docker", "build", "-t", tag, "-f", files[index], "."], cwd=args.root).check_returncode()
def release(args):
root = Path(args.root)
if args.version[0] == 'v':
args.version = args.version[1:]
import re
if not re.match(r"^[0-9]+\.[0-9]+\.[0-9]+$", args.version):
print("Expected version number as parameter: major.minor.patch")
sys.exit(1)
print("Don't forget to merge ready PRs.")
print("Don't forget to updated the 'python' submodule in the Python plugin.")
print("Don't forget to updated the 'plugins' submodule.")
if "y".startswith(input("Shall I run a test build in docker? [Y/n] ").lower()):
test_build(args)
v = input("Confirm the version number: ")
if args.version != (v[1:] if v[0] == 'v' else v):
print("Version mismatch.")
sys.exit(1)
atomic_changelog = root/f"changelog_v{args.version}"
with open(atomic_changelog, 'w') as file:
file.write(create_changelog(args))
print("Changelog created from git logs. Edit it to be meaningful to humans.")
input("Press Enter to continue...")
run(["vim", atomic_changelog]).check_returncode()
with open(atomic_changelog, 'r') as file:
changelog = file.read().strip()
if "y".startswith(input("Create news post? [Y/n] ").lower()):
if (root/"documentation").exists():
run(["git", "pull"], cwd=root/"documentation").check_returncode()
else:
run(["git", "clone", "git://github.com/albertlauncher/documentation.git"], cwd=root).check_returncode()
with open(f"documentation/src/_posts/{datetime.date.today().strftime('%Y-%m-%d')}-albert-v{args.version}-released.md", 'w') as file:
file.write(f"""---
layout: page
title: "Albert v{args.version} released"
date: {datetime.datetime.now().strftime("%Y-%m-%d %H:%M%z")}
---
{changelog.strip()}
Check the GitHub repositories for details.
https://github.com/albertlauncher/albert/commits/v{args.version}
""")
if "y".startswith(input("News post created. Build/Test/Publish it? [Y/n] ").lower()):
run("./build_check_deploy.sh", cwd=root/"documentation").check_returncode()
if "y".startswith(input("Update the changelog? [Y/n] ").lower()):
with open(root/"CHANGELOG.md", 'r') as file:
old_changelog = file.read()
with open(root/"CHANGELOG.md", 'w') as file:
file.write(f"v{args.version} ({datetime.date.today().strftime('%Y-%m-%d')})\n\n{changelog}\n\n{old_changelog}")
print("Changelog updated.")
run(["sed", "-i.bak", f"s/^project.*$/project(albert VERSION {args.version})/", root/"CMakeLists.txt"], cwd=root).check_returncode()
print("Project version updated.")
if "yes".startswith(input("Stage, commit, tag, rebase master and push? [yes/NO]").lower()):
run(["git", "add", root/"CHANGELOG.md", root/"CMakeLists.txt"], cwd=root).check_returncode()
run(["git", "commit", "-m", f"v{args.version}"], cwd=root).check_returncode()
run(["git", "tag", f"v{args.version}"], cwd=root).check_returncode()
run(["git", "rebase", "dev", "master"], cwd=root).check_returncode()
run(["git", "push", "--tags", "--atomic", "origin", "dev", "master"], cwd=root).check_returncode()
print("Clean up…")
run(["rm", atomic_changelog])
run(["rm", "CMakeLists.txt.bak"])
def main():
p = argparse.ArgumentParser()
sps = p.add_subparsers()
sp = sps.add_parser('changelog', help='Create raw changelog.')
sp.set_defaults(func=lambda args: print(create_changelog(args)))
sp = sps.add_parser('test', help='Test build using docker.')
sp.set_defaults(func=test_build)
sp = sps.add_parser('release', help="Release a new version.")
sp.add_argument('version', type=str, help="The sematic version.")
sp.set_defaults(func=release)
args = p.parse_args()
if not hasattr(args, "func"):
p.print_help()
sys.exit(1)
sha = run(["git", "rev-list", "--parents", "HEAD"], capture_output=True).stdout.decode().strip().split("\n")[-1]
if sha != '4d409110b9771e688acbb995422541f03ef0d8a7':
print("Working dir is not the albert repository")
sys.exit(1)
args.root = run(["git", "rev-parse", "--show-toplevel"], capture_output=True).stdout.decode().strip()
try:
args.func(args)
except KeyboardInterrupt:
print("\nBye.")
if __name__ == "__main__":
main()