Nimscript: documented; 'exec' now produces output immediately

This commit is contained in:
Araq 2015-09-07 12:20:37 +02:00
commit a480bebfce
2 changed files with 102 additions and 30 deletions

View file

@ -13,7 +13,7 @@
import import
ast, modules, passes, passaux, condsyms, ast, modules, passes, passaux, condsyms,
options, nimconf, lists, sem, semdata, llstream, vm, vmdef, commands, msgs, options, nimconf, lists, sem, semdata, llstream, vm, vmdef, commands, msgs,
os, times os, times, osproc
# we support 'cmpIgnoreStyle' natively for efficiency: # we support 'cmpIgnoreStyle' natively for efficiency:
from strutils import cmpIgnoreStyle from strutils import cmpIgnoreStyle
@ -73,6 +73,9 @@ proc setupVM*(module: PSym; scriptName: string): PEvalContext =
cbos getLastModificationTime: cbos getLastModificationTime:
setResult(a, toSeconds(getLastModificationTime(getString(a, 0)))) setResult(a, toSeconds(getLastModificationTime(getString(a, 0))))
cbos rawExec:
setResult(a, osproc.execCmd getString(a, 0))
cbconf getEnv: cbconf getEnv:
setResult(a, os.getEnv(a.getString 0)) setResult(a, os.getEnv(a.getString 0))
cbconf existsEnv: cbconf existsEnv:

View file

@ -13,23 +13,51 @@
template builtin = discard template builtin = discard
proc listDirs*(dir: string): seq[string] = builtin proc listDirs*(dir: string): seq[string] =
proc listFiles*(dir: string): seq[string] = builtin ## Lists all the subdirectories (non-recursively) in the directory `dir`.
builtin
proc listFiles*(dir: string): seq[string] =
## Lists all the files (non-recursively) in the directory `dir`.
builtin
proc removeDir(dir: string) = builtin proc removeDir(dir: string){.
proc removeFile(dir: string) = builtin tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
proc moveFile(src, dest: string) = builtin proc removeFile(dir: string) {.
proc copyFile(src, dest: string) = builtin tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
proc createDir(dir: string) = builtin proc moveFile(src, dest: string) {.
tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
proc copyFile(src, dest: string) {.
tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
proc createDir(dir: string) {.tags: [WriteIOEffect], raises: [OSError].} = builtin
proc getOsError: string = builtin proc getOsError: string = builtin
proc setCurrentDir(dir: string) = builtin proc setCurrentDir(dir: string) = builtin
proc getCurrentDir(): string = builtin proc getCurrentDir(): string = builtin
proc paramStr*(i: int): string = builtin proc rawExec(cmd: string): int {.tags: [ExecIOEffect], raises: [OSError].} =
proc paramCount*(): int = builtin builtin
proc paramStr*(i: int): string =
## Retrieves the ``i``'th command line parameter.
builtin
proc paramCount*(): int =
## Retrieves the number of command line parameters.
builtin
proc switch*(key: string, val="") =
## Sets a Nim compiler command line switch, for
## example ``switch("checks", "on")``.
builtin
proc getCommand*(): string =
## Gets the Nim command that the compiler has been invoked with, for example
## "c", "js", "build", "help".
builtin
proc setCommand*(cmd: string) =
## Sets the Nim command that should be continued with after this Nimscript
## has finished.
builtin
proc switch*(key: string, val="") = builtin
proc getCommand*(): string = builtin
proc setCommand*(cmd: string) = builtin
proc cmpIgnoreStyle(a, b: string): int = builtin proc cmpIgnoreStyle(a, b: string): int = builtin
proc cmpIgnoreCase(a, b: string): int = builtin proc cmpIgnoreCase(a, b: string): int = builtin
@ -37,11 +65,23 @@ proc cmpic*(a, b: string): int = cmpIgnoreCase(a, b)
proc getEnv*(key: string): string = builtin proc getEnv*(key: string): string = builtin
proc existsEnv*(key: string): bool = builtin proc existsEnv*(key: string): bool = builtin
proc fileExists*(filename: string): bool = builtin
proc dirExists*(dir: string): bool = builtin
proc existsFile*(filename: string): bool = fileExists(filename) proc fileExists*(filename: string): bool {.tags: [ReadIOEffect].} =
proc existsDir*(dir: string): bool = dirExists(dir) ## Checks if the file exists.
builtin
proc dirExists*(dir: string): bool {.
tags: [ReadIOEffect].} =
## Checks if the directory `dir` exists.
builtin
proc existsFile*(filename: string): bool =
## An alias for ``fileExists``.
fileExists(filename)
proc existsDir*(dir: string): bool =
## An alias for ``dirExists``.
dirExists(dir)
proc toExe*(filename: string): string = proc toExe*(filename: string): string =
## On Windows adds ".exe" to `filename`, else returns `filename` unmodified. ## On Windows adds ".exe" to `filename`, else returns `filename` unmodified.
@ -60,10 +100,11 @@ template `--`*(key, val: untyped) = switch(astToStr(key), strip astToStr(val))
template `--`*(key: untyped) = switch(astToStr(key), "") template `--`*(key: untyped) = switch(astToStr(key), "")
type type
ScriptMode* {.pure.} = enum ScriptMode* {.pure.} = enum ## Controls the behaviour of the script.
Silent, Silent, ## Be silent.
Verbose, Verbose, ## Be verbose.
Whatif Whatif ## Do not run commands, instead just echo what
## would have been done.
var var
mode*: ScriptMode ## Set this to influence how mkDir, rmDir, rmFile etc. mode*: ScriptMode ## Set this to influence how mkDir, rmDir, rmFile etc.
@ -80,31 +121,44 @@ template log(msg: string, body: untyped) =
body body
proc rmDir*(dir: string) {.raises: [OSError].} = proc rmDir*(dir: string) {.raises: [OSError].} =
## Removes the directory `dir`.
log "rmDir: " & dir: log "rmDir: " & dir:
removeDir dir removeDir dir
checkOsError() checkOsError()
proc rmFile*(dir: string) {.raises: [OSError].} = proc rmFile*(file: string) {.raises: [OSError].} =
log "rmFile: " & dir: ## Removes the `file`.
removeFile dir log "rmFile: " & file:
removeFile file
checkOsError() checkOsError()
proc mkDir*(dir: string) {.raises: [OSError].} = proc mkDir*(dir: string) {.raises: [OSError].} =
## Creates the directory `dir` including all necessary subdirectories. If
## the directory already exists, no error is raised.
log "mkDir: " & dir: log "mkDir: " & dir:
createDir dir createDir dir
checkOsError() checkOsError()
proc mvFile*(`from`, to: string) {.raises: [OSError].} = proc mvFile*(`from`, to: string) {.raises: [OSError].} =
## Moves the file `from` to `to`.
log "mvFile: " & `from` & ", " & to: log "mvFile: " & `from` & ", " & to:
moveFile `from`, to moveFile `from`, to
checkOsError() checkOsError()
proc cpFile*(`from`, to: string) {.raises: [OSError].} = proc cpFile*(`from`, to: string) {.raises: [OSError].} =
## Copies the file `from` to `to`.
log "mvFile: " & `from` & ", " & to: log "mvFile: " & `from` & ", " & to:
copyFile `from`, to copyFile `from`, to
checkOsError() checkOsError()
proc exec*(command: string, input = "", cache = "") = proc exec*(command: string) =
## Executes an external process.
log "exec: " & command:
if rawExec(command) != 0:
raise newException(OSError, "FAILED: " & command)
checkOsError()
proc exec*(command: string, input: string, cache = "") =
## Executes an external process. ## Executes an external process.
log "exec: " & command: log "exec: " & command:
echo staticExec(command, input, cache) echo staticExec(command, input, cache)
@ -166,6 +220,11 @@ proc writeTask(name, desc: string) =
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:
##
## .. code-block:: nim
## task build, "default build is via the C backend":
## setCommand "c"
proc `name Task`() = body proc `name Task`() = body
let cmd = getCommand() let cmd = getCommand()
@ -177,13 +236,23 @@ template task*(name: untyped; description: string; body: untyped): untyped =
`name Task`() `name Task`()
var var
packageName* = "" packageName* = "" ## Nimble support: Set this to the package name. It
version*, author*, description*, license*, srcdir*, ## is usually not required to do that, nims' filename is
binDir*, backend*: string ## the default.
version*: string ## Nimble support: The package's version.
author*: string ## Nimble support: The package's author.
description*: string ## Nimble support: The package's description.
license*: string ## Nimble support: The package's license.
srcdir*: string ## Nimble support: The package's source directory.
binDir*: string ## Nimble support: The package's binary directory.
backend*: string ## Nimble support: The package's backend.
skipDirs*, skipFiles*, skipExt*, installDirs*, installFiles*, skipDirs*, skipFiles*, skipExt*, installDirs*, installFiles*,
installExt*, bin*: seq[string] = @[] installExt*, bin*: seq[string] = @[] ## Nimble metadata.
requiresData*: seq[string] = @[] requiresData*: seq[string] = @[] ## Exposes the list of requirements for read
## and write accesses.
proc requires*(deps: varargs[string]) = proc requires*(deps: varargs[string]) =
## Nimble support: Call this to set the list of requirements of your Nimble
## package.
for d in deps: requiresData.add(d) for d in deps: requiresData.add(d)