Skip to content

Commit b239c4a

Browse files
committed
Add version bumping utility
This changes the release workflow for the moment. Now, new updates come in as rc0, and to make a release version, run `tox -e bump -- --release`. Until we gain confidence with smooth releases, it makes sense to start with release candidates and then bump to the full version as part of the release.
1 parent db9ecf8 commit b239c4a

File tree

7 files changed

+136
-5
lines changed

7 files changed

+136
-5
lines changed

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
recursive-include src/tzdata *
2+
include VERSION

VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2020.1rc0

bump_version.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import argparse
2+
import io
3+
import pathlib
4+
5+
import parver
6+
7+
REPO_ROOT = pathlib.Path(__file__).parent
8+
VERSION = REPO_ROOT / pathlib.Path("VERSION")
9+
10+
11+
def get_current_version() -> parver.Version:
12+
with open(VERSION, "rt") as f:
13+
return parver.Version.parse(f.read().strip())
14+
15+
16+
def write_version(version: parver.Version):
17+
with open(VERSION, "wt") as f:
18+
f.write(str(version))
19+
20+
21+
def update_package_version(version: parver.Version):
22+
new_init = io.StringIO()
23+
version_set = False
24+
init = REPO_ROOT / "src" / "tzdata" / "__init__.py"
25+
with open(init, "rt") as f:
26+
for line in f:
27+
if not version_set and line.startswith("__version__"):
28+
line = f'__version__ = "{version}"\n'
29+
version_set = True
30+
new_init.write(line)
31+
32+
if not version_set:
33+
raise ValueError("Version not found in __init__.py!")
34+
35+
new_init.seek(0)
36+
37+
with open(init, "wt") as f:
38+
f.write(new_init.read())
39+
40+
41+
def bump_version(version: parver.Version, args) -> parver.Version:
42+
if args.release:
43+
return version.base_version()
44+
45+
if args.dev:
46+
if args.to is not None:
47+
return version.replace(dev=args.to)
48+
else:
49+
return version.bump_dev()
50+
51+
version = version.replace(dev=None)
52+
53+
if args.post:
54+
if args.to is not None:
55+
return version.replace(post=args.to)
56+
else:
57+
return version.bump_post()
58+
59+
if args.rc:
60+
if version.is_postrelease:
61+
version = version.replace(post=None)
62+
63+
if args.to is not None:
64+
return version.replace(pre_tag="rc", pre=args.to)
65+
else:
66+
return version.bump_pre("rc")
67+
68+
69+
def main(args):
70+
original_version = get_current_version()
71+
bumped_version = bump_version(original_version, args)
72+
73+
print(f"{original_version}{bumped_version}")
74+
if not args.dry_run:
75+
write_version(bumped_version)
76+
update_package_version(bumped_version)
77+
78+
79+
if __name__ == "__main__":
80+
parser = argparse.ArgumentParser(description="Manipulate the package version")
81+
82+
group = parser.add_mutually_exclusive_group(required=True)
83+
84+
group.add_argument("--rc", action="store_true", help="Bump the release candidate")
85+
group.add_argument("--dev", action="store_true", help="Bump the dev version")
86+
group.add_argument(
87+
"--release",
88+
action="store_true",
89+
help="Bump from release candidate / dev to release",
90+
)
91+
group.add_argument(
92+
"--post", action="store_true", help="Bump the post release version"
93+
)
94+
parser.add_argument(
95+
"--to",
96+
type=int,
97+
default=None,
98+
help="Set the specified component to a specific number",
99+
)
100+
parser.add_argument(
101+
"--dry-run",
102+
action="store_true",
103+
help="Preview what the new version will be without writing any files.",
104+
)
105+
106+
args = parser.parse_args()
107+
108+
if args.to is not None and args.release:
109+
raise ValueError("Cannot combine --to and --release")
110+
111+
main(args)

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = tzdata
3-
version = attr:tzdata.__version__
3+
version = file: VERSION
44
description = Provider of IANA time zone data
55
long_description = file: README.rst
66
long_description_content_type = text/x-rst

src/tzdata/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# IANA versions like 2020a are not valid PEP 440 identifiers; the recommended
2-
# way to translate the version is to use YYYY.n where `n` is a 1-based index.
3-
__version__ = "2020.1"
2+
# way to translate the version is to use YYYY.n where `n` is a 0-based index.
3+
__version__ = "2020.1rc0"
44

55
# This exposes the original IANA version number.
66
IANA_VERSION = "2020a"

tox.ini

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,29 @@ skip_install = True
1818
deps =
1919
requests
2020
click
21+
parver
2122
commands =
2223
python update.py {posargs}
2324

25+
[testenv:bump]
26+
description = Bump the current package version
27+
skip_install = True
28+
deps =
29+
parver
30+
commands =
31+
python bump_version.py {posargs}
32+
33+
2434
[testenv:pytype]
2535
description = Run typechecking
2636
basepython = python3.7
2737
skip_install = True
2838
deps =
2939
pytype
40+
parver
3041
commands =
3142
pytype {posargs} update.py
43+
pytype {posargs} bump_version.py
3244

3345
[testenv:format]
3446
description = Run auto formatters

update.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import typing
1111

1212
import click
13-
13+
import parver
1414
import requests
1515

1616
IANA_LATEST_LOCATION = "https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz"
@@ -105,7 +105,10 @@ def create_package(
105105
version: str, zonenames: typing.List[str], zoneinfo_dir: pathlib.Path
106106
):
107107
"""Creates the tzdata package."""
108-
package_version = translate_version(version)
108+
# Start out at rc0
109+
base_version = parver.Version.parse(translate_version(version))
110+
rc_version = base_version.replace(pre_tag="rc", pre=0)
111+
package_version = str(rc_version)
109112

110113
# First remove the existing package contents
111114
target_dir = PKG_BASE / "tzdata"
@@ -126,6 +129,9 @@ def create_package(
126129
with open(target_dir / "__init__.py", "w") as f_out:
127130
f_out.write(contents)
128131

132+
with open(REPO_ROOT / "VERSION", "w") as f:
133+
f.write(package_version)
134+
129135
# Generate the "zones" file as a newline-delimited list
130136
with open(target_dir / "zones", "w") as f:
131137
f.write("\n".join(zonenames))

0 commit comments

Comments
 (0)