Squashed merge of #635 by @genotrance.
Squashed commit of the following:
commit e86a376f2faf9d26109405a3a9f73f986185f62d
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Sun Apr 28 15:37:22 2019 -0500
Fix caching issue
commit 640ce3f2e464e52668b5350fdc5a8fe506e79d38
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Thu Apr 25 18:38:48 2019 -0500
Clean up per feedback
commit ae3ef9f7a0cbad574b725d1bc7a83bd6115e19cc
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Thu Apr 25 16:39:26 2019 -0500
Fix for 0.19.4
commit 915d6b2be43e33bc51327585193b1899386ee250
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Thu Apr 25 16:13:42 2019 -0500
Keep nimscript separate, pin devel
commit c278bd6ba09771dc079029a87e3a375998f0b447
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Mon Apr 22 14:57:44 2019 -0500
Hardcode version, json{}, code width 80, isScriptResultCached, no blank paramStr check
commit 64e5489e256d5fc5abbfe3345789f65edf5980b7
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Wed Apr 17 21:07:03 2019 -0500
Remove compiler dependency
commit a031fffd70c118c16eb3e16d3b1ed10472baf5d7
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Wed Apr 17 16:49:09 2019 -0500
Add devel to travis
commit d49916e2a05b6bd7716f45bd8f74253fc8037827
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Wed Apr 17 16:43:14 2019 -0500
Interactive live, json to file
commit 24131deea4693199922f9a5697aa3d072cceaee1
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Wed Apr 17 12:40:27 2019 -0500
Fix empty param, json echo
commit b22fe37d47fd03367d49129ea4d2d56a779a6f26
Merge: 5cf0240 2942f11
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Apr 16 22:23:17 2019 -0500
Merge branch 'nocompiler' of https://github.com/genotrance/nimble into nocompiler
commit 5cf0240b728ab6ff4a39ddf629ba5833eb8985f5
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Apr 16 22:23:06 2019 -0500
No hints, live output
commit 2942f116c7774e0fa91f770cebde32bc431923a5
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Apr 16 21:02:28 2019 -0500
Remove osx, test with stable
commit 85f3865ef195c7b813f0b9e30b5cc8c9b2756518
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Apr 16 18:19:42 2019 -0500
Remove ospaths, fix tests for Windows
commit 74201bcfe4de00bdece5b31715618975f9ce8e6e
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Apr 16 14:00:14 2019 -0500
No success for missing task
commit 8c2e65e223d32366b03004d9711364504c5d7916
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Apr 16 13:44:32 2019 -0500
Fix packageName to name
commit b05d9480281ebae7a0f5fd0331c8627bbf2a77d5
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Apr 16 13:29:37 2019 -0500
Add switch support
commit deecd903102a9baa5d4674cb9871cd9dbb658a04
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Apr 16 12:24:01 2019 -0500
API cleanup, json setCommand fix
commit 1e95fd4104ec3ffb69fe67b9c2fac23f991e163a
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Apr 16 10:45:12 2019 -0500
getParams once, hash nimscriptapi, fix loop in setcommand
commit 51d03b3845cd562796bb32d41d5ad17cd09a91e7
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Apr 16 07:21:32 2019 -0500
getPkgDir impl
commit 7d0a40aa286d114d7557b229852f3c314795dc5d
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Mon Apr 15 14:24:02 2019 -0500
Before/after hook info
commit cbb3af3e970b20322030331d4849436b821f25ca
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Mon Apr 15 13:44:56 2019 -0500
Remove nims from package dir after exec
commit 0ed53d60bcdc8bb11beddb965590ed3ee63349d4
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Sat Apr 13 00:44:26 2019 -0500
Return bool from hooks
commit ab38b81b81e68cfccf3ca84fd854422cd3733c84
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Fri Apr 12 23:20:13 2019 -0500
Initial version
commit b9ef88b9f79b48435e7b4beeff959b4223f4b8ba
Merge: 220ebae c8d79fc
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Tue Mar 26 20:16:21 2019 -0500
Merge remote-tracking branch 'upstream/master' into nocompiler
commit 220ebae355c945963591b002a43b262a70640aa5
Merge: 3d7227c 119be48
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Wed Dec 12 18:02:10 2018 -0600
Merge remote-tracking branch 'upstream/master'
commit 3d7227c8900c205aada488d60565c90e17759639
Merge: cf7263d 66d79bf
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Wed Oct 17 13:39:51 2018 -0500
Merge remote-tracking branch 'upstream/master'
commit cf7263d6caf27ca4930ed54b05d4aa4f36e1dff1
Merge: 2fc3106 ee4c0ae
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Thu Sep 13 23:03:41 2018 -0500
Merge remote-tracking branch 'upstream/master'
commit 2fc310623b9f49ea012fc04fa09713fda140a7a3
Merge: e9a8850 c249f9b
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Thu Apr 26 16:27:31 2018 -0500
Merge remote-tracking branch 'upstream/master'
commit e9a885099b0b97bf3e0cddcde27e8c6b0bd51b10
Merge: 7adfd7b 75b7a21
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Thu Mar 8 14:26:46 2018 -0600
Merge remote-tracking branch 'upstream/master'
commit 7adfd7be2b38a52886640579845de378139ca0cc
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Mon Jan 15 00:35:55 2018 -0600
Updated fix for #398
commit de18319159b76a9da6765f35ea4d2e2c963d688a
Merge: 93ba4a0 3dae264
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Sun Jan 14 22:01:20 2018 -0600
Merge remote-tracking branch 'upstream/master'
commit 93ba4a00820ccb9a5362f0398cf3b5b4782bbefe
Author: Ganesh Viswanathan <dev@genotrance.com>
Date: Sat Jan 13 19:52:34 2018 -0600
Fix for #398
This commit is contained in:
parent
c8d79fc022
commit
6542c1ef16
10 changed files with 389 additions and 56 deletions
14
.travis.yml
14
.travis.yml
|
|
@ -1,24 +1,24 @@
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
dist: trusty
|
- osx
|
||||||
|
|
||||||
language: c
|
language: c
|
||||||
|
|
||||||
|
env:
|
||||||
|
- BRANCH=0.19.4
|
||||||
|
- BRANCH=#4f9366975441be889a8cd4fbfb4e41f6830dc542
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
- "$HOME/.nimble"
|
- "$HOME/.choosenim/toolchains/nim-0.19.4"
|
||||||
- "$HOME/.choosenim"
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- export CHOOSENIM_CHOOSE_VERSION="#7bb93c730ea87f"
|
- export CHOOSENIM_CHOOSE_VERSION=$BRANCH
|
||||||
- export NIM_LIB_PREFIX="$HOME/.choosenim/toolchains/nim-"$CHOOSENIM_CHOOSE_VERSION
|
|
||||||
- |
|
- |
|
||||||
curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh
|
curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh
|
||||||
sh init.sh -y
|
sh init.sh -y
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- set -e
|
|
||||||
- set -x
|
|
||||||
- export CHOOSENIM_NO_ANALYTICS=1
|
- export CHOOSENIM_NO_ANALYTICS=1
|
||||||
- export PATH=$HOME/.nimble/bin:$PATH
|
- export PATH=$HOME/.nimble/bin:$PATH
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,6 @@
|
||||||
import ospaths
|
|
||||||
template thisModuleFile: string = instantiationInfo(fullPaths = true).filename
|
|
||||||
|
|
||||||
when fileExists(thisModuleFile.parentDir / "src/nimblepkg/common.nim"):
|
|
||||||
# In the git repository the Nimble sources are in a ``src`` directory.
|
|
||||||
import src/nimblepkg/common
|
|
||||||
else:
|
|
||||||
# When the package is installed, the ``src`` directory disappears.
|
|
||||||
import nimblepkg/common
|
|
||||||
|
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = nimbleVersion
|
version = "0.9.0"
|
||||||
author = "Dominik Picheta"
|
author = "Dominik Picheta"
|
||||||
description = "Nim package manager."
|
description = "Nim package manager."
|
||||||
license = "BSD"
|
license = "BSD"
|
||||||
|
|
@ -21,7 +11,7 @@ installExt = @["nim"]
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|
||||||
requires "nim >= 0.13.0", "compiler#head"
|
requires "nim >= 0.13.0"
|
||||||
|
|
||||||
when defined(nimdistros):
|
when defined(nimdistros):
|
||||||
import distros
|
import distros
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import nimblepkg/packageinfo, nimblepkg/version, nimblepkg/tools,
|
||||||
nimblepkg/cli, nimblepkg/packageinstaller, nimblepkg/reversedeps,
|
nimblepkg/cli, nimblepkg/packageinstaller, nimblepkg/reversedeps,
|
||||||
nimblepkg/nimscriptexecutor, nimblepkg/init
|
nimblepkg/nimscriptexecutor, nimblepkg/init
|
||||||
|
|
||||||
import nimblepkg/nimscriptsupport
|
import nimblepkg/nimscriptwrapper
|
||||||
|
|
||||||
proc refresh(options: Options) =
|
proc refresh(options: Options) =
|
||||||
## Downloads the package list from the specified URL.
|
## Downloads the package list from the specified URL.
|
||||||
|
|
@ -896,7 +896,7 @@ proc uninstall(options: Options) =
|
||||||
|
|
||||||
proc listTasks(options: Options) =
|
proc listTasks(options: Options) =
|
||||||
let nimbleFile = findNimbleFile(getCurrentDir(), true)
|
let nimbleFile = findNimbleFile(getCurrentDir(), true)
|
||||||
nimscriptsupport.listTasks(nimbleFile, options)
|
nimscriptwrapper.listTasks(nimbleFile, options)
|
||||||
|
|
||||||
proc developFromDir(dir: string, options: Options) =
|
proc developFromDir(dir: string, options: Options) =
|
||||||
if options.depsOnly:
|
if options.depsOnly:
|
||||||
|
|
@ -1103,7 +1103,7 @@ proc doAction(options: Options) =
|
||||||
return
|
return
|
||||||
let isPreDefined = options.action.command.normalize == "test"
|
let isPreDefined = options.action.command.normalize == "test"
|
||||||
|
|
||||||
var execResult: ExecutionResult[void]
|
var execResult: ExecutionResult[bool]
|
||||||
if execCustom(options, execResult, failFast=not isPreDefined):
|
if execCustom(options, execResult, failFast=not isPreDefined):
|
||||||
if execResult.hasTaskRequestedCommand():
|
if execResult.hasTaskRequestedCommand():
|
||||||
doAction(execResult.getOptionsForCommand(options))
|
doAction(execResult.getOptionsForCommand(options))
|
||||||
|
|
|
||||||
155
src/nimblepkg/nimscriptapi.nim
Normal file → Executable file
155
src/nimblepkg/nimscriptapi.nim
Normal file → Executable file
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
## This module is implicitly imported in NimScript .nimble files.
|
## This module is implicitly imported in NimScript .nimble files.
|
||||||
|
|
||||||
|
import system except getCommand, setCommand, switch, `--`
|
||||||
|
import strformat, strutils, tables
|
||||||
|
|
||||||
var
|
var
|
||||||
packageName* = "" ## Set this to the package name. It
|
packageName* = "" ## Set this to the package name. It
|
||||||
## is usually not required to do that, nims' filename is
|
## is usually not required to do that, nims' filename is
|
||||||
|
|
@ -22,30 +25,134 @@ var
|
||||||
foreignDeps*: seq[string] = @[] ## The foreign dependencies. Only
|
foreignDeps*: seq[string] = @[] ## The foreign dependencies. Only
|
||||||
## exported for 'distros.nim'.
|
## exported for 'distros.nim'.
|
||||||
|
|
||||||
|
beforeHooks: seq[string] = @[]
|
||||||
|
afterHooks: seq[string] = @[]
|
||||||
|
commandLineParams: seq[string] = @[]
|
||||||
|
flags: TableRef[string, seq[string]]
|
||||||
|
|
||||||
|
command = "e"
|
||||||
|
project = ""
|
||||||
|
success = false
|
||||||
|
retVal = true
|
||||||
|
projectFile = ""
|
||||||
|
|
||||||
proc requires*(deps: varargs[string]) =
|
proc requires*(deps: varargs[string]) =
|
||||||
## Call this to set the list of requirements of your Nimble
|
## Call this to set the list of requirements of your Nimble
|
||||||
## package.
|
## package.
|
||||||
for d in deps: requiresData.add(d)
|
for d in deps: requiresData.add(d)
|
||||||
|
|
||||||
|
proc getParams() =
|
||||||
|
for i in 2 .. paramCount():
|
||||||
|
let
|
||||||
|
param = paramStr(i)
|
||||||
|
if param.fileExists():
|
||||||
|
projectFile = param
|
||||||
|
elif param[0] != '-':
|
||||||
|
commandLineParams.add paramStr(i).normalize
|
||||||
|
|
||||||
|
proc getCommand*(): string =
|
||||||
|
return command
|
||||||
|
|
||||||
|
proc setCommand*(cmd: string, prj = "") =
|
||||||
|
command = cmd
|
||||||
|
if prj.len != 0:
|
||||||
|
project = prj
|
||||||
|
|
||||||
|
proc switch*(key: string, value="") =
|
||||||
|
if flags.isNil:
|
||||||
|
flags = newTable[string, seq[string]]()
|
||||||
|
|
||||||
|
if flags.hasKey(key):
|
||||||
|
flags[key].add(value)
|
||||||
|
else:
|
||||||
|
flags[key] = @[value]
|
||||||
|
|
||||||
|
template `--`*(key, val: untyped) =
|
||||||
|
switch(astToStr(key), strip astToStr(val))
|
||||||
|
|
||||||
|
template `--`*(key: untyped) =
|
||||||
|
switch(astToStr(key), "")
|
||||||
|
|
||||||
|
template printIfLen(varName) =
|
||||||
|
if varName.len != 0:
|
||||||
|
iniOut &= astToStr(varName) & ": \"" & varName & "\"\n"
|
||||||
|
|
||||||
|
template printSeqIfLen(varName) =
|
||||||
|
if varName.len != 0:
|
||||||
|
iniOut &= astToStr(varName) & ": \"" & varName.join(", ") & "\"\n"
|
||||||
|
|
||||||
|
proc printPkgInfo() =
|
||||||
|
if backend.len == 0:
|
||||||
|
backend = "c"
|
||||||
|
|
||||||
|
var
|
||||||
|
iniOut = "[Package]\n"
|
||||||
|
if packageName.len != 0:
|
||||||
|
iniOut &= "name: \"" & packageName & "\"\n"
|
||||||
|
printIfLen version
|
||||||
|
printIfLen author
|
||||||
|
printIfLen description
|
||||||
|
printIfLen license
|
||||||
|
printIfLen srcdir
|
||||||
|
printIfLen binDir
|
||||||
|
printIfLen backend
|
||||||
|
|
||||||
|
printSeqIfLen skipDirs
|
||||||
|
printSeqIfLen skipFiles
|
||||||
|
printSeqIfLen skipExt
|
||||||
|
printSeqIfLen installDirs
|
||||||
|
printSeqIfLen installFiles
|
||||||
|
printSeqIfLen installExt
|
||||||
|
printSeqIfLen bin
|
||||||
|
printSeqIfLen beforeHooks
|
||||||
|
printSeqIfLen afterHooks
|
||||||
|
|
||||||
|
if requiresData.len != 0:
|
||||||
|
iniOut &= "\n[Deps]\n"
|
||||||
|
iniOut &= &"requires: \"{requiresData.join(\", \")}\"\n"
|
||||||
|
|
||||||
|
echo iniOut
|
||||||
|
|
||||||
|
proc onExit*() =
|
||||||
|
if "printPkgInfo".normalize in commandLineParams:
|
||||||
|
printPkgInfo()
|
||||||
|
else:
|
||||||
|
var
|
||||||
|
output = ""
|
||||||
|
output &= "\"success\": " & $success & ", "
|
||||||
|
output &= "\"command\": \"" & command & "\", "
|
||||||
|
if project.len != 0:
|
||||||
|
output &= "\"project\": \"" & project & "\", "
|
||||||
|
if not flags.isNil and flags.len != 0:
|
||||||
|
output &= "\"flags\": {"
|
||||||
|
for key, val in flags.pairs:
|
||||||
|
output &= "\"" & key & "\": ["
|
||||||
|
for v in val:
|
||||||
|
output &= "\"" & v & "\", "
|
||||||
|
output = output[0 .. ^3] & "], "
|
||||||
|
output = output[0 .. ^3] & "}, "
|
||||||
|
|
||||||
|
output &= "\"retVal\": " & $retVal
|
||||||
|
|
||||||
|
writeFile(projectFile & ".out", "{" & output & "}")
|
||||||
|
|
||||||
# TODO: New release of Nim will move this `task` template under a
|
# TODO: New release of Nim will move this `task` template under a
|
||||||
# `when not defined(nimble)`. This will allow us to override it in the future.
|
# `when not defined(nimble)`. This will allow us to override it in the future.
|
||||||
when not declared(task):
|
template task*(name: untyped; description: string; body: untyped): untyped =
|
||||||
template task*(name: untyped; description: string; body: untyped): untyped =
|
## Defines a task. Hidden tasks are supported via an empty description.
|
||||||
## Defines a task. Hidden tasks are supported via an empty description.
|
## Example:
|
||||||
## Example:
|
##
|
||||||
##
|
## .. code-block:: nim
|
||||||
## .. code-block:: nim
|
## task build, "default build is via the C backend":
|
||||||
## task build, "default build is via the C backend":
|
## setCommand "c"
|
||||||
## setCommand "c"
|
proc `name Task`*() = body
|
||||||
proc `name Task`*() = body
|
|
||||||
|
|
||||||
let cmd = getCommand()
|
if commandLineParams.len == 0 or "help" in commandLineParams:
|
||||||
if cmd.len == 0 or cmd == "help":
|
success = true
|
||||||
setCommand "help"
|
echo(astToStr(name), " ", description)
|
||||||
echo(astToStr(name), " ", description)
|
elif astToStr(name).normalize in commandLineParams:
|
||||||
elif cmd == astToStr(name):
|
success = true
|
||||||
setCommand "nop"
|
`name Task`()
|
||||||
`name Task`()
|
|
||||||
|
|
||||||
template before*(action: untyped, body: untyped): untyped =
|
template before*(action: untyped, body: untyped): untyped =
|
||||||
## Defines a block of code which is evaluated before ``action`` is executed.
|
## Defines a block of code which is evaluated before ``action`` is executed.
|
||||||
|
|
@ -53,15 +160,27 @@ template before*(action: untyped, body: untyped): untyped =
|
||||||
result = true
|
result = true
|
||||||
body
|
body
|
||||||
|
|
||||||
|
beforeHooks.add astToStr(action)
|
||||||
|
|
||||||
|
if (astToStr(action) & "Before").normalize in commandLineParams:
|
||||||
|
success = true
|
||||||
|
retVal = `action Before`()
|
||||||
|
|
||||||
template after*(action: untyped, body: untyped): untyped =
|
template after*(action: untyped, body: untyped): untyped =
|
||||||
## Defines a block of code which is evaluated after ``action`` is executed.
|
## Defines a block of code which is evaluated after ``action`` is executed.
|
||||||
proc `action After`*(): bool =
|
proc `action After`*(): bool =
|
||||||
result = true
|
result = true
|
||||||
body
|
body
|
||||||
|
|
||||||
template builtin = discard
|
afterHooks.add astToStr(action)
|
||||||
|
|
||||||
|
if (astToStr(action) & "After").normalize in commandLineParams:
|
||||||
|
success = true
|
||||||
|
retVal = `action After`()
|
||||||
|
|
||||||
proc getPkgDir*(): string =
|
proc getPkgDir*(): string =
|
||||||
## Returns the package directory containing the .nimble file currently
|
## Returns the package directory containing the .nimble file currently
|
||||||
## being evaluated.
|
## being evaluated.
|
||||||
builtin
|
result = projectFile.rsplit(seps={'/', '\\', ':'}, maxsplit=1)[0]
|
||||||
|
|
||||||
|
getParams()
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import os, tables, strutils, sets
|
import os, tables, strutils, sets
|
||||||
|
|
||||||
import packageparser, common, packageinfo, options, nimscriptsupport, cli
|
import packageparser, common, packageinfo, options, nimscriptwrapper, cli
|
||||||
|
|
||||||
proc execHook*(options: Options, before: bool): bool =
|
proc execHook*(options: Options, before: bool): bool =
|
||||||
## Returns whether to continue.
|
## Returns whether to continue.
|
||||||
|
|
@ -31,7 +31,7 @@ proc execHook*(options: Options, before: bool): bool =
|
||||||
result = res.retVal
|
result = res.retVal
|
||||||
|
|
||||||
proc execCustom*(options: Options,
|
proc execCustom*(options: Options,
|
||||||
execResult: var ExecutionResult[void],
|
execResult: var ExecutionResult[bool],
|
||||||
failFast = true): bool =
|
failFast = true): bool =
|
||||||
## Executes the custom command using the nimscript backend.
|
## Executes the custom command using the nimscript backend.
|
||||||
##
|
##
|
||||||
|
|
|
||||||
176
src/nimblepkg/nimscriptwrapper.nim
Executable file
176
src/nimblepkg/nimscriptwrapper.nim
Executable file
|
|
@ -0,0 +1,176 @@
|
||||||
|
# Copyright (C) Andreas Rumpf. All rights reserved.
|
||||||
|
# BSD License. Look at license.txt for more info.
|
||||||
|
|
||||||
|
## Implements the new configuration system for Nimble. Uses Nim as a
|
||||||
|
## scripting language.
|
||||||
|
|
||||||
|
import common, version, options, packageinfo, cli
|
||||||
|
import hashes, json, os, streams, strutils, strtabs,
|
||||||
|
tables, times, osproc, sets, pegs
|
||||||
|
|
||||||
|
type
|
||||||
|
Flags = TableRef[string, seq[string]]
|
||||||
|
ExecutionResult*[T] = object
|
||||||
|
success*: bool
|
||||||
|
command*: string
|
||||||
|
arguments*: seq[string]
|
||||||
|
flags*: Flags
|
||||||
|
retVal*: T
|
||||||
|
|
||||||
|
const
|
||||||
|
internalCmd = "e"
|
||||||
|
nimscriptApi = staticRead("nimscriptapi.nim")
|
||||||
|
|
||||||
|
proc execNimscript(nimsFile, projectDir, actionName: string, options: Options,
|
||||||
|
live = true): tuple[output: string, exitCode: int] =
|
||||||
|
let
|
||||||
|
shash = $projectDir.hash().abs()
|
||||||
|
nimsFileCopied = projectDir / nimsFile.splitFile().name & "_" & shash & ".nims"
|
||||||
|
|
||||||
|
let
|
||||||
|
isScriptResultCopied =
|
||||||
|
nimsFileCopied.fileExists() and
|
||||||
|
nimsFileCopied.getLastModificationTime() >= nimsFile.getLastModificationTime()
|
||||||
|
|
||||||
|
if not isScriptResultCopied:
|
||||||
|
nimsFile.copyFile(nimsFileCopied)
|
||||||
|
|
||||||
|
defer:
|
||||||
|
nimsFileCopied.removeFile()
|
||||||
|
|
||||||
|
let
|
||||||
|
cmd = ("nim e --hints:off --verbosity:0 -p:" & (getTempDir() / "nimblecache").quoteShell &
|
||||||
|
" " & nimsFileCopied.quoteShell & " " & actionName).strip()
|
||||||
|
|
||||||
|
if live:
|
||||||
|
result.exitCode = execCmd(cmd)
|
||||||
|
let
|
||||||
|
outFile = nimsFileCopied & ".out"
|
||||||
|
if outFile.fileExists():
|
||||||
|
result.output = outFile.readFile()
|
||||||
|
discard outFile.tryRemoveFile()
|
||||||
|
else:
|
||||||
|
result = execCmdEx(cmd, options = {poUsePath})
|
||||||
|
|
||||||
|
proc getNimsFile(scriptName: string, options: Options): string =
|
||||||
|
let
|
||||||
|
cacheDir = getTempDir() / "nimblecache"
|
||||||
|
shash = $scriptName.parentDir().hash().abs()
|
||||||
|
prjCacheDir = cacheDir / scriptName.splitFile().name & "_" & shash
|
||||||
|
|
||||||
|
result = prjCacheDir / scriptName.extractFilename().changeFileExt ".nims"
|
||||||
|
|
||||||
|
proc setupNimscript(scriptName: string, options: Options) =
|
||||||
|
let
|
||||||
|
cacheDir = getTempDir() / "nimblecache"
|
||||||
|
nimscriptApiFile = cacheDir / "nimscriptapi.nim"
|
||||||
|
nimsFile = getNimsFile(scriptName, options)
|
||||||
|
|
||||||
|
let
|
||||||
|
isNimscriptApiCached =
|
||||||
|
nimscriptApiFile.fileExists() and nimscriptApiFile.getLastModificationTime() >
|
||||||
|
getAppFilename().getLastModificationTime()
|
||||||
|
|
||||||
|
isScriptResultCached =
|
||||||
|
nimsFile.fileExists() and nimsFile.getLastModificationTime() >
|
||||||
|
scriptName.getLastModificationTime()
|
||||||
|
|
||||||
|
if not isNimscriptApiCached:
|
||||||
|
createDir(cacheDir)
|
||||||
|
writeFile(nimscriptApiFile, nimscriptApi)
|
||||||
|
|
||||||
|
if not isScriptResultCached:
|
||||||
|
createDir(nimsFile.parentDir())
|
||||||
|
writeFile(nimsFile, """
|
||||||
|
import system except getCommand, setCommand, switch, `--`,
|
||||||
|
packageName, version, author, description, license, srcDir, binDir, backend,
|
||||||
|
skipDirs, skipFiles, skipExt, installDirs, installFiles, installExt, bin, foreignDeps,
|
||||||
|
requires, task, packageName
|
||||||
|
""" &
|
||||||
|
"import nimscriptapi, strutils\n" & scriptName.readFile() & "\nonExit()\n")
|
||||||
|
|
||||||
|
proc getIniFile*(scriptName: string, options: Options): string =
|
||||||
|
let
|
||||||
|
nimsFile = getNimsFile(scriptName, options)
|
||||||
|
|
||||||
|
result = nimsFile.changeFileExt(".ini")
|
||||||
|
|
||||||
|
let
|
||||||
|
isIniResultCached =
|
||||||
|
result.fileExists() and result.getLastModificationTime() >
|
||||||
|
scriptName.getLastModificationTime()
|
||||||
|
|
||||||
|
if not isIniResultCached:
|
||||||
|
setupNimscript(scriptName, options)
|
||||||
|
let
|
||||||
|
(output, exitCode) =
|
||||||
|
execNimscript(nimsFile, scriptName.parentDir(), "printPkgInfo", options, live=false)
|
||||||
|
|
||||||
|
if exitCode == 0 and output.len != 0:
|
||||||
|
result.writeFile(output)
|
||||||
|
else:
|
||||||
|
raise newException(NimbleError, output & "\nprintPkgInfo() failed")
|
||||||
|
|
||||||
|
proc execScript(scriptName, actionName: string, options: Options):
|
||||||
|
ExecutionResult[bool] =
|
||||||
|
let
|
||||||
|
nimsFile = getNimsFile(scriptName, options)
|
||||||
|
|
||||||
|
if not nimsFile.fileExists():
|
||||||
|
setupNimScript(scriptName, options)
|
||||||
|
|
||||||
|
let
|
||||||
|
(output, exitCode) = execNimscript(nimsFile, scriptName.parentDir(), actionName, options)
|
||||||
|
|
||||||
|
if exitCode != 0:
|
||||||
|
raise newException(NimbleError, output)
|
||||||
|
|
||||||
|
let
|
||||||
|
j =
|
||||||
|
if output.len != 0:
|
||||||
|
parseJson(output)
|
||||||
|
else:
|
||||||
|
parseJson("{}")
|
||||||
|
|
||||||
|
result.flags = newTable[string, seq[string]]()
|
||||||
|
result.success = j{"success"}.getBool()
|
||||||
|
result.command = j{"command"}.getStr()
|
||||||
|
if "project" in j:
|
||||||
|
result.arguments.add j["project"].getStr()
|
||||||
|
if "flags" in j:
|
||||||
|
for flag, vals in j["flags"].pairs:
|
||||||
|
result.flags[flag] = @[]
|
||||||
|
for val in vals.items():
|
||||||
|
result.flags[flag].add val.getStr()
|
||||||
|
result.retVal = j{"retVal"}.getBool()
|
||||||
|
|
||||||
|
proc execTask*(scriptName, taskName: string,
|
||||||
|
options: Options): ExecutionResult[bool] =
|
||||||
|
## Executes the specified task in the specified script.
|
||||||
|
##
|
||||||
|
## `scriptName` should be a filename pointing to the nimscript file.
|
||||||
|
display("Executing", "task $# in $#" % [taskName, scriptName],
|
||||||
|
priority = HighPriority)
|
||||||
|
|
||||||
|
result = execScript(scriptName, taskName, options)
|
||||||
|
|
||||||
|
proc execHook*(scriptName, actionName: string, before: bool,
|
||||||
|
options: Options): ExecutionResult[bool] =
|
||||||
|
## Executes the specified action's hook. Depending on ``before``, either
|
||||||
|
## the "before" or the "after" hook.
|
||||||
|
##
|
||||||
|
## `scriptName` should be a filename pointing to the nimscript file.
|
||||||
|
let hookName =
|
||||||
|
if before: actionName.toLowerAscii & "Before"
|
||||||
|
else: actionName.toLowerAscii & "After"
|
||||||
|
display("Attempting", "to execute hook $# in $#" % [hookName, scriptName],
|
||||||
|
priority = MediumPriority)
|
||||||
|
|
||||||
|
result = execScript(scriptName, hookName, options)
|
||||||
|
|
||||||
|
proc hasTaskRequestedCommand*(execResult: ExecutionResult): bool =
|
||||||
|
## Determines whether the last executed task used ``setCommand``
|
||||||
|
return execResult.command != internalCmd
|
||||||
|
|
||||||
|
proc listTasks*(scriptName: string, options: Options) =
|
||||||
|
discard execScript(scriptName, "", options)
|
||||||
|
|
@ -324,7 +324,7 @@ proc getInstalledPkgsMin*(libsDir: string, options: Options):
|
||||||
seq[tuple[pkginfo: PackageInfo, meta: MetaData]] =
|
seq[tuple[pkginfo: PackageInfo, meta: MetaData]] =
|
||||||
## Gets a list of installed packages. The resulting package info is
|
## Gets a list of installed packages. The resulting package info is
|
||||||
## minimal. This has the advantage that it does not depend on the
|
## minimal. This has the advantage that it does not depend on the
|
||||||
## ``packageparser`` module, and so can be used by ``nimscriptsupport``.
|
## ``packageparser`` module, and so can be used by ``nimscriptwrapper``.
|
||||||
##
|
##
|
||||||
## ``libsDir`` is in most cases: ~/.nimble/pkgs/ (options.getPkgsDir)
|
## ``libsDir`` is in most cases: ~/.nimble/pkgs/ (options.getPkgsDir)
|
||||||
result = @[]
|
result = @[]
|
||||||
|
|
|
||||||
20
src/nimblepkg/packageparser.nim
Normal file → Executable file
20
src/nimblepkg/packageparser.nim
Normal file → Executable file
|
|
@ -1,12 +1,12 @@
|
||||||
# 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, os, tables, sugar
|
import parsecfg, json, sets, streams, strutils, parseutils, os, tables, sugar
|
||||||
from sequtils import apply, map
|
from sequtils import apply, map
|
||||||
|
|
||||||
import version, tools, common, nimscriptsupport, options, packageinfo, cli
|
import version, tools, common, nimscriptwrapper, options, packageinfo, cli
|
||||||
|
|
||||||
## Contains procedures for parsing .nimble files. Moved here from ``packageinfo``
|
## Contains procedures for parsing .nimble files. Moved here from ``packageinfo``
|
||||||
## because it depends on ``nimscriptsupport`` (``nimscriptsupport`` also
|
## because it depends on ``nimscriptwrapper`` (``nimscriptwrapper`` also
|
||||||
## depends on other procedures in ``packageinfo``.
|
## depends on other procedures in ``packageinfo``.
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -259,6 +259,12 @@ proc readPackageInfoFromNimble(path: string; result: var PackageInfo) =
|
||||||
case result.backend.normalize
|
case result.backend.normalize
|
||||||
of "javascript": result.backend = "js"
|
of "javascript": result.backend = "js"
|
||||||
else: discard
|
else: discard
|
||||||
|
of "beforehooks":
|
||||||
|
for i in ev.value.multiSplit:
|
||||||
|
result.preHooks.incl(i.normalize)
|
||||||
|
of "afterhooks":
|
||||||
|
for i in ev.value.multiSplit:
|
||||||
|
result.postHooks.incl(i.normalize)
|
||||||
else:
|
else:
|
||||||
raise newException(NimbleError, "Invalid field: " & ev.key)
|
raise newException(NimbleError, "Invalid field: " & ev.key)
|
||||||
of "deps", "dependencies":
|
of "deps", "dependencies":
|
||||||
|
|
@ -277,6 +283,14 @@ proc readPackageInfoFromNimble(path: string; result: var PackageInfo) =
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Cannot open package info: " & path)
|
raise newException(ValueError, "Cannot open package info: " & path)
|
||||||
|
|
||||||
|
proc readPackageInfoFromNims(scriptName: string, options: Options,
|
||||||
|
result: var PackageInfo) =
|
||||||
|
let
|
||||||
|
iniFile = getIniFile(scriptName, options)
|
||||||
|
|
||||||
|
if iniFile.fileExists():
|
||||||
|
readPackageInfoFromNimble(iniFile, result)
|
||||||
|
|
||||||
proc inferInstallRules(pkgInfo: var PackageInfo, options: Options) =
|
proc inferInstallRules(pkgInfo: var PackageInfo, options: Options) =
|
||||||
# Binary packages shouldn't install .nim files by default.
|
# Binary packages shouldn't install .nim files by default.
|
||||||
# (As long as the package info doesn't explicitly specify what should be
|
# (As long as the package info doesn't explicitly specify what should be
|
||||||
|
|
|
||||||
10
tests/caching/caching.nimble
Normal file
10
tests/caching/caching.nimble
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Package
|
||||||
|
|
||||||
|
version = "0.1.0"
|
||||||
|
author = "Dominik Picheta"
|
||||||
|
description = "Test package"
|
||||||
|
license = "BSD"
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
requires "nim >= 0.12.1"
|
||||||
|
|
@ -36,9 +36,13 @@ proc execNimble(args: varargs[string]): tuple[output: string, exitCode: int] =
|
||||||
quotedArgs.add("--nimbleDir:" & installDir)
|
quotedArgs.add("--nimbleDir:" & installDir)
|
||||||
quotedArgs = quotedArgs.map((x: string) => ("\"" & x & "\""))
|
quotedArgs = quotedArgs.map((x: string) => ("\"" & x & "\""))
|
||||||
|
|
||||||
let path = getCurrentDir().parentDir() / "src"
|
let path {.used.} = getCurrentDir().parentDir() / "src"
|
||||||
|
|
||||||
var cmd = "PATH=" & path & ":$PATH " & quotedArgs.join(" ")
|
var cmd =
|
||||||
|
when not defined(windows):
|
||||||
|
"PATH=" & path & ":$PATH " & quotedArgs.join(" ")
|
||||||
|
else:
|
||||||
|
quotedArgs.join(" ")
|
||||||
when defined(macosx):
|
when defined(macosx):
|
||||||
# TODO: Yeah, this is really specific to my machine but for my own sanity...
|
# TODO: Yeah, this is really specific to my machine but for my own sanity...
|
||||||
cmd = "DYLD_LIBRARY_PATH=/usr/local/opt/openssl@1.1/lib " & cmd
|
cmd = "DYLD_LIBRARY_PATH=/usr/local/opt/openssl@1.1/lib " & cmd
|
||||||
|
|
@ -67,6 +71,17 @@ proc inLines(lines: seq[string], line: string): bool =
|
||||||
for i in lines:
|
for i in lines:
|
||||||
if line.normalize in i.normalize: return true
|
if line.normalize in i.normalize: return true
|
||||||
|
|
||||||
|
test "caching works":
|
||||||
|
cd "caching":
|
||||||
|
var (output, exitCode) = execNimble("dump")
|
||||||
|
check output.contains("0.1.0")
|
||||||
|
let
|
||||||
|
nfile = "caching.nimble"
|
||||||
|
writeFile(nfile, readFile(nfile).replace("0.1.0", "0.2.0"))
|
||||||
|
(output, exitCode) = execNimble("dump")
|
||||||
|
check output.contains("0.2.0")
|
||||||
|
writeFile(nfile, readFile(nfile).replace("0.2.0", "0.1.0"))
|
||||||
|
|
||||||
test "picks #head when looking for packages":
|
test "picks #head when looking for packages":
|
||||||
cd "versionClashes" / "aporiaScenario":
|
cd "versionClashes" / "aporiaScenario":
|
||||||
let (output, exitCode) = execNimble("install", "-y", "--verbose")
|
let (output, exitCode) = execNimble("install", "-y", "--verbose")
|
||||||
|
|
@ -213,7 +228,7 @@ test "can refresh with local package list":
|
||||||
[PackageList]
|
[PackageList]
|
||||||
name = "local"
|
name = "local"
|
||||||
path = "$1"
|
path = "$1"
|
||||||
""".unindent % (getCurrentDir() / "issue368" / "packages.json"))
|
""".unindent % (getCurrentDir() / "issue368" / "packages.json").replace("\\", "\\\\"))
|
||||||
let (output, exitCode) = execNimble(["refresh", "--verbose"])
|
let (output, exitCode) = execNimble(["refresh", "--verbose"])
|
||||||
let lines = output.strip.processOutput()
|
let lines = output.strip.processOutput()
|
||||||
check inLines(lines, "config file at")
|
check inLines(lines, "config file at")
|
||||||
|
|
@ -258,9 +273,9 @@ suite "nimscript":
|
||||||
check exitCode == QuitSuccess
|
check exitCode == QuitSuccess
|
||||||
let lines = output.strip.processOutput()
|
let lines = output.strip.processOutput()
|
||||||
check lines[0].startsWith("Before PkgDir:")
|
check lines[0].startsWith("Before PkgDir:")
|
||||||
check lines[0].endsWith("tests/nimscript")
|
check lines[0].endsWith("tests" / "nimscript")
|
||||||
check lines[^1].startsWith("After PkgDir:")
|
check lines[^1].startsWith("After PkgDir:")
|
||||||
check lines[^1].endsWith("tests/nimbleDir/pkgs/nimscript-0.1.0")
|
check lines[^1].endsWith("tests" / "nimbleDir" / "pkgs" / "nimscript-0.1.0")
|
||||||
|
|
||||||
test "can execute nimscript tasks":
|
test "can execute nimscript tasks":
|
||||||
cd "nimscript":
|
cd "nimscript":
|
||||||
|
|
@ -412,6 +427,9 @@ test "issue #349":
|
||||||
]
|
]
|
||||||
|
|
||||||
proc checkName(name: string) =
|
proc checkName(name: string) =
|
||||||
|
when defined(windows):
|
||||||
|
if name.toLowerAscii() in @["con", "nul"]:
|
||||||
|
return
|
||||||
let (outp, code) = execNimble("init", "-y", name)
|
let (outp, code) = execNimble("init", "-y", name)
|
||||||
let msg = outp.strip.processOutput()
|
let msg = outp.strip.processOutput()
|
||||||
check code == QuitFailure
|
check code == QuitFailure
|
||||||
|
|
@ -526,9 +544,15 @@ suite "can handle two binary versions":
|
||||||
cd "binaryPackage/v2":
|
cd "binaryPackage/v2":
|
||||||
check execNimble("install", "-y").exitCode == QuitSuccess
|
check execNimble("install", "-y").exitCode == QuitSuccess
|
||||||
|
|
||||||
|
var
|
||||||
|
cmd = installDir / "bin" / "binaryPackage"
|
||||||
|
|
||||||
|
when defined(windows):
|
||||||
|
cmd = "cmd /c " & cmd & ".cmd"
|
||||||
|
|
||||||
test "can execute v2":
|
test "can execute v2":
|
||||||
let (output, exitCode) =
|
let (output, exitCode) =
|
||||||
execCmdEx(installDir / "bin" / "binaryPackage".addFileExt(ExeExt))
|
execCmdEx(cmd)
|
||||||
check exitCode == QuitSuccess
|
check exitCode == QuitSuccess
|
||||||
check output.strip() == "v2"
|
check output.strip() == "v2"
|
||||||
|
|
||||||
|
|
@ -536,7 +560,7 @@ suite "can handle two binary versions":
|
||||||
check execNimble("remove", "binaryPackage@2.0", "-y").exitCode==QuitSuccess
|
check execNimble("remove", "binaryPackage@2.0", "-y").exitCode==QuitSuccess
|
||||||
|
|
||||||
let (output, exitCode) =
|
let (output, exitCode) =
|
||||||
execCmdEx(installDir / "bin" / "binaryPackage".addFileExt(ExeExt))
|
execCmdEx(cmd)
|
||||||
check exitCode == QuitSuccess
|
check exitCode == QuitSuccess
|
||||||
check output.strip() == "v1"
|
check output.strip() == "v1"
|
||||||
|
|
||||||
|
|
@ -544,7 +568,7 @@ suite "can handle two binary versions":
|
||||||
check execNimble("remove", "binaryPackage@1.0", "-y").exitCode==QuitSuccess
|
check execNimble("remove", "binaryPackage@1.0", "-y").exitCode==QuitSuccess
|
||||||
|
|
||||||
let (output, exitCode) =
|
let (output, exitCode) =
|
||||||
execCmdEx(installDir / "bin" / "binaryPackage".addFileExt(ExeExt))
|
execCmdEx(cmd)
|
||||||
check exitCode == QuitSuccess
|
check exitCode == QuitSuccess
|
||||||
check output.strip() == "v2"
|
check output.strip() == "v2"
|
||||||
|
|
||||||
|
|
@ -678,9 +702,9 @@ suite "path command":
|
||||||
test "can get correct path for srcDir (#531)":
|
test "can get correct path for srcDir (#531)":
|
||||||
check execNimble("uninstall", "srcdirtest", "-y").exitCode == QuitSuccess
|
check execNimble("uninstall", "srcdirtest", "-y").exitCode == QuitSuccess
|
||||||
cd "develop/srcdirtest":
|
cd "develop/srcdirtest":
|
||||||
let (output, exitCode) = execNimble("install", "-y")
|
let (_, exitCode) = execNimble("install", "-y")
|
||||||
check exitCode == QuitSuccess
|
check exitCode == QuitSuccess
|
||||||
let (output, exitCode) = execNimble("path", "srcdirtest")
|
let (output, _) = execNimble("path", "srcdirtest")
|
||||||
check output.strip() == installDir / "pkgs" / "srcdirtest-1.0"
|
check output.strip() == installDir / "pkgs" / "srcdirtest-1.0"
|
||||||
|
|
||||||
suite "test command":
|
suite "test command":
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue