Skip to content

Commit

Permalink
Change: Refactor release CLI for VersionCommand changes
Browse files Browse the repository at this point in the history
Also don't use the version CLI function anymore.
  • Loading branch information
bjoernricks authored and y0urself committed Jan 13, 2023
1 parent 60724e6 commit c15b757
Show file tree
Hide file tree
Showing 10 changed files with 423 additions and 415 deletions.
57 changes: 24 additions & 33 deletions pontos/release/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,13 @@

import datetime
import sys
from pathlib import Path
from typing import Optional, Tuple

from packaging.version import InvalidVersion, Version

from pontos import version
from pontos.git import Git, GitError
from pontos.terminal import Terminal
from pontos.version import (
CMakeVersionCommand,
JavaScriptVersionCommand,
PythonVersionCommand,
)
from pontos.version import COMMANDS
from pontos.version.helper import VersionError

DEFAULT_TIMEOUT = 1000
Expand All @@ -43,7 +37,7 @@ def commit_files(
*,
git_signing_key: str = "",
changelog: bool = False,
):
) -> None:
"""Add files to staged and commit staged files.
Args:
Expand Down Expand Up @@ -113,17 +107,11 @@ def get_current_version(terminal: Terminal) -> Optional[str]:
"""Get the current Version from a pyproject.toml or
a CMakeLists.txt file"""

available_cmds = [
("CMakeLists.txt", CMakeVersionCommand),
("pyproject.toml", PythonVersionCommand),
("package.json", JavaScriptVersionCommand),
]
for file_name, cmd in available_cmds:
project_definition_path = Path.cwd() / file_name
if project_definition_path.exists():
terminal.ok(f"Found {file_name} project definition file.")
current_version: str = cmd().get_current_version()
return current_version
for cmd in COMMANDS:
command = cmd()
if command.project_found():
terminal.ok("Found project definition file.")
return command.get_current_version()

terminal.error("No project settings file found")
return None
Expand Down Expand Up @@ -218,7 +206,7 @@ def find_signing_key(terminal: Terminal) -> str:

def update_version(
terminal: Terminal, to: str, *, develop: bool = False
) -> Tuple[bool, str]:
) -> Tuple[bool, Optional[str]]:
"""Use pontos-version to update the version.
Arguments:
Expand All @@ -229,17 +217,20 @@ def update_version(
executed: True if successfully executed, False else
filename: The filename of the project definition
"""
args = ["--quiet"]
args.append("update")
args.append(to)
if develop:
args.append("--develop")
executed, filename = version.main(leave=False, args=args)

if not executed:
if filename == "":
terminal.error("No project definition found.")
else:
terminal.error(f"Unable to update version {to} in {filename}")
project_file = None
for cmd in COMMANDS:
command = cmd()
project_file = command.project_file_found()
if project_file:
break

if not project_file:
terminal.error("No project definition found.")
return False, None

return executed, filename
try:
command.update_version(new_version=to, develop=develop)
return True, project_file.name
except VersionError:
terminal.error(f"Unable to update version {to} in {project_file}")
return False, None
18 changes: 10 additions & 8 deletions pontos/release/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import sys
from argparse import ArgumentParser, FileType, Namespace
from pathlib import Path
from typing import Tuple
from typing import NoReturn, Tuple

from pontos.terminal.null import NullTerminal
from pontos.terminal.rich import RichTerminal
Expand All @@ -34,6 +34,9 @@


def parse_args(args) -> Tuple[str, str, Namespace]:
"""
Return user, token, parsed arguments
"""
parser = ArgumentParser(
description="Release handling utility.",
prog="pontos-release",
Expand Down Expand Up @@ -224,9 +227,8 @@ def parse_args(args) -> Tuple[str, str, Namespace]:


def main(
leave: bool = True,
args=None,
):
) -> NoReturn:
username, token, parsed_args = parse_args(args)
if parsed_args.quiet:
term = NullTerminal()
Expand All @@ -237,13 +239,15 @@ def main(

with term.indent():
try:
if not parsed_args.func(
retval = parsed_args.func(
term,
parsed_args,
username=username,
token=token,
):
return sys.exit(1) if leave else False
)
sys.exit(int(retval))
except KeyboardInterrupt:
sys.exit(1)
except subprocess.CalledProcessError as e:
if not "--passphrase" in e.cmd:
term.error(f'Could not run command "{e.cmd}".')
Expand All @@ -253,8 +257,6 @@ def main(
term.print(f"Error was: {e.stderr}")
sys.exit(1)

return sys.exit(0) if leave else True


if __name__ == "__main__":
main()
22 changes: 15 additions & 7 deletions pontos/release/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import sys
from argparse import Namespace
from enum import IntEnum
from pathlib import Path

from pontos import changelog
Expand All @@ -36,11 +36,19 @@
RELEASE_TEXT_FILE = ".release.md"


class PrepareReturnValue(IntEnum):
SUCCESS = 0
NO_RELEASE_VERSION = 1
ALREADY_TAKEN = 2
UPDATE_VERSION_ERROR = 3
NO_UNRELEASED_CHANGELOG = 4


def prepare(
terminal: Terminal,
args: Namespace,
**_kwargs,
) -> bool:
) -> IntEnum:
git_tag_prefix: str = args.git_tag_prefix
git_signing_key: str = (
args.git_signing_key
Expand All @@ -62,7 +70,7 @@ def prepare(
release_version: str = args.release_version

if not release_version:
sys.exit(1)
return PrepareReturnValue.NO_RELEASE_VERSION

terminal.info(f"Preparing the release {release_version}")

Expand All @@ -72,11 +80,11 @@ def prepare(
git_version = f"{git_tag_prefix}{release_version}"
if git_version in git_tags:
terminal.error(f"git tag {git_version} is already taken.")
sys.exit(1)
return PrepareReturnValue.ALREADY_TAKEN

executed, filename = update_version(terminal, release_version)
if not executed:
return False
return PrepareReturnValue.UPDATE_VERSION_ERROR

terminal.ok(f"updated version in {filename} to {release_version}")

Expand Down Expand Up @@ -138,7 +146,7 @@ def prepare(

if not updated:
terminal.error("No unreleased text found in CHANGELOG.md")
sys.exit(1)
return PrepareReturnValue.NO_UNRELEASED_CHANGELOG

change_log_path.write_text(updated, encoding="utf-8")

Expand Down Expand Up @@ -166,4 +174,4 @@ def prepare(
)
terminal.print("Afterwards please execute release")

return True
return PrepareReturnValue.SUCCESS
21 changes: 15 additions & 6 deletions pontos/release/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#

from argparse import Namespace
from enum import IntEnum
from pathlib import Path

import httpx
Expand All @@ -38,19 +39,27 @@
RELEASE_TEXT_FILE = ".release.md"


class ReleaseReturnValue(IntEnum):
SUCCESS = 0
TOKEN_MISSING = 1
NO_RELEASE_VERSION = 2
CREATE_RELEASE_ERROR = 3
UPDATE_VERSION_ERROR = 4


def release(
terminal: Terminal,
args: Namespace,
*,
token: str,
**_kwargs,
) -> bool:
) -> IntEnum:
if not token:
terminal.error(
"Token is missing. The GitHub token is required to create a "
"release."
)
return False
return ReleaseReturnValue.TOKEN_MISSING

project: str = (
args.project if args.project is not None else get_git_repository_name()
Expand All @@ -72,7 +81,7 @@ def release(
)
if not release_version:
terminal.error("No release version available.")
return False
return ReleaseReturnValue.NO_RELEASE_VERSION

next_version: str = (
args.next_version
Expand Down Expand Up @@ -102,7 +111,7 @@ def release(
)
except httpx.HTTPError as e:
terminal.error(str(e))
return False
return ReleaseReturnValue.CREATE_RELEASE_ERROR

Path(RELEASE_TEXT_FILE).unlink()

Expand Down Expand Up @@ -136,7 +145,7 @@ def release(

executed, filename = update_version(terminal, next_version, develop=True)
if not executed:
return False
return ReleaseReturnValue.UPDATE_VERSION_ERROR

commit_files(
git,
Expand All @@ -149,4 +158,4 @@ def release(
# pushing the new tag
git.push(follow_tags=True, remote=git_remote_name)

return True
return ReleaseReturnValue.SUCCESS
23 changes: 16 additions & 7 deletions pontos/release/sign.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#

from argparse import Namespace
from enum import IntEnum
from pathlib import Path

import httpx
Expand All @@ -28,21 +29,29 @@
from .helper import get_current_version, get_git_repository_name


class SignReturnValue(IntEnum):
SUCCESS = 0
TOKEN_MISSING = 1
NO_RELEASE_VERSION = 2
NO_RELEASE = 3
UPLOAD_ASSET_ERROR = 4


def sign(
terminal: Terminal,
args: Namespace,
*,
token: str,
**_kwargs,
) -> bool:
) -> IntEnum:
if not token and not args.dry_run:
# dry run doesn't upload assets. therefore a token MAY NOT be required
# for public repositories.
terminal.error(
"Token is missing. The GitHub token is required to upload "
"signature files."
)
return False
return SignReturnValue.TOKEN_MISSING

project: str = (
args.project if args.project is not None else get_git_repository_name()
Expand All @@ -55,7 +64,7 @@ def sign(
else get_current_version(terminal)
)
if not release_version:
return False
return SignReturnValue.NO_RELEASE_VERSION

signing_key: str = args.signing_key

Expand All @@ -66,7 +75,7 @@ def sign(

if not github.release_exists(repo, git_version):
terminal.error(f"Release version {git_version} does not exist.")
return False
return SignReturnValue.NO_RELEASE

zip_destination = Path(f"{project}-{release_version}.zip")
with github.download_release_zip(
Expand Down Expand Up @@ -104,7 +113,7 @@ def sign(
process.check_returncode()

if args.dry_run:
return True
return SignReturnValue.SUCCESS

upload_files = [
(Path(f"{str(p)}.asc"), "application/pgp-signature") for p in file_paths
Expand All @@ -118,6 +127,6 @@ def sign(
terminal.ok(f"Uploaded: {uploaded_file}")
except httpx.HTTPError as e:
terminal.error(f"Failed uploading asset {e}")
return False
return SignReturnValue.UPLOAD_ASSET_ERROR

return True
return SignReturnValue.SUCCESS
1 change: 1 addition & 0 deletions pontos/version/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def main() -> NoReturn:
command: VersionCommand = cmd()
if command.project_found():
found = True
break

if not found:
print("No project found.", file=sys.stderr)
Expand Down
Loading

0 comments on commit c15b757

Please sign in to comment.