Add changes required by Nimble lock file support (#12104)

Implemented support for Nimble local cache with package directories with
a checksum of the package at the end of their names. Now the compiler
supports package paths in the form:

 * /path_to_nimble_cache_dir/pkgs/package_name-1.2.3-
FEBADEAEA2345E777F0F6F8433F7F0A52EDD5D1B

 * /path_to_nimble_cache_dir/pkgs/package_name-#head-
042D4BE2B90ED0672E717D71850ABDB0A2D19CD2

 * /path_to_nimble_cache_dir/pkgs/package_name-#branch-name-
DBC1F902CB79946E990E38AF51F0BAD36ACFABD9

Related to nim-lang/nimble#127
This commit is contained in:
Ivan Bobev 2021-07-15 23:13:01 +03:00 • committed by GitHub
commit 5e6680406f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 135 additions and 50 deletions

View file

@ -9,8 +9,8 @@
## Implements some helper procs for Nimble (Nim's package manager) support.
import parseutils, strutils, strtabs, os, options, msgs, sequtils,
lineinfos, pathutils
import parseutils, strutils, os, options, msgs, sequtils, lineinfos, pathutils,
std/sha1, tables
proc addPath*(conf: ConfigRef; path: AbsoluteDir, info: TLineInfo) =
if not conf.searchPaths.contains(path):
@ -18,6 +18,7 @@ proc addPath*(conf: ConfigRef; path: AbsoluteDir, info: TLineInfo) =
type
Version* = distinct string
PackageInfo = Table[string, tuple[version, checksum: string]]
proc `$`*(ver: Version): string {.borrow.}
@ -62,43 +63,64 @@ proc `<`*(ver: Version, ver2: Version): bool =
else:
return false
proc getPathVersion*(p: string): tuple[name, version: string] =
## Splits path ``p`` in the format ``/home/user/.nimble/pkgs/package-0.1``
## into ``(/home/user/.nimble/pkgs/package, 0.1)``
result.name = ""
result.version = ""
proc getPathVersionChecksum*(p: string): tuple[name, version, checksum: string] =
## Splits path ``p`` in the format
## ``/home/user/.nimble/pkgs/package-0.1-febadeaea2345e777f0f6f8433f7f0a52edd5d1b`` into
## ``("/home/user/.nimble/pkgs/package", "0.1", "febadeaea2345e777f0f6f8433f7f0a52edd5d1b")``
const specialSeparator = "-#"
let last = p.rfind(p.lastPathPart) # the index where the last path part begins
var sepIdx = p.find(specialSeparator, start = last)
if sepIdx == -1:
sepIdx = p.rfind('-', start = last)
const checksumSeparator = '-'
const versionSeparator = '-'
const specialVersionSepartator = "-#"
const separatorNotFound = -1
if sepIdx == -1:
result.name = p
return
var checksumSeparatorIndex = p.rfind(checksumSeparator)
if checksumSeparatorIndex != separatorNotFound:
result.checksum = p.substr(checksumSeparatorIndex + 1)
if not result.checksum.isValidSha1Hash():
result.checksum = ""
checksumSeparatorIndex = p.len()
else:
checksumSeparatorIndex = p.len()
for i in sepIdx..<p.len:
if p[i] in {DirSep, AltSep}:
result.name = p
return
var versionSeparatorIndex = p.rfind(
specialVersionSepartator, 0, checksumSeparatorIndex - 1)
if versionSeparatorIndex != separatorNotFound:
result.version = p.substr(
versionSeparatorIndex + 1, checksumSeparatorIndex - 1)
else:
versionSeparatorIndex = p.rfind(
versionSeparator, 0, checksumSeparatorIndex - 1)
if versionSeparatorIndex != separatorNotFound:
result.version = p.substr(
versionSeparatorIndex + 1, checksumSeparatorIndex - 1)
else:
versionSeparatorIndex = checksumSeparatorIndex
result.name = p[0..sepIdx - 1]
result.version = p.substr(sepIdx + 1)
result.name = p[0..<versionSeparatorIndex]
proc addPackage(conf: ConfigRef; packages: StringTableRef, p: string; info: TLineInfo) =
let (name, ver) = getPathVersion(p)
proc addPackage*(conf: ConfigRef; packages: var PackageInfo, p: string;
info: TLineInfo) =
let (name, ver, checksum) = getPathVersionChecksum(p)
if isValidVersion(ver):
let version = newVersion(ver)
if packages.getOrDefault(name).newVersion < version or
if packages.getOrDefault(name).version.newVersion < version or
(not packages.hasKey(name)):
packages[name] = $version
if checksum.isValidSha1Hash():
packages[name] = ($version, checksum)
else:
packages[name] = ($version, "")
else:
localError(conf, info, "invalid package name: " & p)
iterator chosen(packages: StringTableRef): string =
iterator chosen(packages: PackageInfo): string =
for key, val in pairs(packages):
let res = if val.len == 0: key else: key & '-' & val
var res = key
if val.version.len != 0:
res &= '-'
res &= val.version
if val.checksum.len != 0:
res &= '-'
res &= val.checksum
yield res
proc addNimblePath(conf: ConfigRef; p: string, info: TLineInfo) =
@ -118,7 +140,7 @@ proc addNimblePath(conf: ConfigRef; p: string, info: TLineInfo) =
conf.lazyPaths.insert(AbsoluteDir path, 0)
proc addPathRec(conf: ConfigRef; dir: string, info: TLineInfo) =
var packages = newStringTable(modeStyleInsensitive)
var packages: PackageInfo
var pos = dir.len-1
if dir[pos] in {DirSep, AltSep}: inc(pos)
for k,p in os.walkDir(dir):