Skip to content

Commit

Permalink
Change: Consolidate CLI parsing
Browse files Browse the repository at this point in the history
Move all CLI parsing to dedicated modules. This allows for better
separation of concerns and easier testing.
  • Loading branch information
bjoernricks authored and greenbonebot committed Feb 5, 2024
1 parent e105f3f commit a75b5f1
Show file tree
Hide file tree
Showing 23 changed files with 390 additions and 333 deletions.
102 changes: 102 additions & 0 deletions pontos/changelog/_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# SPDX-FileCopyrightText: 2024 Greenbone AG
#
# SPDX-License-Identifier: GPL-3.0-or-later

from argparse import ArgumentParser, Namespace
from pathlib import Path
from typing import Optional, Sequence

import shtab

from pontos.version.schemes import (
VERSIONING_SCHEMES,
VersioningScheme,
versioning_scheme_argument_type,
)


def parse_args(args: Optional[Sequence[str]] = None) -> Namespace:
parser = ArgumentParser(
description="Conventional commits utility. Create a changelog markdown "
" text from conventional commits between the current and next release.",
prog="pontos-changelog",
)
shtab.add_argument_to(parser)

parser.add_argument(
"--config",
"-C",
type=Path,
help="Optional. Conventional commits config file (toml), including "
"conventions. If not provided defaults are used.",
).complete = shtab.FILE # type: ignore[attr-defined]

parser.add_argument(
"--project",
required=True,
help="The github project. Used for building the links to the "
"repository.",
)

parser.add_argument(
"--space",
default="greenbone",
help="User/Team name in github. Used for building the links to the "
"repository",
)

parser.add_argument(
"--versioning-scheme",
help="Versioning scheme to use for parsing and handling version "
f"information. Choices are {', '.join(VERSIONING_SCHEMES.keys())}. "
"Default: %(default)s",
default="pep440",
type=versioning_scheme_argument_type,
)

parser.add_argument(
"--current-version",
help="Version to start looking for changes. All commits since this "
"releases are take into account for creating the changelog text.",
)

parser.add_argument(
"--next-version",
"--release-version",
dest="next_version",
help="The planned release version",
)

parser.add_argument(
"--git-tag-prefix",
default="v",
help="Prefix for git tag versions. Used to determine existing "
"releases. Default: %(default)s",
)

parser.add_argument(
"--output",
"-o",
type=Path,
help="Write changelog to this file.",
).complete = shtab.FILE # type: ignore[attr-defined]

parser.add_argument(
"--quiet",
"-q",
action="store_true",
help="Don't print messages to the terminal",
)

parsed_args = parser.parse_args(args=args)

scheme: VersioningScheme = parsed_args.versioning_scheme
current_version = getattr(parsed_args, "current_version", None)
if current_version:
parsed_args.current_version = scheme.parse_version(current_version)

next_version = getattr(parsed_args, "next_version", None)
if next_version:
parsed_args.next_version = scheme.parse_version(next_version)

return parsed_args
96 changes: 1 addition & 95 deletions pontos/changelog/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,109 +4,15 @@
#

import sys
from argparse import ArgumentParser, Namespace
from pathlib import Path
from typing import NoReturn, Optional, Sequence

import shtab

from pontos.changelog.conventional_commits import ChangelogBuilder
from pontos.errors import PontosError
from pontos.terminal.null import NullTerminal
from pontos.terminal.rich import RichTerminal
from pontos.version.helper import get_last_release_version
from pontos.version.schemes import (
VERSIONING_SCHEMES,
VersioningScheme,
versioning_scheme_argument_type,
)


def parse_args(args: Optional[Sequence[str]] = None) -> Namespace:
parser = ArgumentParser(
description="Conventional commits utility. Create a changelog markdown "
" text from conventional commits between the current and next release.",
prog="pontos-changelog",
)
shtab.add_argument_to(parser)

parser.add_argument(
"--config",
"-C",
type=Path,
help="Optional. Conventional commits config file (toml), including "
"conventions. If not provided defaults are used.",
).complete = shtab.FILE # type: ignore[attr-defined]

parser.add_argument(
"--project",
required=True,
help="The github project. Used for building the links to the "
"repository.",
)

parser.add_argument(
"--space",
default="greenbone",
help="User/Team name in github. Used for building the links to the "
"repository",
)

parser.add_argument(
"--versioning-scheme",
help="Versioning scheme to use for parsing and handling version "
f"information. Choices are {', '.join(VERSIONING_SCHEMES.keys())}. "
"Default: %(default)s",
default="pep440",
type=versioning_scheme_argument_type,
)

parser.add_argument(
"--current-version",
help="Version to start looking for changes. All commits since this "
"releases are take into account for creating the changelog text.",
)

parser.add_argument(
"--next-version",
"--release-version",
dest="next_version",
help="The planned release version",
)

parser.add_argument(
"--git-tag-prefix",
default="v",
help="Prefix for git tag versions. Used to determine existing "
"releases. Default: %(default)s",
)

parser.add_argument(
"--output",
"-o",
type=Path,
help="Write changelog to this file.",
).complete = shtab.FILE # type: ignore[attr-defined]

parser.add_argument(
"--quiet",
"-q",
action="store_true",
help="Don't print messages to the terminal",
)

parsed_args = parser.parse_args(args=args)

scheme: VersioningScheme = parsed_args.versioning_scheme
current_version = getattr(parsed_args, "current_version", None)
if current_version:
parsed_args.current_version = scheme.parse_version(current_version)

next_version = getattr(parsed_args, "next_version", None)
if next_version:
parsed_args.next_version = scheme.parse_version(next_version)

return parsed_args
from ._parser import parse_args


def main(args: Optional[Sequence[str]] = None) -> NoReturn:
Expand Down
9 changes: 3 additions & 6 deletions pontos/github/argparser.py → pontos/github/_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import os
from argparse import ArgumentParser, FileType, Namespace
from pathlib import Path
from typing import List, Optional
from typing import Optional, Sequence

import shtab

Expand All @@ -35,9 +35,7 @@ def from_env(name: str) -> str:
return os.environ.get(name, name)


def parse_args(
args: Optional[List[str]] = None,
) -> Namespace:
def parse_args(args: Optional[Sequence[str]] = None) -> Namespace:
"""
Parsing args for Pontos GitHub
Expand Down Expand Up @@ -243,7 +241,6 @@ def parse_args(
),
)

# orga-repos
repos_parser = subparsers.add_parser(
"repos", aliases=["R"], help="Repository information"
)
Expand Down Expand Up @@ -418,7 +415,7 @@ def parse_args(
"-got",
"--git-object-type",
default="commit",
help="The type of the object we're taggin",
help="The type of the object we're tagging",
)

create_tag_parser.add_argument(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
""" Argument parser for pontos-github-actions """

from argparse import ArgumentParser, Namespace
from typing import List, Optional
from typing import Optional, Sequence

import shtab

from .cmds import actions_input, actions_output

Expand All @@ -17,16 +19,15 @@ def split_pairs(value: str):
return tuple(value.split("=", 1))


def parse_args(
args: Optional[List[str]] = None,
) -> Namespace:
def parse_args(args: Optional[Sequence[str]] = None) -> Namespace:
"""
Parsing args for Pontos GitHub Actions
"""

parser = ArgumentParser(
description="Greenbone GitHub Actions API.",
)
shtab.add_argument_to(parser)

parser.add_argument(
"--quiet",
Expand Down
3 changes: 2 additions & 1 deletion pontos/github/actions/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#

from pontos.github.actions.argparser import parse_args
from pontos.terminal.null import NullTerminal
from pontos.terminal.rich import RichTerminal

from ._parser import parse_args


def main(args=None):
parsed_args = parse_args(args)
Expand Down
3 changes: 2 additions & 1 deletion pontos/github/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import asyncio
import sys

from pontos.github.argparser import parse_args
from pontos.terminal.null import NullTerminal
from pontos.terminal.rich import RichTerminal

from ._parser import parse_args


def main(args=None):
parsed_args = parse_args(args)
Expand Down
2 changes: 1 addition & 1 deletion pontos/github/script/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ async def github_script(api: GitHubAsyncRESTApi, args: Namespace) -> int:

from pontos.errors import PontosError

from ._parser import create_parser
from .errors import GitHubScriptError
from .load import (
load_script,
run_add_arguments_function,
run_github_script_function,
)
from .parser import create_parser

__all__ = (
"GitHubScriptError",
Expand Down
File renamed without changes.
42 changes: 6 additions & 36 deletions pontos/nvd/cpe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
#

import asyncio
from argparse import ArgumentParser, Namespace
from argparse import Namespace
from typing import Callable

import httpx
import shtab

from pontos.nvd.cpe.api import CPEApi

from ._parser import cpe_parser, cpes_parser

__all__ = ("CPEApi",)


Expand All @@ -34,46 +35,15 @@ async def query_cpes(args: Namespace) -> None:


def cpe_main() -> None:
parser = ArgumentParser()
shtab.add_argument_to(parser)
parser.add_argument("--token", help="API key to use for querying.")
parser.add_argument(
"cpe_name_id", metavar="CPE Name ID", help="UUID of the CPE"
)

main(parser, query_cpe)
main(cpe_parser(), query_cpe)


def cpes_main() -> None:
parser = ArgumentParser()
shtab.add_argument_to(parser)
parser.add_argument("--token", help="API key to use for querying.")
parser.add_argument(
"--cpe-match-string",
help="Search for CPE names that exist in the Official CPE Dictionary.",
)
parser.add_argument(
"--keywords",
nargs="*",
help="Search for CPEs containing the keyword in their titles and "
"references.",
)
parser.add_argument(
"--number", "-n", metavar="N", help="Request only N CPEs", type=int
)
parser.add_argument(
"--start",
"-s",
help="Index of the first CPE to request.",
type=int,
)

main(parser, query_cpes)
main(cpes_parser(), query_cpes)


def main(parser: ArgumentParser, func: Callable) -> None:
def main(args: Namespace, func: Callable) -> None:
try:
args = parser.parse_args()
asyncio.run(func(args))
except KeyboardInterrupt:
pass
Expand Down
Loading

0 comments on commit a75b5f1

Please sign in to comment.