117 lines
3.9 KiB
Nim
117 lines
3.9 KiB
Nim
# Copyright (C) Dominik Picheta. All rights reserved.
|
|
# BSD License. Look at license.txt for more info.
|
|
|
|
import parseutils, os, osproc, strutils, tables
|
|
|
|
import packageinfo, common, version, tools
|
|
|
|
type
|
|
TDownloadMethod {.pure.} = enum
|
|
Git = "git", Hg = "hg"
|
|
|
|
proc getSpecificDir(meth: TDownloadMethod): string =
|
|
case meth
|
|
of TDownloadMethod.Git:
|
|
".git"
|
|
of TDownloadMethod.Hg:
|
|
".hg"
|
|
|
|
proc doCheckout(meth: TDownloadMethod, downloadDir, branch: string) =
|
|
case meth
|
|
of TDownloadMethod.Git:
|
|
cd downloadDir:
|
|
doCmd("git checkout " & branch)
|
|
of TDownloadMethod.Hg:
|
|
cd downloadDir:
|
|
doCmd("hg checkout " & branch)
|
|
|
|
proc doPull(meth: TDownloadMethod, downloadDir: string) =
|
|
case meth
|
|
of TDownloadMethod.Git:
|
|
doCheckout(meth, downloadDir, "master")
|
|
cd downloadDir:
|
|
doCmd("git pull")
|
|
of TDownloadMethod.Hg:
|
|
doCheckout(meth, downloadDir, "default")
|
|
cd downloadDir:
|
|
doCmd("hg pull")
|
|
|
|
proc doClone(meth: TDownloadMethod, url, downloadDir: string) =
|
|
case meth
|
|
of TDownloadMethod.Git:
|
|
doCmd("git clone --depth 1 " & url & " " & downloadDir)
|
|
of TDownloadMethod.Hg:
|
|
doCmd("hg clone -r tip " & url & " " & downloadDir)
|
|
|
|
proc getTagsList(dir: string, meth: TDownloadMethod): seq[string] =
|
|
cd dir:
|
|
var output = execProcess("git tag")
|
|
case meth
|
|
of TDownloadMethod.Git:
|
|
output = execProcess("git tag")
|
|
of TDownloadMethod.Hg:
|
|
output = execProcess("hg tags")
|
|
if output.len > 0:
|
|
case meth
|
|
of TDownloadMethod.Git:
|
|
result = output.splitLines()
|
|
of TDownloadMethod.Hg:
|
|
result = @[]
|
|
for i in output.splitLines():
|
|
var tag = ""
|
|
discard parseUntil(i, tag, ' ')
|
|
if tag != "tip":
|
|
result.add(tag)
|
|
else:
|
|
result = @[]
|
|
|
|
proc getVersionList(dir: string,
|
|
meth: TDownloadMethod): TTable[TVersion, string] =
|
|
# Returns: TTable of version -> git tag name
|
|
result = initTable[TVersion, string]()
|
|
let tags = getTagsList(dir, meth)
|
|
for tag in tags:
|
|
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 .. -1])] = tag
|
|
|
|
proc getDownloadMethod(meth: string): TDownloadMethod =
|
|
case meth
|
|
of "git": return TDownloadMethod.Git
|
|
of "hg", "mercurial": return TDownloadMethod.Hg
|
|
else:
|
|
raise newException(EBabel, "Invalid download method: " & meth)
|
|
|
|
proc doDownload*(pkg: TPackage, downloadDir: string, verRange: PVersionRange) =
|
|
let downMethod = pkg.downloadMethod.getDownloadMethod()
|
|
echo "Executing ", downMethod, "..."
|
|
|
|
if existsDir(downloadDir / getSpecificDir(downMethod)):
|
|
doPull(downMethod, downloadDir)
|
|
else:
|
|
removeDir(downloadDir)
|
|
doClone(downMethod, pkg.url, downloadDir)
|
|
|
|
# TODO: Determine if version is a commit hash, if it is. Move the
|
|
# git repo to ``babelDir/pkgs``, then babel can simply checkout
|
|
# the correct hash instead of constantly cloning and copying.
|
|
# N.B. This may still partly be required, 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, downMethod)
|
|
if versions.len > 0:
|
|
echo("Found tags...")
|
|
var latest = findLatest(verRange, versions)
|
|
## Note: HEAD is not used when verRange.kind is verAny. This is
|
|
## intended behaviour, the latest tagged version will be used in this case.
|
|
if latest.tag != "":
|
|
echo("Switching to latest tagged version: ", latest.tag)
|
|
doCheckout(downMethod, downloadDir, 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
|