Add excludes to examples in readme
This commit is contained in:
parent
39b552c831
commit
2e2129e873
21
README.md
21
README.md
|
@ -12,13 +12,16 @@ nim_lk > lock.json
|
|||
These lock files contain Nix FOD store paths that can be converted to `nim.cfg` files.
|
||||
|
||||
```nix
|
||||
{ pkgs ? import <nixpkgs> { }, lockPath }:
|
||||
{ pkgs ? import <nixpkgs> { }, lockPath, excludes ? [ ] }:
|
||||
|
||||
let inherit (pkgs) lib;
|
||||
in lib.pipe lockPath [
|
||||
builtins.readFile
|
||||
builtins.fromJSON
|
||||
(builtins.getAttr "depends")
|
||||
(map ({ path, srcDir, ... }: ''path:"${path}/${srcDir}"''))
|
||||
in with builtins;
|
||||
lib.pipe lockPath [
|
||||
readFile
|
||||
fromJSON
|
||||
(getAttr "depends")
|
||||
(filter ({ packages, ... }: !(any (pkg: elem pkg excludes) packages)))
|
||||
(map ({ path, srcDir, ... }: ''path:"${storePath path}/${srcDir}"''))
|
||||
lib.strings.concatLines
|
||||
(pkgs.writeText "nim.cfg")
|
||||
]
|
||||
|
@ -28,15 +31,17 @@ I manage all this with [Tup](https://gittup.org/tup).
|
|||
|
||||
```
|
||||
# Tuprules.tup above my Nim projects
|
||||
!nim_lk = |> nim_lk > %o |> lock.json
|
||||
!nim_lk = |> nim_lk | jq --compact-output --sort-keys > %o |> lock.json
|
||||
|
||||
NIXEXPRS_DIR = $(TUP_CWD)/nixexprs
|
||||
!nim_cfg = |> nix build --file $(NIXEXPRS_DIR)/configure.nix --argstr lockPath `pwd`/%f --out-link %o |> nim.cfg
|
||||
!nim_cfg = |> nix build --file $(NIXEXPRS_DIR)/configure.nix --out-link %o --arg lockPath `pwd`/%f --arg excludes '[$(NIM_LOCK_EXCLUDES)]' |> nim.cfg
|
||||
```
|
||||
|
||||
```
|
||||
# Tupfile in a Nim project
|
||||
include_rules
|
||||
# Omit the foobar library from nim.cfg.
|
||||
NIM_LOCK_EXCLUDES += "foobar"
|
||||
: |> !nim_lk |> | ./<lock>
|
||||
: lock.json |> !nim_cfg |> | ./<lock>
|
||||
```
|
||||
|
|
|
@ -1,324 +0,0 @@
|
|||
# Copyright (C) Dominik Picheta. All rights reserved.
|
||||
# BSD License. Look at license.txt for more info.
|
||||
|
||||
import parseutils, os, osproc, strutils, tables, pegs, uri, json
|
||||
|
||||
import packageinfo, packageparser, version, tools, common, options, cli
|
||||
from algorithm import SortOrder, sorted
|
||||
from sequtils import toSeq, filterIt, map
|
||||
|
||||
type
|
||||
DownloadMethod* {.pure.} = enum
|
||||
git = "git", hg = "hg"
|
||||
|
||||
proc getSpecificDir(meth: DownloadMethod): string {.used.} =
|
||||
case meth
|
||||
of DownloadMethod.git:
|
||||
".git"
|
||||
of DownloadMethod.hg:
|
||||
".hg"
|
||||
|
||||
proc doCheckout(meth: DownloadMethod, downloadDir, branch: string) =
|
||||
case meth
|
||||
of DownloadMethod.git:
|
||||
cd downloadDir:
|
||||
# Force is used here because local changes may appear straight after a
|
||||
# clone has happened. Like in the case of git on Windows where it
|
||||
# messes up the damn line endings.
|
||||
doCmd("git checkout --force " & branch)
|
||||
doCmd("git submodule update --recursive")
|
||||
of DownloadMethod.hg:
|
||||
cd downloadDir:
|
||||
doCmd("hg checkout " & branch)
|
||||
|
||||
proc doPull(meth: DownloadMethod, downloadDir: string) {.used.} =
|
||||
case meth
|
||||
of DownloadMethod.git:
|
||||
doCheckout(meth, downloadDir, "")
|
||||
cd downloadDir:
|
||||
doCmd("git pull")
|
||||
if existsFile(".gitmodules"):
|
||||
doCmd("git submodule update")
|
||||
of DownloadMethod.hg:
|
||||
doCheckout(meth, downloadDir, "default")
|
||||
cd downloadDir:
|
||||
doCmd("hg pull")
|
||||
|
||||
proc doClone(meth: DownloadMethod, url, downloadDir: string, branch = "",
|
||||
onlyTip = true) =
|
||||
case meth
|
||||
of DownloadMethod.git:
|
||||
let
|
||||
depthArg = if onlyTip: "--depth 1 " else: ""
|
||||
branchArg = if branch == "": "" else: "-b " & branch & " "
|
||||
doCmd("git clone --recursive " & depthArg & branchArg & url &
|
||||
" " & downloadDir)
|
||||
of DownloadMethod.hg:
|
||||
let
|
||||
tipArg = if onlyTip: "-r tip " else: ""
|
||||
branchArg = if branch == "": "" else: "-b " & branch & " "
|
||||
doCmd("hg clone " & tipArg & branchArg & url & " " & downloadDir)
|
||||
|
||||
proc getTagsList(dir: string, meth: DownloadMethod): seq[string] =
|
||||
cd dir:
|
||||
var output = execProcess("git tag")
|
||||
case meth
|
||||
of DownloadMethod.git:
|
||||
output = execProcess("git tag")
|
||||
of DownloadMethod.hg:
|
||||
output = execProcess("hg tags")
|
||||
if output.len > 0:
|
||||
case meth
|
||||
of DownloadMethod.git:
|
||||
result = @[]
|
||||
for i in output.splitLines():
|
||||
if i == "": continue
|
||||
result.add(i)
|
||||
of DownloadMethod.hg:
|
||||
result = @[]
|
||||
for i in output.splitLines():
|
||||
if i == "": continue
|
||||
var tag = ""
|
||||
discard parseUntil(i, tag, ' ')
|
||||
if tag != "tip":
|
||||
result.add(tag)
|
||||
else:
|
||||
result = @[]
|
||||
|
||||
proc getTagsListRemote*(url: string, meth: DownloadMethod): seq[string] =
|
||||
var
|
||||
url = url
|
||||
uri = parseUri url
|
||||
if uri.query != "":
|
||||
uri.query = ""
|
||||
url = $uri
|
||||
result = @[]
|
||||
case meth
|
||||
of DownloadMethod.git:
|
||||
var (output, exitCode) = doCmdEx("git ls-remote --tags " & url)
|
||||
if exitCode != QuitSuccess:
|
||||
raise newException(OSError, "Unable to query remote tags for " & url &
|
||||
". Git returned: " & output)
|
||||
for i in output.splitLines():
|
||||
let refStart = i.find("refs/tags/")
|
||||
# git outputs warnings, empty lines, etc
|
||||
if refStart == -1: continue
|
||||
let start = refStart+"refs/tags/".len
|
||||
let tag = i[start .. i.len-1]
|
||||
if not tag.endswith("^{}"): result.add(tag)
|
||||
|
||||
of DownloadMethod.hg:
|
||||
# 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]): 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
|
||||
of "git": return DownloadMethod.git
|
||||
of "hg", "mercurial": return DownloadMethod.hg
|
||||
else:
|
||||
raise newException(NimbleError, "Invalid download method: " & meth)
|
||||
|
||||
proc getHeadName*(meth: DownloadMethod): Version =
|
||||
## Returns the name of the download method specific head. i.e. for git
|
||||
## it's ``head`` for hg it's ``tip``.
|
||||
case meth
|
||||
of DownloadMethod.git: newVersion("#head")
|
||||
of DownloadMethod.hg: newVersion("#tip")
|
||||
|
||||
proc checkUrlType*(url: string): DownloadMethod =
|
||||
## Determines the download method based on the URL.
|
||||
if doCmdEx("git ls-remote " & url).exitCode == QuitSuccess:
|
||||
return DownloadMethod.git
|
||||
elif doCmdEx("hg identify " & url).exitCode == QuitSuccess:
|
||||
return DownloadMethod.hg
|
||||
else:
|
||||
raise newException(NimbleError, "Unable to identify url: " & url)
|
||||
|
||||
proc getUrlData*(url: string): (string, Table[string, string]) =
|
||||
var uri = parseUri(url)
|
||||
# TODO: use uri.parseQuery once it lands... this code is quick and dirty.
|
||||
var subdir = ""
|
||||
if uri.query.startsWith("subdir="):
|
||||
subdir = uri.query[7 .. ^1]
|
||||
|
||||
uri.query = ""
|
||||
return ($uri, {"subdir": subdir}.toTable())
|
||||
|
||||
proc isURL*(name: string): bool =
|
||||
name.startsWith(peg" @'://' ")
|
||||
|
||||
proc doDownload(url: string, downloadDir: string, verRange: VersionRange,
|
||||
downMethod: DownloadMethod,
|
||||
options: Options): Version =
|
||||
## Downloads the repository specified by ``url`` using the specified download
|
||||
## method.
|
||||
##
|
||||
## Returns the version of the repository which has been downloaded.
|
||||
template getLatestByTag(meth: untyped) {.dirty.} =
|
||||
# Find latest version that fits our ``verRange``.
|
||||
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 no tagged versions satisfy our range latest.tag will be "".
|
||||
# We still clone in that scenario because we want to try HEAD in that case.
|
||||
# https://github.com/nim-lang/nimble/issues/22
|
||||
meth
|
||||
if $latest.ver != "":
|
||||
result = latest.ver
|
||||
|
||||
removeDir(downloadDir)
|
||||
if verRange.kind == verSpecial:
|
||||
# We want a specific commit/branch/tag here.
|
||||
if verRange.spe == getHeadName(downMethod):
|
||||
# Grab HEAD.
|
||||
doClone(downMethod, url, downloadDir, onlyTip = not options.forceFullClone)
|
||||
else:
|
||||
# Grab the full repo.
|
||||
doClone(downMethod, url, downloadDir, onlyTip = false)
|
||||
# Then perform a checkout operation to get the specified branch/commit.
|
||||
# `spe` starts with '#', trim it.
|
||||
doAssert(($verRange.spe)[0] == '#')
|
||||
doCheckout(downMethod, downloadDir, substr($verRange.spe, 1))
|
||||
result = verRange.spe
|
||||
else:
|
||||
case downMethod
|
||||
of DownloadMethod.git:
|
||||
# For Git we have to query the repo remotely for its tags. This is
|
||||
# necessary as cloning with a --depth of 1 removes all tag info.
|
||||
result = getHeadName(downMethod)
|
||||
let versions = getTagsListRemote(url, downMethod).getVersionList()
|
||||
if versions.len > 0:
|
||||
getLatestByTag:
|
||||
display("Cloning", "latest tagged version: " & latest.tag,
|
||||
priority = MediumPriority)
|
||||
doClone(downMethod, url, downloadDir, latest.tag,
|
||||
onlyTip = not options.forceFullClone)
|
||||
else:
|
||||
# If no commits have been tagged on the repo we just clone HEAD.
|
||||
doClone(downMethod, url, downloadDir) # Grab HEAD.
|
||||
of DownloadMethod.hg:
|
||||
doClone(downMethod, url, downloadDir, onlyTip = not options.forceFullClone)
|
||||
result = getHeadName(downMethod)
|
||||
let versions = getTagsList(downloadDir, downMethod).getVersionList()
|
||||
|
||||
if versions.len > 0:
|
||||
getLatestByTag:
|
||||
display("Switching", "to latest tagged version: " & latest.tag,
|
||||
priority = MediumPriority)
|
||||
doCheckout(downMethod, downloadDir, latest.tag)
|
||||
|
||||
proc downloadPkg*(url: string, verRange: VersionRange,
|
||||
downMethod: DownloadMethod,
|
||||
subdir: string,
|
||||
options: Options,
|
||||
downloadPath = ""): (string, Version) =
|
||||
## Downloads the repository as specified by ``url`` and ``verRange`` using
|
||||
## the download method specified.
|
||||
##
|
||||
## If `downloadPath` isn't specified a location in /tmp/ will be used.
|
||||
##
|
||||
## Returns the directory where it was downloaded (subdir is appended) and
|
||||
## the concrete version which was downloaded.
|
||||
let downloadDir =
|
||||
if downloadPath == "":
|
||||
(getNimbleTempDir() / getDownloadDirName(url, verRange))
|
||||
else:
|
||||
downloadPath
|
||||
|
||||
createDir(downloadDir)
|
||||
var modUrl =
|
||||
if url.startsWith("git://") and options.config.cloneUsingHttps:
|
||||
"https://" & url[6 .. ^1]
|
||||
else: url
|
||||
|
||||
# Fixes issue #204
|
||||
# github + https + trailing url slash causes a
|
||||
# checkout/ls-remote to fail with Repository not found
|
||||
if modUrl.contains("github.com") and modUrl.endswith("/"):
|
||||
modUrl = modUrl[0 .. ^2]
|
||||
|
||||
if subdir.len > 0:
|
||||
display("Downloading", "$1 using $2 (subdir is '$3')" %
|
||||
[modUrl, $downMethod, subdir],
|
||||
priority = HighPriority)
|
||||
else:
|
||||
display("Downloading", "$1 using $2" % [modUrl, $downMethod],
|
||||
priority = HighPriority)
|
||||
result = (
|
||||
downloadDir / subdir,
|
||||
doDownload(modUrl, downloadDir, verRange, downMethod, options)
|
||||
)
|
||||
|
||||
if verRange.kind != verSpecial:
|
||||
## Makes sure that the downloaded package's version satisfies the requested
|
||||
## version range.
|
||||
let pkginfo = getPkgInfo(result[0], options)
|
||||
if pkginfo.version.newVersion notin verRange:
|
||||
raise newException(NimbleError,
|
||||
"Downloaded package's version does not satisfy requested version " &
|
||||
"range: wanted $1 got $2." %
|
||||
[$verRange, $pkginfo.version])
|
||||
|
||||
proc echoPackageVersions*(pkg: Package) =
|
||||
let downMethod = pkg.downloadMethod.getDownloadMethod()
|
||||
case downMethod
|
||||
of DownloadMethod.git:
|
||||
try:
|
||||
let versions = getTagsListRemote(pkg.url, downMethod).getVersionList()
|
||||
if versions.len > 0:
|
||||
let sortedVersions = toSeq(values(versions))
|
||||
echo(" versions: " & join(sortedVersions, ", "))
|
||||
else:
|
||||
echo(" versions: (No versions tagged in the remote repository)")
|
||||
except OSError:
|
||||
echo(getCurrentExceptionMsg())
|
||||
of DownloadMethod.hg:
|
||||
echo(" versions: (Remote tag retrieval not supported by " &
|
||||
pkg.downloadMethod & ")")
|
||||
|
||||
proc packageVersionsJson*(pkg: Package): JsonNode =
|
||||
result = newJArray()
|
||||
let downMethod = pkg.downloadMethod.getDownloadMethod()
|
||||
try:
|
||||
case downMethod
|
||||
of DownloadMethod.git:
|
||||
let versions = getTagsListRemote(pkg.url, downMethod).getVersionList()
|
||||
for v in values(versions):
|
||||
result.add %v
|
||||
of DownloadMethod.hg:
|
||||
discard
|
||||
except:
|
||||
result = %* { "exception": getCurrentExceptionMsg() }
|
||||
|
||||
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!")
|
Loading…
Reference in New Issue