cli: add version part filter
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
Bug: https://bugs.sysrq.in/show_bug.cgi?id=4
This commit is contained in:
parent
d7a99e3903
commit
4935f3fe45
|
@ -5,9 +5,11 @@
|
|||
Release Notes
|
||||
=============
|
||||
|
||||
0.6.2
|
||||
0.7.0
|
||||
-----
|
||||
|
||||
* **New**: Filter oudated packages by version part (:bug:`4`).
|
||||
|
||||
*Modules changelog:*
|
||||
|
||||
* **pgo**:
|
||||
|
|
|
@ -68,6 +68,9 @@ class OptionsBase(ABC):
|
|||
class ModuleOptionsBase(OptionsBase, ABC):
|
||||
""" Base class for module-specific options. """
|
||||
|
||||
#: Extra options used in the command scope.
|
||||
extra_options: dict[str, Any] | None = None
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def cache_order(self) -> list[str]:
|
||||
|
@ -95,6 +98,15 @@ class BugzillaOptions(ModuleOptionsBase):
|
|||
return ["chronological_sort", "short_desc", "product", "component"]
|
||||
|
||||
|
||||
@dataclass
|
||||
class PgoOptions(ModuleOptionsBase):
|
||||
""" Gentoo Packages subcommand options. """
|
||||
|
||||
@cached_property
|
||||
def cache_order(self) -> list[str]:
|
||||
return []
|
||||
|
||||
|
||||
@dataclass
|
||||
class PkgcheckOptions(ModuleOptionsBase):
|
||||
""" pkgcheck subcommand options. """
|
||||
|
@ -155,8 +167,9 @@ class Options(OptionsBase):
|
|||
# Byte string used for creating cache key.
|
||||
cache_key: CacheKey = field(default_factory=CacheKey)
|
||||
|
||||
# Subcommand options.
|
||||
#: Subcommand options.
|
||||
bugzilla: BugzillaOptions = field(default_factory=BugzillaOptions)
|
||||
pgo: PgoOptions = field(default_factory=PgoOptions)
|
||||
pkgcheck: PkgcheckOptions = field(default_factory=PkgcheckOptions)
|
||||
repology: RepologyOptions = field(default_factory=RepologyOptions)
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ from find_work.cache import (
|
|||
)
|
||||
from find_work.cli import Message, Options, ProgressDots
|
||||
from find_work.constants import PGO_BASE_URL, PGO_API_URL
|
||||
from find_work.types import VersionBump
|
||||
from find_work.types import VersionBump, VersionPart
|
||||
from find_work.utils import aiohttp_session
|
||||
|
||||
|
||||
|
@ -61,6 +61,9 @@ async def _outdated(options: Options) -> None:
|
|||
"Filtering by maintainer is not implemented for this command"
|
||||
)
|
||||
|
||||
if (extra_options := options.pgo.extra_options) is not None:
|
||||
version_part: VersionPart | None = extra_options.get("version_part")
|
||||
|
||||
dots = ProgressDots(options.verbose)
|
||||
|
||||
options.say(Message.CACHE_LOAD)
|
||||
|
@ -78,14 +81,18 @@ async def _outdated(options: Options) -> None:
|
|||
with dots():
|
||||
write_json_cache(data, options.cache_key)
|
||||
|
||||
outdated_set = _collect_version_bumps(data, options)
|
||||
for bump in outdated_set:
|
||||
no_work = True
|
||||
for bump in _collect_version_bumps(data, options):
|
||||
if version_part and not bump.changed(version_part):
|
||||
continue
|
||||
|
||||
options.echo(bump.atom + " ", nl=False)
|
||||
options.secho(bump.old_version, fg="red", nl=False)
|
||||
options.echo(" → ", nl=False)
|
||||
options.secho(bump.new_version, fg="green")
|
||||
no_work = False
|
||||
|
||||
if len(outdated_set) == 0:
|
||||
if no_work:
|
||||
options.say(Message.NO_WORK)
|
||||
|
||||
|
||||
|
@ -168,10 +175,18 @@ async def _stabilization(options: Options) -> None:
|
|||
|
||||
|
||||
@click.command()
|
||||
@click.option("-F", "--filter", "version_part",
|
||||
type=click.Choice(["major", "minor", "patch"]),
|
||||
help="Version part filter.")
|
||||
@click.pass_obj
|
||||
def outdated(options: Options) -> None:
|
||||
""" Find outdated packages. """
|
||||
def outdated(options: Options, version_part: VersionPart | None = None) -> None:
|
||||
"""
|
||||
Find outdated packages.
|
||||
"""
|
||||
|
||||
options.cache_key.feed("outdated")
|
||||
|
||||
options.pgo.extra_options = {"version_part": version_part}
|
||||
asyncio.run(_outdated(options))
|
||||
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ from find_work.cache import (
|
|||
write_json_cache,
|
||||
)
|
||||
from find_work.cli import Message, Options, ProgressDots
|
||||
from find_work.types import VersionBump
|
||||
from find_work.types import VersionBump, VersionPart
|
||||
from find_work.utils import aiohttp_session
|
||||
|
||||
|
||||
|
@ -87,6 +87,9 @@ def _collect_version_bumps(data: Iterable[set[Package]],
|
|||
async def _outdated(options: Options) -> None:
|
||||
dots = ProgressDots(options.verbose)
|
||||
|
||||
if (extra_options := options.repology.extra_options) is not None:
|
||||
version_part: VersionPart | None = extra_options.get("version_part")
|
||||
|
||||
options.say(Message.CACHE_LOAD)
|
||||
with dots():
|
||||
cached_data = read_json_cache(options.cache_key)
|
||||
|
@ -107,20 +110,32 @@ async def _outdated(options: Options) -> None:
|
|||
json_data = _projects_to_json(data)
|
||||
write_json_cache(json_data, options.cache_key)
|
||||
|
||||
outdated_set = _collect_version_bumps(data.values(), options)
|
||||
for bump in outdated_set:
|
||||
no_work = True
|
||||
for bump in _collect_version_bumps(data.values(), options):
|
||||
if version_part and not bump.changed(version_part):
|
||||
continue
|
||||
|
||||
options.echo(bump.atom + " ", nl=False)
|
||||
options.secho(bump.old_version, fg="red", nl=False)
|
||||
options.echo(" → ", nl=False)
|
||||
options.secho(bump.new_version, fg="green")
|
||||
no_work = False
|
||||
|
||||
if len(outdated_set) == 0:
|
||||
if no_work:
|
||||
options.say(Message.NO_WORK)
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option("-F", "--filter", "version_part",
|
||||
type=click.Choice(["major", "minor", "patch"]),
|
||||
help="Version part filter.")
|
||||
@click.pass_obj
|
||||
def outdated(options: Options) -> None:
|
||||
""" Find outdated packages. """
|
||||
def outdated(options: Options, version_part: VersionPart | None = None) -> None:
|
||||
"""
|
||||
Find outdated packages.
|
||||
"""
|
||||
|
||||
options.cache_key.feed("outdated")
|
||||
|
||||
options.repology.extra_options = {"version_part": version_part}
|
||||
asyncio.run(_outdated(options))
|
||||
|
|
|
@ -3,23 +3,65 @@
|
|||
# No warranty
|
||||
|
||||
"""
|
||||
Type definitions for the application, implemented (mostly) as Pydantic models.
|
||||
Type definitions for the application, implemented as enums and Pydantic models.
|
||||
"""
|
||||
|
||||
from dataclasses import field
|
||||
from enum import Enum, auto
|
||||
from enum import Enum, StrEnum, auto
|
||||
from itertools import zip_longest
|
||||
|
||||
from pydantic.dataclasses import dataclass
|
||||
|
||||
|
||||
class VersionPart(StrEnum):
|
||||
MAJOR = auto()
|
||||
MINOR = auto()
|
||||
PATCH = auto()
|
||||
|
||||
|
||||
@dataclass(frozen=True, order=True)
|
||||
class VersionBump:
|
||||
""" Version bump representation for a Gentoo repository. """
|
||||
"""
|
||||
Version bump representation for a Gentoo repository.
|
||||
"""
|
||||
|
||||
atom: str
|
||||
old_version: str = field(compare=False)
|
||||
new_version: str = field(compare=False)
|
||||
|
||||
def changed(self, stop_after_part: VersionPart) -> bool:
|
||||
"""
|
||||
Roughly determine whether versions differ up to the given part.
|
||||
|
||||
>>> VersionBump("foo", "1.3.2", "1.4").changed(VersionPart.PATCH)
|
||||
True
|
||||
>>> VersionBump("foo", "1.3.2", "2.0").changed(VersionPart.MINOR)
|
||||
True
|
||||
>>> VersionBump("foo", "1", "1.0.1").changed(VersionPart.MINOR)
|
||||
False
|
||||
>>> VersionBump("foo", "1", "1.1").changed(VersionPart.MINOR)
|
||||
True
|
||||
|
||||
Remember that it doesn't always work correctly:
|
||||
|
||||
>>> VersionBump("foo", "1", "1.00").changed(VersionPart.MINOR)
|
||||
True
|
||||
"""
|
||||
|
||||
def split_version(version: str) -> list[str]:
|
||||
return version.replace("-", ".").replace("_", ".").split(".")
|
||||
|
||||
old_parts = split_version(self.old_version)
|
||||
new_parts = split_version(self.new_version)
|
||||
|
||||
parts = list(zip_longest(old_parts, new_parts, fillvalue="0"))
|
||||
stop_index = list(VersionPart).index(stop_after_part)
|
||||
for old, new in parts[:stop_index + 1]:
|
||||
if old != new:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@dataclass(frozen=True, order=True)
|
||||
class BugView:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
.\" SPDX-FileCopyrightText: 2024 Anna <cyber@sysrq.in>
|
||||
.\" SPDX-License-Identifier: WTFPL
|
||||
.\" No warranty
|
||||
.Dd January 14, 2024
|
||||
.Dd April 23, 2024
|
||||
.Dt FIND-WORK 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -17,9 +17,11 @@
|
|||
.Ar module
|
||||
.Op Ar arg ...
|
||||
.Ar command
|
||||
.Op Ar arg ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a fun little tool that lets you discover what you can do for Gentoo as a package mantainer.
|
||||
is a fun little tool
|
||||
that lets you discover what you can do for Gentoo as a package mantainer.
|
||||
It contains filters to show only packages you might be interested in.
|
||||
.Pp
|
||||
.Nm
|
||||
|
@ -84,8 +86,28 @@ This module uses Gentoo Packages API to find work.
|
|||
.Ar command
|
||||
can be one of the following:
|
||||
.Bl -tag -width Ds
|
||||
.It Ic outdated Pq alias: Ic out , Ic o
|
||||
.It Xo
|
||||
.Ic outdated
|
||||
.Fl F Ar part
|
||||
.Xc
|
||||
.Dl Pq alias: Ic out , Ic o
|
||||
.Pp
|
||||
Find outdated packages.
|
||||
.Pp
|
||||
This command accepts the following options:
|
||||
.Bl -tag width Ds
|
||||
.It Fl F Ar part , Fl -filter Ar part
|
||||
Least important version part
|
||||
.Po
|
||||
major,
|
||||
minor,
|
||||
patch
|
||||
.Pc
|
||||
change to be displayed.
|
||||
Version part matching is implemented very roughly
|
||||
and can lead to false matches.
|
||||
.El
|
||||
.
|
||||
.It Ic stabilization Pq alias: Ic stab , Ic s
|
||||
Find stabilization candidates.
|
||||
.El
|
||||
|
@ -133,8 +155,28 @@ This module uses Repology API to find work.
|
|||
.Ar command
|
||||
can be one of the following:
|
||||
.Bl -tag -width Ds
|
||||
.It Ic outdated Pq alias: Ic out , Ic o
|
||||
.It Xo
|
||||
.Ic outdated
|
||||
.Fl F Ar part
|
||||
.Xc
|
||||
.Dl Pq alias: Ic out , Ic o
|
||||
.Pp
|
||||
Find outdated packages.
|
||||
.Pp
|
||||
This command accepts the following options:
|
||||
.Bl -tag width Ds
|
||||
.It Fl F Ar part , Fl -filter Ar part
|
||||
Least important version part
|
||||
.Po
|
||||
major,
|
||||
minor,
|
||||
patch
|
||||
.Pc
|
||||
change to be displayed.
|
||||
Version part matching is implemented very roughly
|
||||
and can lead to false matches.
|
||||
.El
|
||||
.
|
||||
.El
|
||||
.Pp
|
||||
The options for
|
||||
|
|
Loading…
Reference in New Issue