-
Notifications
You must be signed in to change notification settings - Fork 7
/
publish.py
144 lines (105 loc) · 4.48 KB
/
publish.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
138
139
140
141
142
143
144
from __future__ import annotations
import json
import os
import re
import shutil
import subprocess
from pathlib import Path
from urllib.request import urlopen
from natsort import natsorted
MVN_BASE_URL = "https://search.maven.org"
MVN_CENTRAL_BASE_URL = "https://central.sonatype.com"
def convert_pre_release_version(version: str) -> str:
pattern = re.compile(r"(?P<ver>\d+\.\d+\.\d+)-(?P<stage>[ab])(?:lpha|eta)(?P<revision>\d*)$")
if not (m := pattern.match(version)):
return version
if not (ver := m["ver"]):
return version
if not (stage := m["stage"]):
return version
revision = m["revision"] or 0
return pattern.sub(f"{ver}{stage}{revision}", version, count=1)
def download_openapi_generator_jar(version: str) -> None:
download_url = (
MVN_BASE_URL
+ "/remotecontent?filepath=org/openapitools/openapi-generator-cli"
+ f"/{version}/openapi-generator-cli-{version}.jar"
)
Path("openapi-generator.jar").unlink(missing_ok=True)
print(f"[{version}] URL: {download_url!r}")
response = urlopen(download_url) # noqa: S310
if response.status != 200: # noqa: PLR2004
msg = f"{response.status}: {download_url}"
raise RuntimeError(msg)
with Path("openapi_generator_cli/openapi-generator.jar").open("wb") as openapi_generator_jar:
openapi_generator_jar.write(response.read())
openapi_generator_jar.close()
def get_available_versions() -> set[str]:
rows = 200
versions: list[str] = []
for page_index, _ in enumerate(iter(int, 1)): # 0..Inf
mvn_url = (
MVN_CENTRAL_BASE_URL
+ "/solrsearch/select?q=g:org.openapitools+AND+a:openapi-generator-cli&core=gav&format=json"
f"&start={page_index}&rows={rows}"
)
response = urlopen(mvn_url) # noqa: S310
docs = json.loads(response.read())["response"]["docs"]
if len(docs) == 0:
break
versions.extend(convert_pre_release_version(doc["v"]) for doc in docs)
return set(versions)
def get_published_vesions() -> set[str]:
pypi_url = "https://pypi.org/pypi/openapi-generator-cli/json"
response = urlopen(pypi_url) # noqa: S310
if response.status != 200: # noqa: PLR2004
msg = f"{response.status}: {pypi_url}"
raise RuntimeError(msg)
published_releases = json.loads(response.read()).get("releases")
if not isinstance(published_releases, dict):
msg = f"Expected dict, got {type(published_releases)}"
raise TypeError(msg)
return set(published_releases.keys())
def update_package_version(version: str) -> None:
updated_toml = re.sub(
r'(?<=\[tool.poetry\]\nversion = ")[^"]+(?=")',
version,
Path("pyproject.toml").open("r").read(), # noqa: SIM115
count=1,
flags=(re.MULTILINE),
)
with Path("pyproject.toml").open("w") as toml:
toml.write(updated_toml)
def download_latest_jar_for_test() -> None:
latest_version = natsorted(get_available_versions())[-1]
print(f"[{latest_version}] Downloading...")
download_openapi_generator_jar(latest_version)
print(f"[{latest_version}] Downloaded!")
def publish(*, dryrun: bool = False) -> None:
pytest_path = shutil.which("pytest")
poetry_path = shutil.which("poetry")
unpublished_versions = natsorted(get_available_versions() - get_published_vesions())
if len(unpublished_versions) == 0:
print("[!] Nothing to be released.")
return
for publishing_version in unpublished_versions:
print(f"[{publishing_version}] Downloading...")
download_openapi_generator_jar(publishing_version)
print(f"[{publishing_version}] Updating package version...")
update_package_version(publishing_version)
print(f"[{publishing_version}] Testing...")
subprocess.check_call([pytest_path])
if dryrun:
continue
print(f"[{publishing_version}] Building...")
subprocess.check_call([poetry_path, "build", "-v"])
print(f"[{publishing_version}] Publishing to TestPyPI...")
subprocess.check_call([poetry_path, "publish", "-r", "testpypi", "-v"])
print(f"[{publishing_version}] Publishing to PyPI...")
subprocess.check_call([poetry_path, "publish", "-v"])
print(f"[{publishing_version}] Published!")
if __name__ == "__main__":
if os.getenv("DOWNLOAD_LATEST_ONLY") == "1":
download_latest_jar_for_test()
else:
publish(dryrun=os.getenv("DRYRUN") == "1")