Fix #567: Display package versions in sorted order (#688)

* Fix #567: Display package versions in sorted order

* Add docs

* Fix docs to focus on git tags

* Refactor to use version module

* Streamline docs

* Refactor to make things work in nim <= 0.19.6

* Improve code readability
This commit is contained in:
Hitesh Jasani 2019-08-24 05:15:29 -04:00 committed by Dominik Picheta
commit 2243e3fbc2
4 changed files with 63 additions and 20 deletions

View file

@ -786,6 +786,19 @@ To summarise, the steps for release are:
Once the new tag is in the remote repository, Nimble will be able to detect
the new version.
##### Git Version Tagging
Use dot separated numbers to represent the release version in the git
tag label. Nimble will parse these git tag labels to know which
versions of a package are published.
``` text
v0.2.0 # 0.2.0
v1 # 1
v1.2.3-zuzu # 1.2.3
foo-1.2.3.4 # 1.2.3.4
```
## Publishing packages
Publishing packages isn't a requirement. But doing so allows people to associate

View file

@ -2,8 +2,9 @@
# BSD License. Look at license.txt for more info.
import parseutils, os, osproc, strutils, tables, pegs, uri
import packageinfo, packageparser, version, tools, common, options, cli
from algorithm import SortOrder, sorted
from sequtils import toSeq, filterIt, map
type
DownloadMethod* {.pure.} = enum
@ -103,14 +104,21 @@ proc getTagsListRemote*(url: string, meth: DownloadMethod): seq[string] =
# http://stackoverflow.com/questions/2039150/show-tags-for-remote-hg-repository
raise newException(ValueError, "Hg doesn't support remote tag querying.")
proc getVersionList*(tags: seq[string]): Table[Version, string] =
# Returns: TTable of version -> git tag name
result = initTable[Version, string]()
for tag in tags:
if tag != "":
let i = skipUntil(tag, Digits) # skip any chars before the version
# TODO: Better checking, tags can have any names. Add warnings and such.
result[newVersion(tag[i .. tag.len-1])] = tag
proc getVersionList*(tags: seq[string]): OrderedTable[Version, string] =
## Return an ordered table of Version -> git tag label. Ordering is
## in descending order with the most recent version first.
let taggedVers: seq[tuple[ver: Version, tag: string]] =
tags
.filterIt(it != "")
.map(proc(s: string): tuple[ver: Version, tag: string] =
# skip any chars before the version
let i = skipUntil(s, Digits)
# TODO: Better checking, tags can have any
# names. Add warnings and such.
result = (newVersion(s[i .. s.len-1]), s))
.sorted(proc(a, b: (Version, string)): int = cmp(a[0], b[0]),
SortOrder.Descending)
result = toOrderedTable[Version, string](taggedVers)
proc getDownloadMethod*(meth: string): DownloadMethod =
case meth
@ -268,14 +276,8 @@ proc echoPackageVersions*(pkg: Package) =
try:
let versions = getTagsListRemote(pkg.url, downMethod).getVersionList()
if versions.len > 0:
var vstr = ""
var i = 0
for v in values(versions):
if i != 0:
vstr.add(", ")
vstr.add(v)
i.inc
echo(" versions: " & vstr)
let sortedVersions = toSeq(values(versions))
echo(" versions: " & join(sortedVersions, ", "))
else:
echo(" versions: (No versions tagged in the remote repository)")
except OSError:
@ -283,3 +285,19 @@ proc echoPackageVersions*(pkg: Package) =
of DownloadMethod.hg:
echo(" versions: (Remote tag retrieval not supported by " &
pkg.downloadMethod & ")")
when isMainModule:
# Test version sorting
block:
let data = @["v9.0.0-taeyeon", "v9.0.1-jessica", "v9.2.0-sunny",
"v9.4.0-tiffany", "v9.4.2-hyoyeon"]
let expected = toOrderedTable[Version, string]({
newVersion("9.4.2-hyoyeon"): "v9.4.2-hyoyeon",
newVersion("9.4.0-tiffany"): "v9.4.0-tiffany",
newVersion("9.2.0-sunny"): "v9.2.0-sunny",
newVersion("9.0.1-jessica"): "v9.0.1-jessica",
newVersion("9.0.0-taeyeon"): "v9.0.0-taeyeon"
})
doAssert expected == getVersionList(data)
echo("Everything works!")

View file

@ -93,6 +93,11 @@ proc `==`*(ver: Version, ver2: Version): bool =
else:
return false
proc cmp*(a, b: Version): int =
if a < b: -1
elif a > b: 1
else: 0
proc `<=`*(ver: Version, ver2: Version): bool =
return (ver == ver2) or (ver < ver2)
@ -272,7 +277,7 @@ proc newVREq*(ver: string): VersionRange =
result.ver = newVersion(ver)
proc findLatest*(verRange: VersionRange,
versions: Table[Version, string]): tuple[ver: Version, tag: string] =
versions: OrderedTable[Version, string]): tuple[ver: Version, tag: string] =
result = (newVersion(""), "")
for ver, tag in versions:
if not withinRange(ver, verRange): continue
@ -309,8 +314,11 @@ when isMainModule:
doAssert(newVersion("") < newVersion("1.0.0"))
doAssert(newVersion("") < newVersion("0.1.0"))
var versions = toTable[Version, string]({newVersion("0.1.1"): "v0.1.1",
newVersion("0.2.3"): "v0.2.3", newVersion("0.5"): "v0.5"})
var versions = toOrderedTable[Version, string]({
newVersion("0.1.1"): "v0.1.1",
newVersion("0.2.3"): "v0.2.3",
newVersion("0.5"): "v0.5"
})
doAssert findLatest(parseVersionRange(">= 0.1 & <= 0.4"), versions) ==
(newVersion("0.2.3"), "v0.2.3")

View file

@ -818,6 +818,10 @@ suite "Module tests":
cd "..":
check execCmdEx("nim c -r src/nimblepkg/cli").exitCode == QuitSuccess
test "download":
cd "..":
check execCmdEx("nim c -r src/nimblepkg/download").exitCode == QuitSuccess
test "init does not overwrite existing files (#581)":
createDir("issue581/src")
cd "issue581":