about summary refs log tree commit diff stats
path: root/dev/git/install.html
blob: 16311ede911a78f57c1cce1cb904e669ffb0d3a4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#
#
#           The Nim Compiler
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## Implements some helper procs for Nimble (Nim's package manager) support.

import parseutils, strutils, os, options, msgs, sequtils, lineinfos, pathutils,
  std/sha1, tables

proc addPath*
class="w"> info: TLineInfo) = if not conf.searchPaths.contains(path): conf.searchPaths.insert(path, 0) type Version* = distinct string PackageInfo = Table[string, tuple[version, checksum: string]] proc `$`*(ver: Version): string {.borrow.} proc newVersion*(ver: string): Version = doAssert(ver.len == 0 or ver[0] in {'#', '\0'} + Digits, "Wrong version: " & ver) return Version(ver) proc isSpecial(ver: Version): bool = return ($ver).len > 0 and ($ver)[0] == '#' proc isValidVersion(v: string): bool = if v.len > 0: if v[0] in {'#'} + Digits: return true proc `<`*(ver: Version, ver2: Version): bool = ## This is synced from Nimble's version module. # Handling for special versions such as "#head" or "#branch". if ver.isSpecial or ver2.isSpecial: if ver2.isSpecial and ($ver2).normalize == "#head": return ($ver).normalize != "#head" if not ver2.isSpecial: # `#aa111 < 1.1` return ($ver).normalize != "#head" # Handling for normal versions such as "0.1.0" or "1.0". var sVer = string(ver).split('.') var sVer2 = string(ver2).split('.') for i in 0..<max(sVer.len, sVer2.len): var sVerI = 0 if i < sVer.len: discard parseInt(sVer[i], sVerI) var sVerI2 = 0 if i < sVer2.len: discard parseInt(sVer2[i], sVerI2) if sVerI < sVerI2: return true elif sVerI == sVerI2: discard else: return false 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 checksumSeparator = '-' const versionSeparator = '-' const specialVersionSepartator = "-#" const separatorNotFound = -1 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() 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..<versionSeparatorIndex] 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).version.newVersion < version or (not packages.hasKey(name)): if checksum.isValidSha1Hash(): packages[name] = ($version, checksum) else: packages[name] = ($version, "") else: localError(conf, info, "invalid package name: " & p) iterator chosen(packages: PackageInfo): string = for key, val in pairs(packages): 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) = var path = p let nimbleLinks = toSeq(walkPattern(p / "*.nimble-link")) if nimbleLinks.len > 0: # If the user has more than one .nimble-link file then... we just ignore it. # Spec for these files is available in Nimble's readme: # https://github.com/nim-lang/nimble#nimble-link let nimbleLinkLines = readFile(nimbleLinks[0]).splitLines() path = nimbleLinkLines[1] if not path.isAbsolute(): path = p / path if not contains(conf.searchPaths, AbsoluteDir path): message(conf, info, hintPath, path) conf.lazyPaths.insert(AbsoluteDir path, 0) proc addPathRec(conf: ConfigRef; dir: string, info: TLineInfo) = var packages: PackageInfo var pos = dir.len-1 if dir[pos] in {DirSep, AltSep}: inc(pos) for k,p in os.walkDir(dir): if k == pcDir and p[pos] != '.': addPackage(conf, packages, p, info) for p in packages.chosen: addNimblePath(conf, p, info) proc nimblePath*(conf: ConfigRef; path: AbsoluteDir, info: TLineInfo) = addPathRec(conf, path.string, info) addNimblePath(conf, path.string, info) let i = conf.nimblePaths.find(path) if i != -1: conf.nimblePaths.delete(i) conf.nimblePaths.insert(path, 0)