Move things to rpmautospec Python package

This allows us to reuse code, e.g. to get info out of Koji, for both
calculating release tags and generating the changelog.

Signed-off-by: Nils Philippsen <nils@redhat.com>
This commit is contained in:
Nils Philippsen 2020-02-21 16:50:00 +01:00
parent 6803b2b8c7
commit 3b5dc34a5d
7 changed files with 89 additions and 31 deletions

6
rpmautospec.py Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env python
from rpmautospec.cli import main
main()

0
rpmautospec/__init__.py Normal file
View file

View file

@ -13,6 +13,18 @@ import pygit2
_log = logging.getLogger(__name__)
def register_subcommand(subparsers):
subcmd_name = "generate-changelog"
gen_changelog_parser = subparsers.add_parser(
subcmd_name, help="Generate changelog entries from git commit logs",
)
gen_changelog_parser.add_argument("worktree_path", help="Path to the dist-git worktree")
return subcmd_name
def run_command(command, cwd=None):
""" Run the specified command in a specific working directory if one
is specified.
@ -31,8 +43,10 @@ def run_command(command, cwd=None):
def main(args):
""" Main method. """
repo_obj = pygit2.Repository(args[0])
name = os.path.basename(args[0])
repopath = args.worktree_path
repo_obj = pygit2.Repository(repopath)
name = os.path.basename(repopath)
branch = repo_obj.lookup_branch(repo_obj.head.shorthand)
commit = branch.peel(pygit2.Commit)
@ -53,7 +67,7 @@ def main(args):
repo_obj.checkout_tree(
commit, strategy=pygit2.GIT_CHECKOUT_FORCE | pygit2.GIT_CHECKOUT_RECREATE_MISSING,
)
if os.path.exists(os.path.join(args[0], f"{name}.spec")):
if os.path.exists(os.path.join(repopath, f"{name}.spec")):
try:
output = run_command(
[
@ -63,7 +77,7 @@ def main(args):
"--specfile",
f"{name}.spec",
],
cwd=args[0],
cwd=repopath,
)
except Exception:
continue
@ -108,7 +122,3 @@ def main(args):
)
print("- %s" % message)
print()
if __name__ == "__main__":
main(sys.argv[1:])

43
rpmautospec/cli.py Normal file
View file

@ -0,0 +1,43 @@
import argparse
import sys
from . import changelog, release
subcmd_modules_by_name = {}
def get_cli_args(args):
global subcmd_modules_by_name
parser = argparse.ArgumentParser(prog="rpmautospec")
# global arguments
parser.add_argument(
"--koji-url",
help="The base URL of the Koji hub",
default="https://koji.fedoraproject.org/kojihub",
)
# parsers for sub-commands
subparsers = parser.add_subparsers(dest="subcommand", required=True)
for subcmd_module in (changelog, release):
subcmd_name = subcmd_module.register_subcommand(subparsers)
if subcmd_name in subcmd_modules_by_name:
raise RuntimeError(f"Sub-command specified more than once: {subcmd_name}.")
subcmd_modules_by_name[subcmd_name] = subcmd_module
return parser.parse_args(args)
def main():
args = get_cli_args(sys.argv[1:])
if args.subcommand:
subcmd_module = subcmd_modules_by_name[args.subcommand]
subcmd_module.main(args)

View file

@ -20,29 +20,27 @@ _disttag_re = re.compile(r"^\.?(?P<distcode>[^\d\.]+)(?P<distver>\d+)")
_evr_re = re.compile(r"^(?:(?P<epoch>\d+):)?(?P<version>[^-:]+)(?:-(?P<release>[^-:]+))?$")
def get_cli_arguments(args):
""" Set the CLI argument parser and return the argument parsed.
"""
parser = argparse.ArgumentParser(description="Script to determine the next NVR of a build")
parser.add_argument(
"--koji-url",
help="The base URL of the Koji hub",
default="https://koji.fedoraproject.org/kojihub",
def register_subcommand(subparsers):
subcmd_name = "calculate-release"
calc_release_parser = subparsers.add_parser(
subcmd_name, help="Calculate the next release tag for a package build",
)
parser.add_argument(
calc_release_parser.add_argument(
"--algorithm",
"--algo",
help="The algorithm with which to determine the next release",
help="The algorithm with which to calculate the next release",
choices=["sequential_builds", "holistic_heuristic"],
default="sequential_builds",
)
parser.add_argument("package", help="The name of the package of interest")
parser.add_argument("dist", help="The dist-tag of interest")
parser.add_argument(
calc_release_parser.add_argument("package", help="The name of the package of interest")
calc_release_parser.add_argument("dist", help="The dist-tag of interest")
calc_release_parser.add_argument(
"evr", help="The [epoch:]version[-release] of the package", nargs="?", type=parse_evr,
)
return parser.parse_args(args)
return subcmd_name
def parse_evr(evr_str):
@ -255,7 +253,6 @@ def main_holistic_heuristic_algo(args, client, pkgid):
def main(args):
""" Main method. """
args = get_cli_arguments(args)
client = koji.ClientSession(args.koji_url)
pkgid = client.getPackageID(args.package)
@ -267,7 +264,3 @@ def main(args):
main_sequential_builds_algo(args, client, pkgid)
elif args.algorithm == "holistic_heuristic":
main_holistic_heuristic_algo(args, client, pkgid)
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))

View file

@ -5,5 +5,5 @@ exclude = .git,.tox,dist,*egg,build,tools
#ignore =
# Configure flake8-import-order
application-import-names = generate_changelog,next_build
application-import-names = rpmautospec
import-order-style = google

View file

@ -4,7 +4,7 @@ from unittest import mock
import pytest
import next_build
from rpmautospec import release
__here__ = os.path.dirname(__file__)
@ -42,13 +42,19 @@ class TestNextBuild:
) as f:
koji_list_builds_output = json.load(f)
with mock.patch("next_build.koji") as mock_koji:
with mock.patch("rpmautospec.release.koji") as mock_koji:
mock_client = mock.MagicMock()
mock_koji.ClientSession.return_value = mock_client
mock_client.getPackageID.return_value = 1234
mock_client.listBuilds.return_value = koji_list_builds_output
next_build.main((test_data["package"], test_data["dist"]))
main_args = mock.Mock()
main_args.algorithm = "sequential_builds"
main_args.package = test_data["package"]
main_args.dist = test_data["dist"]
main_args.evr = None
release.main(main_args)
mock_client.getPackageID.assert_called_once()
mock_client.listBuilds.assert_called_once()