Refactored a lot of code -- split many functions into separate module.
This commit is contained in:
parent
5e01fa0342
commit
f46fcaf6d3
4 changed files with 134 additions and 114 deletions
164
babel.nim
164
babel.nim
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import httpclient, parseopt, os, strutils, osproc, pegs, tables, parseutils
|
import httpclient, parseopt, os, strutils, osproc, pegs, tables, parseutils
|
||||||
|
|
||||||
import packageinfo, version
|
import packageinfo, version, common, tools
|
||||||
|
|
||||||
type
|
type
|
||||||
TActionType = enum
|
TActionType = enum
|
||||||
|
|
@ -18,19 +18,17 @@ type
|
||||||
optionalName: seq[string] # When this is @[], installs package from current dir.
|
optionalName: seq[string] # When this is @[], installs package from current dir.
|
||||||
of ActionSearch:
|
of ActionSearch:
|
||||||
search: seq[string] # Search string.
|
search: seq[string] # Search string.
|
||||||
|
|
||||||
EBabel = object of EBase
|
|
||||||
|
|
||||||
const
|
const
|
||||||
help = """
|
help = """
|
||||||
Usage: babel COMMAND [opts]
|
Usage: babel COMMAND [opts]
|
||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
install Installs a list of packages.
|
install [pkgname, ...] Installs a list of packages.
|
||||||
build Builds a package.
|
build [pkgname] Builds a package.
|
||||||
update Updates package list. A package list URL can be optionally specificed.
|
update [url] Updates package list. A package list URL can be optionally specified.
|
||||||
search Searches for a specified package.
|
search pkg/tag Searches for a specified package. Search is performed by tag and by name.
|
||||||
list Lists all packages.
|
list Lists all packages.
|
||||||
"""
|
"""
|
||||||
babelVersion = "0.1.0"
|
babelVersion = "0.1.0"
|
||||||
defaultPackageURL = "https://github.com/nimrod-code/packages/raw/master/packages.json"
|
defaultPackageURL = "https://github.com/nimrod-code/packages/raw/master/packages.json"
|
||||||
|
|
@ -95,13 +93,6 @@ proc prompt(question: string): bool =
|
||||||
else:
|
else:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
proc getNimrodVersion: TVersion =
|
|
||||||
let vOutput = execProcess("nimrod -v")
|
|
||||||
var matches: array[0..MaxSubpatterns, string]
|
|
||||||
if vOutput.find(peg"'Version'\s{(\d\.)+\d}", matches) == -1:
|
|
||||||
quit("Couldn't find Nimrod version.", QuitFailure)
|
|
||||||
newVersion(matches[0])
|
|
||||||
|
|
||||||
let babelDir = getHomeDir() / ".babel"
|
let babelDir = getHomeDir() / ".babel"
|
||||||
let libsDir = babelDir / "libs"
|
let libsDir = babelDir / "libs"
|
||||||
let binDir = babelDir / "bin"
|
let binDir = babelDir / "bin"
|
||||||
|
|
@ -112,40 +103,18 @@ proc update(url: string = defaultPackageURL) =
|
||||||
downloadFile(url, babelDir / "packages.json")
|
downloadFile(url, babelDir / "packages.json")
|
||||||
echo("Done.")
|
echo("Done.")
|
||||||
|
|
||||||
proc findBabelFile(dir: string): string =
|
|
||||||
result = ""
|
|
||||||
for kind, path in walkDir(dir):
|
|
||||||
if kind == pcFile and path.splitFile.ext == ".babel":
|
|
||||||
if result != "": quit("Only one .babel file should be present in " & dir)
|
|
||||||
result = path
|
|
||||||
|
|
||||||
proc copyFileD(fro, to: string) =
|
proc copyFileD(fro, to: string) =
|
||||||
echo(fro, " -> ", to)
|
echo(fro, " -> ", to)
|
||||||
copyFile(fro, to)
|
copyFile(fro, to)
|
||||||
|
|
||||||
proc samePaths(p1, p2: string): bool =
|
|
||||||
## Normalizes path (by adding a trailing slash) and compares.
|
|
||||||
let cp1 = if not p1.endsWith("/"): p1 & "/" else: p1
|
|
||||||
let cp2 = if not p2.endsWith("/"): p2 & "/" else: p2
|
|
||||||
return cmpPaths(cp1, cp2) == 0
|
|
||||||
|
|
||||||
proc changeRoot(origRoot, newRoot, path: string): string =
|
|
||||||
## origRoot: /home/dom/
|
|
||||||
## newRoot: /home/test/
|
|
||||||
## path: /home/dom/bar/blah/2/foo.txt
|
|
||||||
## Return value -> /home/test/bar/blah/2/foo.txt
|
|
||||||
if path.startsWith(origRoot):
|
|
||||||
return newRoot / path[origRoot.len .. -1]
|
|
||||||
else:
|
|
||||||
raise newException(EInvalidValue,
|
|
||||||
"Cannot change root of path: Path does not begin with original root.")
|
|
||||||
|
|
||||||
proc doCmd(cmd: string) =
|
proc doCmd(cmd: string) =
|
||||||
let exitCode = execCmd(cmd)
|
let exitCode = execCmd(cmd)
|
||||||
if exitCode != QuitSuccess:
|
if exitCode != QuitSuccess:
|
||||||
quit("Execution failed with exit code " & $exitCode, QuitFailure)
|
quit("Execution failed with exit code " & $exitCode, QuitFailure)
|
||||||
|
|
||||||
proc copyFilesRec(origDir, currentDir, dest: string, pkgInfo: TPackageInfo) =
|
proc copyFilesRec(origDir, currentDir, dest: string, pkgInfo: TPackageInfo) =
|
||||||
|
## Used for library-only packages. Copies all the required files, skips
|
||||||
|
## files specified in the .babel file.
|
||||||
for kind, file in walkDir(currentDir):
|
for kind, file in walkDir(currentDir):
|
||||||
if kind == pcDir:
|
if kind == pcDir:
|
||||||
var skip = false
|
var skip = false
|
||||||
|
|
@ -168,7 +137,7 @@ proc copyFilesRec(origDir, currentDir, dest: string, pkgInfo: TPackageInfo) =
|
||||||
if file.splitFile().name[0] == '.': skip = true
|
if file.splitFile().name[0] == '.': skip = true
|
||||||
for ignoreFile in pkgInfo.skipFiles:
|
for ignoreFile in pkgInfo.skipFiles:
|
||||||
if ignoreFile.endswith("babel"):
|
if ignoreFile.endswith("babel"):
|
||||||
quit(ignoreFile & " must be installed.")
|
raise newException(EBabel, ignoreFile & " must be installed.")
|
||||||
if samePaths(file, origDir / ignoreFile):
|
if samePaths(file, origDir / ignoreFile):
|
||||||
skip = true
|
skip = true
|
||||||
break
|
break
|
||||||
|
|
@ -176,59 +145,30 @@ proc copyFilesRec(origDir, currentDir, dest: string, pkgInfo: TPackageInfo) =
|
||||||
if not skip:
|
if not skip:
|
||||||
copyFileD(file, changeRoot(origDir, dest, file))
|
copyFileD(file, changeRoot(origDir, dest, file))
|
||||||
|
|
||||||
proc getPkgInfo(dir: string): TPackageInfo =
|
|
||||||
let babelFile = findBabelFile(dir)
|
|
||||||
if babelFile == "":
|
|
||||||
quit("Specified directory does not contain a .babel file.", QuitFailure)
|
|
||||||
result = readPackageInfo(babelFile)
|
|
||||||
|
|
||||||
# TODO: Move to packageinfo.nim
|
|
||||||
|
|
||||||
proc getInstalledPkgs(): seq[tuple[path: string, info: TPackageInfo]] =
|
|
||||||
## Gets a list of installed packages
|
|
||||||
result = @[]
|
|
||||||
for kind, path in walkDir(libsDir):
|
|
||||||
if kind == pcDir:
|
|
||||||
let babelFile = findBabelFile(path)
|
|
||||||
if babelFile != "":
|
|
||||||
result.add((path, readPackageInfo(babelFile)))
|
|
||||||
else:
|
|
||||||
# TODO: Abstract logging.
|
|
||||||
echo("WARNING: No .babel file found for ", path)
|
|
||||||
|
|
||||||
proc findPkg(pkglist: seq[tuple[path: string, info: TPackageInfo]],
|
|
||||||
dep: tuple[name: string, ver: PVersionRange],
|
|
||||||
r: var tuple[path: string, info: TPackageInfo]): bool =
|
|
||||||
for pkg in pkglist:
|
|
||||||
if pkg.info.name != dep.name: continue
|
|
||||||
if withinRange(newVersion(pkg.info.version), dep.ver):
|
|
||||||
if not result or newVersion(r.info.version) < newVersion(pkg.info.version):
|
|
||||||
r = pkg
|
|
||||||
result = true
|
|
||||||
|
|
||||||
proc install(packages: seq[String], verRange: PVersionRange): string {.discardable.}
|
proc install(packages: seq[String], verRange: PVersionRange): string {.discardable.}
|
||||||
proc processDeps(pkginfo: TPackageInfo): seq[string] =
|
proc processDeps(pkginfo: TPackageInfo): seq[string] =
|
||||||
## Verifies and installs dependencies.
|
## Verifies and installs dependencies.
|
||||||
##
|
##
|
||||||
## Returns the list of paths to pass to the compiler during build phase.
|
## Returns the list of paths to pass to the compiler during build phase.
|
||||||
result = @[]
|
result = @[]
|
||||||
let pkglist = getInstalledPkgs()
|
let pkglist = getInstalledPkgs(libsDir)
|
||||||
for dep in pkginfo.requires:
|
for dep in pkginfo.requires:
|
||||||
if dep.name == "nimrod":
|
if dep.name == "nimrod":
|
||||||
if not withinRange(nimVer, dep.ver):
|
if not withinRange(nimVer, dep.ver):
|
||||||
quit("Unsatisfied dependency: " & dep.name & " (" & $dep.ver & ")")
|
quit("Unsatisfied dependency: " & dep.name & " (" & $dep.ver & ")")
|
||||||
else:
|
else:
|
||||||
echo("Looking for ", dep.name, " (", $dep.ver, ")...")
|
echo("Looking for ", dep.name, " (", $dep.ver, ")...")
|
||||||
var pkg: tuple[path: string, info: TPackageInfo]
|
var pkg: TPackageInfo
|
||||||
if not findPkg(pkglist, dep, pkg):
|
if not findPkg(pkglist, dep, pkg):
|
||||||
|
echo("None found, installing...")
|
||||||
let dest = install(@[dep.name], dep.ver)
|
let dest = install(@[dep.name], dep.ver)
|
||||||
if dest != "":
|
if dest != "":
|
||||||
# only add if not a binary package
|
# only add if not a binary package
|
||||||
result.add(dest)
|
result.add(dest)
|
||||||
else:
|
else:
|
||||||
echo("Dependency already satisfied.")
|
echo("Dependency already satisfied.")
|
||||||
if pkg.info.bin.len == 0:
|
if pkg.bin.len == 0:
|
||||||
result.add(pkg.path)
|
result.add(pkg.mypath.splitFile.dir)
|
||||||
|
|
||||||
proc buildFromDir(dir: string, paths: seq[string]) =
|
proc buildFromDir(dir: string, paths: seq[string]) =
|
||||||
## Builds a package which resides in ``dir``
|
## Builds a package which resides in ``dir``
|
||||||
|
|
@ -237,7 +177,6 @@ proc buildFromDir(dir: string, paths: seq[string]) =
|
||||||
for path in paths: args.add("--path:" & path & " ")
|
for path in paths: args.add("--path:" & path & " ")
|
||||||
for bin in pkgInfo.bin:
|
for bin in pkgInfo.bin:
|
||||||
echo("Building ", pkginfo.name, "/", bin, "...")
|
echo("Building ", pkginfo.name, "/", bin, "...")
|
||||||
echo(args)
|
|
||||||
doCmd("nimrod c -d:release " & args & dir / bin)
|
doCmd("nimrod c -d:release " & args & dir / bin)
|
||||||
|
|
||||||
proc installFromDir(dir: string, latest: bool): string =
|
proc installFromDir(dir: string, latest: bool): string =
|
||||||
|
|
@ -273,11 +212,6 @@ proc installFromDir(dir: string, latest: bool): string =
|
||||||
echo(pkgInfo.name & " installed successfully.")
|
echo(pkgInfo.name & " installed successfully.")
|
||||||
result = pkgDestDir
|
result = pkgDestDir
|
||||||
|
|
||||||
proc getDVCSTag(pkg: TPackage): string =
|
|
||||||
result = pkg.dvcsTag
|
|
||||||
if result == "":
|
|
||||||
result = pkg.version
|
|
||||||
|
|
||||||
proc getTagsList(dir: string): seq[string] =
|
proc getTagsList(dir: string): seq[string] =
|
||||||
let output = execProcess("cd \"" & dir & "\" && git tag")
|
let output = execProcess("cd \"" & dir & "\" && git tag")
|
||||||
if output.len > 0:
|
if output.len > 0:
|
||||||
|
|
@ -294,6 +228,42 @@ proc getVersionList(dir: string): TTable[TVersion, string] =
|
||||||
# TODO: Better checking, tags can have any names. Add warnings and such.
|
# TODO: Better checking, tags can have any names. Add warnings and such.
|
||||||
result[newVersion(tag[i .. -1])] = tag
|
result[newVersion(tag[i .. -1])] = tag
|
||||||
|
|
||||||
|
proc downloadPkg(pkg: TPackage, verRange: PVersionRange): string =
|
||||||
|
let downloadDir = (getTempDir() / "babel" / pkg.name)
|
||||||
|
echo("Downloading ", pkg.name, " into ", downloadDir, "...")
|
||||||
|
case pkg.downloadMethod
|
||||||
|
of "git":
|
||||||
|
echo("Executing git...")
|
||||||
|
if existsDir(downloadDir / ".git"):
|
||||||
|
doCmd("cd " & downloadDir & " && git pull")
|
||||||
|
else:
|
||||||
|
removeDir(downloadDir)
|
||||||
|
doCmd("git clone --depth 1 " & pkg.url & " " & downloadDir)
|
||||||
|
|
||||||
|
# TODO: Determine if version is a commit hash, if it is. Move the
|
||||||
|
# git repo to ``babelDir/libs``, then babel can simply checkout
|
||||||
|
# the correct hash instead of constantly cloning and copying.
|
||||||
|
# N.B. This may still partly be requires, as one lib may require hash A
|
||||||
|
# whereas another lib requires hash B and they are both required by the
|
||||||
|
# project you want to build.
|
||||||
|
let versions = getVersionList(downloadDir)
|
||||||
|
if versions.len > 0:
|
||||||
|
let latest = findLatest(verRange, versions)
|
||||||
|
|
||||||
|
if latest.tag != "":
|
||||||
|
doCmd("cd \"" & downloadDir & "\" && git checkout " & latest.tag)
|
||||||
|
elif verRange.kind != verAny:
|
||||||
|
let pkginfo = getPkgInfo(downloadDir)
|
||||||
|
if pkginfo.version.newVersion notin verRange:
|
||||||
|
raise newException(EBabel,
|
||||||
|
"No versions of " & pkg.name &
|
||||||
|
" exist (this usually means that `git tag` returned nothing)." &
|
||||||
|
"Git HEAD also does not satisfy version range: " & $verRange)
|
||||||
|
# We use GIT HEAD if it satisfies our ver range
|
||||||
|
|
||||||
|
else: raise newException(EBabel, "Unknown download method: " & pkg.downloadMethod)
|
||||||
|
result = downloadDir
|
||||||
|
|
||||||
proc install(packages: seq[String], verRange: PVersionRange): string =
|
proc install(packages: seq[String], verRange: PVersionRange): string =
|
||||||
if packages == @[]:
|
if packages == @[]:
|
||||||
result = installFromDir(getCurrentDir(), false)
|
result = installFromDir(getCurrentDir(), false)
|
||||||
|
|
@ -303,37 +273,7 @@ proc install(packages: seq[String], verRange: PVersionRange): string =
|
||||||
for p in packages:
|
for p in packages:
|
||||||
var pkg: TPackage
|
var pkg: TPackage
|
||||||
if getPackage(p, babelDir / "packages.json", pkg):
|
if getPackage(p, babelDir / "packages.json", pkg):
|
||||||
let downloadDir = (getTempDir() / "babel" / pkg.name)
|
let downloadDir = downloadPkg(pkg, verRange)
|
||||||
#let dvcsTag = getDVCSTag(pkg)
|
|
||||||
case pkg.downloadMethod
|
|
||||||
of "git":
|
|
||||||
echo("Executing git...")
|
|
||||||
if existsDir(downloadDir / ".git"):
|
|
||||||
doCmd("cd " & downloadDir & " && git pull")
|
|
||||||
else:
|
|
||||||
removeDir(downloadDir)
|
|
||||||
doCmd("git clone --depth 1 " & pkg.url & " " & downloadDir)
|
|
||||||
|
|
||||||
# TODO: Determine if version is a commit hash, if it is. Move the
|
|
||||||
# git repo to ``babelDir/libs``, then babel can simply checkout
|
|
||||||
# the correct hash instead of constantly cloning and copying.
|
|
||||||
let versions = getVersionList(downloadDir)
|
|
||||||
if versions.len > 0:
|
|
||||||
let latest = findLatest(verRange, versions)
|
|
||||||
|
|
||||||
if latest.tag != "":
|
|
||||||
doCmd("cd \"" & downloadDir & "\" && git checkout " & latest.tag)
|
|
||||||
elif verRange.kind != verAny:
|
|
||||||
let pkginfo = getPkgInfo(downloadDir)
|
|
||||||
if pkginfo.version.newVersion notin verRange:
|
|
||||||
raise newException(EBabel,
|
|
||||||
"No versions of " & pkg.name &
|
|
||||||
" exist (this usually means that `git tag` returned nothing)." &
|
|
||||||
"Git HEAD also does not satisfy version range: " & $verRange)
|
|
||||||
# We use GIT HEAD if it satisfies our ver range
|
|
||||||
|
|
||||||
else: quit("Unknown download method: " & pkg.downloadMethod, QuitFailure)
|
|
||||||
|
|
||||||
result = installFromDir(downloadDir, false)
|
result = installFromDir(downloadDir, false)
|
||||||
else:
|
else:
|
||||||
raise newException(EBabel, "Package not found.")
|
raise newException(EBabel, "Package not found.")
|
||||||
|
|
@ -359,7 +299,7 @@ proc search(action: TAction) =
|
||||||
notFound = false
|
notFound = false
|
||||||
break
|
break
|
||||||
if notFound:
|
if notFound:
|
||||||
# Search by tag.
|
# Search by name.
|
||||||
for pkg in pkgList:
|
for pkg in pkgList:
|
||||||
if pkg.name in action.search:
|
if pkg.name in action.search:
|
||||||
echoPackage(pkg)
|
echoPackage(pkg)
|
||||||
|
|
|
||||||
4
common.nim
Normal file
4
common.nim
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Copyright (C) Dominik Picheta. All rights reserved.
|
||||||
|
# BSD License. Look at license.txt for more info.
|
||||||
|
type
|
||||||
|
EBabel* = object of EBase
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
# Copyright (C) Dominik Picheta. All rights reserved.
|
# Copyright (C) Dominik Picheta. All rights reserved.
|
||||||
# BSD License. Look at license.txt for more info.
|
# BSD License. Look at license.txt for more info.
|
||||||
import parsecfg, json, streams, strutils, parseutils
|
import parsecfg, json, streams, strutils, parseutils, os
|
||||||
import version
|
import version, common
|
||||||
type
|
type
|
||||||
TPackageInfo* = object
|
TPackageInfo* = object
|
||||||
|
mypath*: string ## The path of this .babel file
|
||||||
name*: string
|
name*: string
|
||||||
version*: string
|
version*: string
|
||||||
author*: string
|
author*: string
|
||||||
|
|
@ -25,6 +26,7 @@ type
|
||||||
description*: string
|
description*: string
|
||||||
|
|
||||||
proc initPackageInfo(): TPackageInfo =
|
proc initPackageInfo(): TPackageInfo =
|
||||||
|
result.mypath = ""
|
||||||
result.name = ""
|
result.name = ""
|
||||||
result.version = ""
|
result.version = ""
|
||||||
result.author = ""
|
result.author = ""
|
||||||
|
|
@ -61,6 +63,7 @@ proc parseRequires(req: string): tuple[name: string, ver: PVersionRange] =
|
||||||
|
|
||||||
proc readPackageInfo*(path: string): TPackageInfo =
|
proc readPackageInfo*(path: string): TPackageInfo =
|
||||||
result = initPackageInfo()
|
result = initPackageInfo()
|
||||||
|
result.mypath = path
|
||||||
var fs = newFileStream(path, fmRead)
|
var fs = newFileStream(path, fmRead)
|
||||||
if fs != nil:
|
if fs != nil:
|
||||||
var p: TCfgParser
|
var p: TCfgParser
|
||||||
|
|
@ -157,6 +160,49 @@ proc getPackageList*(packagesPath: string): seq[TPackage] =
|
||||||
pkg.description = p.requiredField("description")
|
pkg.description = p.requiredField("description")
|
||||||
result.add(pkg)
|
result.add(pkg)
|
||||||
|
|
||||||
|
proc findBabelFile*(dir: string): string =
|
||||||
|
result = ""
|
||||||
|
for kind, path in walkDir(dir):
|
||||||
|
if kind == pcFile and path.splitFile.ext == ".babel":
|
||||||
|
if result != "":
|
||||||
|
raise newException(EBabel, "Only one .babel file should be present in " & dir)
|
||||||
|
result = path
|
||||||
|
|
||||||
|
proc getPkgInfo*(dir: string): TPackageInfo =
|
||||||
|
## Find the .babel file in ``dir`` and parses it, returning a TPackageInfo.
|
||||||
|
let babelFile = findBabelFile(dir)
|
||||||
|
if babelFile == "":
|
||||||
|
quit("Specified directory does not contain a .babel file.", QuitFailure)
|
||||||
|
result = readPackageInfo(babelFile)
|
||||||
|
|
||||||
|
proc getInstalledPkgs*(libsDir: string): seq[TPackageInfo] =
|
||||||
|
## Gets a list of installed packages.
|
||||||
|
##
|
||||||
|
## ``libsDir`` is in most cases: ~/.babel/libs/
|
||||||
|
result = @[]
|
||||||
|
for kind, path in walkDir(libsDir):
|
||||||
|
if kind == pcDir:
|
||||||
|
let babelFile = findBabelFile(path)
|
||||||
|
if babelFile != "":
|
||||||
|
result.add(readPackageInfo(babelFile))
|
||||||
|
else:
|
||||||
|
# TODO: Abstract logging.
|
||||||
|
echo("WARNING: No .babel file found for ", path)
|
||||||
|
|
||||||
|
proc findPkg*(pkglist: seq[TPackageInfo],
|
||||||
|
dep: tuple[name: string, ver: PVersionRange],
|
||||||
|
r: var TPackageInfo): bool =
|
||||||
|
## Searches ``pkglist`` for a package of which version is withing the range
|
||||||
|
## of ``dep.ver``. ``True`` is returned if a package is found. If multiple
|
||||||
|
## packages are found the newest one is returned (the one with the highest
|
||||||
|
## version number)
|
||||||
|
for pkg in pkglist:
|
||||||
|
if pkg.name != dep.name: continue
|
||||||
|
if withinRange(newVersion(pkg.version), dep.ver):
|
||||||
|
if not result or newVersion(r.version) < newVersion(pkg.version):
|
||||||
|
r = pkg
|
||||||
|
result = true
|
||||||
|
|
||||||
proc echoPackage*(pkg: TPackage) =
|
proc echoPackage*(pkg: TPackage) =
|
||||||
echo(pkg.name & ":")
|
echo(pkg.name & ":")
|
||||||
if pkg.version != "":
|
if pkg.version != "":
|
||||||
|
|
|
||||||
30
tools.nim
Normal file
30
tools.nim
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Copyright (C) Dominik Picheta. All rights reserved.
|
||||||
|
# BSD License. Look at license.txt for more info.
|
||||||
|
#
|
||||||
|
# Various miscellaneous utility functions reside here.
|
||||||
|
import osproc, pegs, strutils, os
|
||||||
|
import version
|
||||||
|
|
||||||
|
proc getNimrodVersion*: TVersion =
|
||||||
|
let vOutput = execProcess("nimrod -v")
|
||||||
|
var matches: array[0..MaxSubpatterns, string]
|
||||||
|
if vOutput.find(peg"'Version'\s{(\d\.)+\d}", matches) == -1:
|
||||||
|
quit("Couldn't find Nimrod version.", QuitFailure)
|
||||||
|
newVersion(matches[0])
|
||||||
|
|
||||||
|
proc samePaths*(p1, p2: string): bool =
|
||||||
|
## Normalizes path (by adding a trailing slash) and compares.
|
||||||
|
let cp1 = if not p1.endsWith("/"): p1 & "/" else: p1
|
||||||
|
let cp2 = if not p2.endsWith("/"): p2 & "/" else: p2
|
||||||
|
return cmpPaths(cp1, cp2) == 0
|
||||||
|
|
||||||
|
proc changeRoot*(origRoot, newRoot, path: string): string =
|
||||||
|
## origRoot: /home/dom/
|
||||||
|
## newRoot: /home/test/
|
||||||
|
## path: /home/dom/bar/blah/2/foo.txt
|
||||||
|
## Return value -> /home/test/bar/blah/2/foo.txt
|
||||||
|
if path.startsWith(origRoot):
|
||||||
|
return newRoot / path[origRoot.len .. -1]
|
||||||
|
else:
|
||||||
|
raise newException(EInvalidValue,
|
||||||
|
"Cannot change root of path: Path does not begin with original root.")
|
||||||
Loading…
Add table
Add a link
Reference in a new issue