Significantly improve release version validation

This commit is contained in:
Pradyun Gedam 2020-04-10 01:04:39 +05:30
parent 4416e88ef1
commit de633cdf4b
No known key found for this signature in database
GPG Key ID: DA17C4B29CB32E4B
3 changed files with 59 additions and 15 deletions

View File

@ -155,9 +155,9 @@ def lint(session):
# -----------------------------------------------------------------------------
@nox.session(name="prepare-release")
def prepare_release(session):
version = release.get_version_from_arguments(session.posargs)
version = release.get_version_from_arguments(session)
if not version:
session.error("Usage: nox -s prepare-release -- YY.N[.P]")
session.error("Usage: nox -s prepare-release -- <version>")
session.log("# Ensure nothing is staged")
if release.modified_files_in_git("--staged"):
@ -190,7 +190,7 @@ def prepare_release(session):
@nox.session(name="build-release")
def build_release(session):
version = release.get_version_from_arguments(session.posargs)
version = release.get_version_from_arguments(session)
if not version:
session.error("Usage: nox -s build-release -- YY.N[.P]")
@ -249,7 +249,7 @@ def build_dists(session):
@nox.session(name="upload-release")
def upload_release(session):
version = release.get_version_from_arguments(session.posargs)
version = release.get_version_from_arguments(session)
if not version:
session.error("Usage: nox -s upload-release -- YY.N[.P]")

View File

@ -14,24 +14,25 @@ from typing import Iterator, List, Optional, Set
from nox.sessions import Session
def get_version_from_arguments(arguments: List[str]) -> Optional[str]:
def get_version_from_arguments(session: Session) -> Optional[str]:
"""Checks the arguments passed to `nox -s release`.
If there is only 1 argument that looks like a pip version, returns that.
Otherwise, returns None.
"""
if len(arguments) != 1:
if len(session.posargs) != 1:
return None
version = session.posargs[0]
version = arguments[0]
parts = version.split('.')
if not 2 <= len(parts) <= 3:
# Not of the form: YY.N or YY.N.P
return None
if not all(part.isdigit() for part in parts):
# Not all segments are integers.
# We delegate to a script here, so that it can depend on packaging.
session.install("packaging")
cmd = [
os.path.join(session.bin, "python"),
"tools/automation/release/check_version.py",
version
]
not_ok = subprocess.run(cmd).returncode
if not_ok:
return None
# All is good.

View File

@ -0,0 +1,43 @@
"""Checks if the version is acceptable, as per this project's release process.
"""
import sys
from datetime import datetime
from typing import Optional
from packaging.version import InvalidVersion, Version
def is_this_a_good_version_number(string: str) -> Optional[str]:
try:
v = Version(string)
except InvalidVersion as e:
return str(e)
if v.local:
return "Nope. PyPI refuses local release versions."
if v.dev:
return "No development releases on PyPI. What are you even thinking?"
if v.is_prerelease and v.pre[0] != "b":
return "Only beta releases are allowed. No alphas."
release = v.release
expected_major = datetime.now().year % 100
if len(release) not in [2, 3]:
return "Not of the form: {0}.N or {0}.N.P".format(expected_major)
return None
def main() -> None:
problem = is_this_a_good_version_number(sys.argv[1])
if problem is not None:
print("ERROR:", problem)
sys.exit(1)
if __name__ == "__main__":
main()