From 28bbdf97749ef58ddc4ac7b803e26b43a8f708dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20=E2=80=9CCyberTailor=E2=80=9D?= Date: Fri, 5 Jan 2024 20:04:47 +0500 Subject: [PATCH] cli: initial mockup --- .bumpversion.cfg | 8 ++++ .bumpversion.cfg.license | 3 ++ .drone.yml | 16 ++++++++ find_work/__init__.py | 7 ++++ find_work/__main__.py | 49 ++++++++++++++++++++++++ find_work/cli/__init__.py | 21 +++++++++++ find_work/cli/repology.py | 15 ++++++++ man/find-work.1 | 79 +++++++++++++++++++++++++++++++++++++++ pyproject.toml | 51 +++++++++++++++++++++++++ tox.ini | 28 ++++++++++++++ 10 files changed, 277 insertions(+) create mode 100644 .bumpversion.cfg create mode 100644 .bumpversion.cfg.license create mode 100644 .drone.yml create mode 100644 find_work/__init__.py create mode 100644 find_work/__main__.py create mode 100644 find_work/cli/__init__.py create mode 100644 find_work/cli/repology.py create mode 100644 man/find-work.1 create mode 100644 pyproject.toml create mode 100644 tox.ini diff --git a/.bumpversion.cfg b/.bumpversion.cfg new file mode 100644 index 0000000..da844f2 --- /dev/null +++ b/.bumpversion.cfg @@ -0,0 +1,8 @@ +[bumpversion] +current_version = 0.1.0 +commit = True +tag = True +tag_name = {new_version} +sign_tags = True + +[bumpversion:file:find_work/__init__.py] diff --git a/.bumpversion.cfg.license b/.bumpversion.cfg.license new file mode 100644 index 0000000..9482f74 --- /dev/null +++ b/.bumpversion.cfg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2024 Anna + +SPDX-License-Identifier: CC0-1.0 diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..ed2dde8 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2023 Anna + +kind: pipeline +type: docker +name: default + +workspace: + path: /tests + +steps: + - name: test + image: 31z4/tox:4 + user: root + commands: + - tox run diff --git a/find_work/__init__.py b/find_work/__init__.py new file mode 100644 index 0000000..4925c90 --- /dev/null +++ b/find_work/__init__.py @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: WTFPL +# SPDX-FileCopyrightText: 2024 Anna +# No warranty + +""" Personal advice utility for Gentoo package maintainers """ + +__version__ = "0.1.0" diff --git a/find_work/__main__.py b/find_work/__main__.py new file mode 100644 index 0000000..6161a18 --- /dev/null +++ b/find_work/__main__.py @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: WTFPL +# SPDX-FileCopyrightText: 2024 Anna +# No warranty + +from typing import Callable + +import click +from click_aliases import ClickAliasedGroup + +import find_work +import find_work.cli.repology +from find_work.cli import Options + + +def help_text(docstring: str) -> Callable: + """ + Override function's docstring. + + :param docstring: new docstring + :return: decorated function + """ + def decorate(f: Callable) -> Callable: + f.__doc__ = docstring + return f + return decorate + + +@click.group(cls=ClickAliasedGroup, + context_settings={"help_option_names": ["-h", "--help"]}) +@click.option("-I", "--installed", is_flag=True, + help="Only match installed packages.") +@click.version_option(find_work.__version__, "-V", "--version") +@click.pass_context +@help_text(find_work.__doc__) +def cli(ctx: click.Context, installed: bool) -> None: + ctx.ensure_object(Options) + ctx.obj.only_installed = installed + + +@cli.group(aliases=["rep", "r"], cls=ClickAliasedGroup) +@click.option("-r", "--repo", required=True, + help="Repository name on Repology.") +@click.pass_obj +def repology(options: Options, repo: str) -> None: + """ Use Repology to find work. """ + options.repology.repo = repo + + +repology.add_command(find_work.cli.repology.outdated, aliases=["out", "o"]) diff --git a/find_work/cli/__init__.py b/find_work/cli/__init__.py new file mode 100644 index 0000000..8e2c446 --- /dev/null +++ b/find_work/cli/__init__.py @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: WTFPL +# SPDX-FileCopyrightText: 2024 Anna +# No warranty + +""" Modules implementing command-line functionality """ + +from dataclasses import dataclass, field + + +@dataclass +class RepologyOptions: + """ Repology subcommand options """ + repo: str = "" + + +@dataclass +class Options: + """ Global options """ + only_installed: bool = False + + repology: RepologyOptions = field(default_factory=RepologyOptions) diff --git a/find_work/cli/repology.py b/find_work/cli/repology.py new file mode 100644 index 0000000..920aba1 --- /dev/null +++ b/find_work/cli/repology.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: WTFPL +# SPDX-FileCopyrightText: 2024 Anna +# No warranty + +""" CLI subcommands for everything Repology. """ + +import click + +from find_work.cli import Options + + +@click.command() +@click.pass_obj +def outdated(options: Options) -> None: + """ Find outdated packages. """ diff --git a/man/find-work.1 b/man/find-work.1 new file mode 100644 index 0000000..20b3cfa --- /dev/null +++ b/man/find-work.1 @@ -0,0 +1,79 @@ +.\" SPDX-FileType: DOCUMENTATION +.\" SPDX-FileCopyrightText: 2024 Anna +.\" SPDX-License-Identifier: CC0-1.0 +.\" No warranty +.Dd January 4, 2024 +.Dt FIND-WORK 1 +.Os +.Sh NAME +.Nm find-work +.Nd discover ebuilds to improve +.Sh SYNOPSIS +.Nm +.Op Fl hV +.Nm +.Op Fl I +.Ar module +.Op Ar arg ... +.Ar command +.Sh DESCRIPTION +.Nm +provides global and module-specific options. +Global options must precede the module name, and are as follows: +.Bl -tag -width tenletters +.It Fl h , -help +Display usage information and exit immediately. +.It Fl I , -installed +Only match installed packages. +.It Fl V , -version +Display program version and exit immediately. +.El +.Pp +The modules for +.Nm +are as follows: +.Bl -tag -width repology +.It Xo +.Cm repology +.Op Fl r Ar repo +.Ar command +.Xc +.Dl Pq alias: Cm rep , Cm r +.Pp +This module uses Repology API to find work. +.Pp +.Ar command +can be one of the following: +.Bl -tag -width Ds +.It Ic outdated Pq alias: Ic out , Ic o +Find outdated packages. +.El +.Pp +The options for +.Cm find-work repology +are as follows: +.Bl -tag -width Ds +.It Fl r Ar repo +Repository name on repology. +This option is required. +Some examples for Gentoo include: +.Bl -bullet -compact -width 1n +.It +.Ql gentoo +.It +.Ql gentoo_ovl_guru +.It +.Ql gentoo_ovl_pentoo +.It +.Ql gentoo_ovl_science +.El +.El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +Find outdated GURU packages installed on your system using Repology data: +.Pp +.Dl "$ find-work repology -r gentoo_ovl_guru outdated" +.Sh AUTHORS +.An Anna +.Aq Mt cyber@sysrq.in diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3c63802 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2024 Anna + +[build-system] +requires = ["flit_core >=3.2,<4"] +build-backend = "flit_core.buildapi" + +[project] +name = "find-work" +authors = [ + {name = "Anna", email = "cyber@sysrq.in"}, +] +dynamic = ["version", "description"] +readme = "README.md" +license = {file = "LICENSE"} +requires-python = ">=3.10" +dependencies = [ + "click", + "click-aliases", +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "Intended Audience :: Developers", + "License :: DFSG approved", + "Operating System :: POSIX", + "Programming Language :: Python :: 3 :: Only", + "Topic :: System :: Software Distribution", + "Topic :: Utilities", + "Typing :: Typed", +] +keywords = ["gentoo", "ebuild", "repository", "maintainer"] + +[project.scripts] +find-work = "find_work.__main__:cli" + +[project.urls] +Home = "https://find-work.sysrq.in" +Source = "https://git.sysrq.in/find-work" +Issues = "https://bugs.sysrq.in/enter_bug.cgi?product=Software&component=find-work" +Changelog = "https://find-work.sysrq.in/release-notes.html" + +[tool.mypy] +disallow_untyped_defs = true +no_implicit_optional = true + +[[tool.mypy.overrides]] +module = [ + "click_aliases", +] +ignore_missing_imports = true diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..6cf9ee0 --- /dev/null +++ b/tox.ini @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2023-2024 Anna + +[tox] +minversion = 4.0 +env_list = py3{10,11,12}, lint + +[testenv] +description = run the tests +deps = + mypy +commands = + mypy find_work + +[testenv:lint] +description = run the linters +skip_install = true +deps = + pycodestyle + pyflakes + reuse +commands = + reuse lint + pyflakes {posargs:find_work} + pycodestyle {posargs:find_work} + +[pycodestyle] +max-line-length = 100