mirror of
https://gitlab.com/khumba/nvd.git
synced 2024-11-14 00:49:26 +01:00
Add semver sorting (issue #17).
This commit is contained in:
parent
4ae4ae9fae
commit
c0ed21c632
3 changed files with 72 additions and 2 deletions
|
@ -6,7 +6,8 @@
|
|||
profile, issue #18. Big thanks to Felix Uhl for the idea and implementation!
|
||||
|
||||
- Added `--sort` option for controlling the order packages are listed in, for
|
||||
issue #17.
|
||||
issue #17. Supported sort options are package name, and the level of semver
|
||||
version change.
|
||||
|
||||
- In the "Version changes" section of a diff, highlight the portions of version
|
||||
numbers that have changed, i.e., everything after the part common to all
|
||||
|
|
52
src/nvd
52
src/nvd
|
@ -253,6 +253,9 @@ class Version:
|
|||
"""Returns the version string, empty (not None) if there is no version."""
|
||||
return self._text
|
||||
|
||||
def chunks(self) -> list[VersionChunk]:
|
||||
return self._chunks
|
||||
|
||||
class Package:
|
||||
def __init__(self, *, pname: str, version: Version, store_path: StorePath):
|
||||
assert isinstance(pname, str), f"Not a string: {pname!r}"
|
||||
|
@ -405,6 +408,8 @@ class PackageListEntry:
|
|||
self._left_packages = left_packages
|
||||
self._right_packages = right_packages
|
||||
|
||||
self._first_changed_version_chunk: Optional[int] = None
|
||||
|
||||
def get_pname(self) -> str:
|
||||
if self._right_packages:
|
||||
return self._right_packages[0].pname()
|
||||
|
@ -417,6 +422,31 @@ class PackageListEntry:
|
|||
def get_right_packages(self) -> Optional[list[Package]]:
|
||||
return self._right_packages
|
||||
|
||||
def find_first_changed_version_chunk(self) -> int:
|
||||
"""
|
||||
Returns the position of the earliest version chunk that differs when
|
||||
comparing the maximum version on the left, with the maximum version on
|
||||
the right.
|
||||
"""
|
||||
|
||||
if self._right_packages is None:
|
||||
return 0
|
||||
|
||||
if self._first_changed_version_chunk is not None:
|
||||
return self._first_changed_version_chunk
|
||||
|
||||
max_left_ver = self.get_left_packages()[-1].version()
|
||||
max_right_ver = self.get_right_packages()[-1].version()
|
||||
chunks_in_common = 0
|
||||
for left_chunk, right_chunk in zip(max_left_ver.chunks(), max_right_ver.chunks()):
|
||||
if left_chunk == right_chunk:
|
||||
chunks_in_common += 1
|
||||
else:
|
||||
break
|
||||
|
||||
self._first_changed_version_chunk = chunks_in_common
|
||||
return chunks_in_common
|
||||
|
||||
class PackageListEntryComparator:
|
||||
@abstractmethod
|
||||
def name(self) -> str:
|
||||
|
@ -443,6 +473,8 @@ class PackageListEntryReverseComparator(PackageListEntryComparator):
|
|||
return self._delegate
|
||||
|
||||
class PackageListEntryNameComparator(PackageListEntryComparator):
|
||||
"""Sorts package list entries by pname."""
|
||||
|
||||
def name(self) -> str:
|
||||
return "name"
|
||||
|
||||
|
@ -452,11 +484,31 @@ class PackageListEntryNameComparator(PackageListEntryComparator):
|
|||
b.get_left_packages()[0].pname(),
|
||||
)
|
||||
|
||||
class PackageListEntrySemVerChangeComparator(PackageListEntryComparator):
|
||||
"""
|
||||
Sorts package list entries by the level of version change according to
|
||||
Semantic Versioning.
|
||||
|
||||
The maximum version on the left is compared with the maximum version on the
|
||||
right. Packages whose first version chunks differ are sorted first,
|
||||
followed by packages whose second chunks differ, and so on.
|
||||
"""
|
||||
|
||||
def name(self) -> str:
|
||||
return "semver"
|
||||
|
||||
def cmp_packages(self, a: PackageListEntry, b: PackageListEntry) -> int:
|
||||
return cmp(
|
||||
a.find_first_changed_version_chunk(),
|
||||
b.find_first_changed_version_chunk(),
|
||||
)
|
||||
|
||||
ALL_SORTS: dict[str, PackageListEntryComparator] = {
|
||||
sk.name(): sk
|
||||
for sk in (
|
||||
# The first one listed here is the default.
|
||||
PackageListEntryNameComparator(),
|
||||
PackageListEntrySemVerChangeComparator(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
19
src/nvd.1
19
src/nvd.1
|
@ -193,7 +193,24 @@ break ties, in order. Each keyword may be preceeded by a hyphen
|
|||
.B \-
|
||||
to reverse the regular sort order of the keyword. The default order is
|
||||
.B name,
|
||||
which sorts by package name. Currently only this keyword is supported.
|
||||
which sorts by package name.
|
||||
.IP
|
||||
The keyword
|
||||
.B semver
|
||||
sorts packages according to how significant their version changes are, by the
|
||||
rules of Semantic Versioning, when versions are being compared (with the
|
||||
.B diff
|
||||
and
|
||||
.B history
|
||||
commands). Each package's highest old version is compared with its highest new
|
||||
version. Packages where the first component of these two versions have changed
|
||||
are sorted first. Packages where the second version components differ are
|
||||
sorted second, and so on. Components here are consecutive runs of digits, or of
|
||||
letters (but not both), as per the Nix version handling rules. Only the
|
||||
position of the first difference is used; the numeric difference between version
|
||||
numbers does not matter. Because only the highest old and new versions are
|
||||
compared, this sort type may not produce ideal results if multiple versions of a
|
||||
package are present.
|
||||
.TP
|
||||
-r|--root <store-path>
|
||||
For the
|
||||
|
|
Loading…
Reference in a new issue