-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprepare_release.py
137 lines (118 loc) · 4.4 KB
/
prepare_release.py
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
#!/bin/env/python
"""Prepare a new release of the DC tools for Windows
This script performs the following steps:
- upgrade dclab, dcnum, dcoraid, and chipstream to the latest version
- determine the version of each of those packages
- modify the following files for the new release:
- CHANGELOG: add a new entry with today's date
- requirements.txt: update the version pins for all packages
"""
import importlib
import pathlib
from pprint import pprint
import re
import subprocess as sp
import sys
import time
here = pathlib.Path(__file__).parent
def get_import_name(pkg):
if pkg == "scikit-image":
return "skimage"
return pkg.split("[")[0]
def get_packages():
"""read packages from requirements.txt"""
data = (here / 'requirements.txt').read_text().split('\n')
packages = []
packages_pinned = []
for line in data:
pkg = line.split("==")[0].strip()
if line.count("# no-upgrade"):
packages_pinned.append(line.split("#")[0].strip())
elif line.strip():
packages.append(pkg)
return packages, packages_pinned
def get_package_versions(packages, packages_pinned):
"""get versions of packages currently installed"""
version_dict = {}
for pkg in packages:
mod = importlib.import_module(get_import_name(pkg))
version_dict[pkg] = mod.__version__.split("+")[0]
for pkgv in packages_pinned:
pk, ver = pkgv.split("==")
pmod = importlib.import_module(get_import_name(pk))
pver = pmod.__version__.split("+")[0]
if pver != ver:
raise ValueError(
f"Package {pk} should be {ver}, but is {pver}")
version_dict[pk] = f"{ver} # no-upgrade"
return version_dict
def upgrade_packages(packages, packages_pinned):
"""upgrade all packages to latest version (resolving dependencies)"""
print("Installing pins", packages_pinned)
sp.check_output("pip install " + " ".join(packages_pinned), shell=True)
print("Upgrading", packages)
sp.check_output("pip install --upgrade " + " ".join(packages), shell=True)
def write_changelog_entry(version_dict):
"""Add a new entry to CHANGELOG"""
# parse the changelog
data = (here / "CHANGELOG").read_text().split('\n')
versions = {}
idat = []
iver = ""
for line in data:
if line.startswith("-"):
if iver:
versions[iver] = idat
idat = []
# set new version identifier
iver = line.strip(" -")
elif line:
# version data
idat.append(line)
else:
if iver:
# the final version
versions[iver] = idat
# add the latest version (replacing anything we did today)
nver = time.strftime("%Y.%m.%d")
ndat = [f" - Python {write_python_version()}"]
for key in sorted(version_dict.keys()):
pver = version_dict[key].split("#")[0].strip()
ndat.append(f" - {key} {pver}")
versions[nver] = ndat
# write everything to CHANGELOG
text = []
for vv in sorted(versions.keys())[::-1]:
text.append(f"- {vv}")
text += versions[vv]
(here / "CHANGELOG").write_text("\n".join(text))
def write_python_version():
# passive version file
pv = ".".join(f"{v}" for v in sys.version_info[:2])
(here / "python_version.txt").write_text(pv)
# tagged with "# PYTHON VERSION" in github workflows
pvmatch = re.compile('.*"([0-9]\.[0-9]*)".*# PYTHON VERSION')
# github actions
for pp in (here / ".github" / "workflows").glob("*.yml"):
data = pp.read_text().split("\n")
for ii, line in enumerate(data):
for oldver in re.findall(pvmatch, line):
if oldver != pv:
print(f"Updating Python {oldver} -> {pv} in {pp}")
data[ii] = line.replace(oldver, pv)
pp.write_text("\n".join(data))
return pv
def write_package_pins(version_dict):
"""write package pins to requirements.txt"""
text = []
for pkg in version_dict:
text.append(pkg + "==" + version_dict[pkg])
(here / 'requirements.txt').write_text("\n".join(text))
if __name__ == "__main__":
packages, packages_pinned = get_packages()
upgrade_packages(packages, packages_pinned)
version_dict = get_package_versions(packages, packages_pinned)
print("New versions:")
pprint(version_dict)
write_package_pins(version_dict)
write_changelog_entry(version_dict)