implements experimental new config system based on NimScript
This commit is contained in:
parent
d81578cb9b
commit
69b32637b1
13 changed files with 398 additions and 69 deletions
152
lib/system/nimscript.nim
Normal file
152
lib/system/nimscript.nim
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
#
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2015 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
# Nim's configuration system now uses Nim for scripting. This module provides
|
||||
# a few things that are required for this to work.
|
||||
|
||||
template builtin = discard
|
||||
|
||||
proc listDirs*(dir: string): seq[string] = builtin
|
||||
proc listFiles*(dir: string): seq[string] = builtin
|
||||
|
||||
proc removeDir(dir: string) = builtin
|
||||
proc removeFile(dir: string) = builtin
|
||||
proc moveFile(src, dest: string) = builtin
|
||||
proc createDir(dir: string) = builtin
|
||||
proc getOsError: string = builtin
|
||||
proc setCurrentDir(dir: string) = builtin
|
||||
proc getCurrentDir(): string = builtin
|
||||
proc paramStr*(i: int): string = builtin
|
||||
proc paramCount*(): int = builtin
|
||||
|
||||
proc switch*(key: string, val="") = builtin
|
||||
proc getCommand*(): string = builtin
|
||||
proc setCommand*(cmd: string) = builtin
|
||||
proc cmpIgnoreStyle(a, b: string): int = builtin
|
||||
|
||||
proc strip(s: string): string =
|
||||
var i = 0
|
||||
while s[i] in {' ', '\c', '\L'}: inc i
|
||||
result = s.substr(i)
|
||||
|
||||
template `--`*(key, val: untyped) = switch(astToStr(key), strip astToStr(val))
|
||||
template `--`*(key: untyped) = switch(astToStr(key), "")
|
||||
|
||||
type
|
||||
ScriptMode* {.pure.} = enum
|
||||
Silent,
|
||||
Verbose,
|
||||
Whatif
|
||||
|
||||
var
|
||||
mode*: ScriptMode ## Set this to influence how mkDir, rmDir, rmFile etc.
|
||||
## behave
|
||||
|
||||
template checkOsError =
|
||||
let err = getOsError()
|
||||
if err.len > 0: raise newException(OSError, err)
|
||||
|
||||
template log(msg: string, body: untyped) =
|
||||
if mode == ScriptMode.Verbose or mode == ScriptMode.Whatif:
|
||||
echo "[NimScript] ", msg
|
||||
if mode != ScriptMode.WhatIf:
|
||||
body
|
||||
|
||||
proc rmDir*(dir: string) {.raises: [OSError].} =
|
||||
log "rmDir: " & dir:
|
||||
removeDir dir
|
||||
checkOsError()
|
||||
|
||||
proc rmFile*(dir: string) {.raises: [OSError].} =
|
||||
log "rmFile: " & dir:
|
||||
removeFile dir
|
||||
checkOsError()
|
||||
|
||||
proc mkDir*(dir: string) {.raises: [OSError].} =
|
||||
log "mkDir: " & dir:
|
||||
createDir dir
|
||||
checkOsError()
|
||||
|
||||
proc mvFile*(`from`, to: string) {.raises: [OSError].} =
|
||||
log "mvFile: " & `from` & ", " & to:
|
||||
moveFile `from`, to
|
||||
checkOsError()
|
||||
|
||||
proc exec*(command: string, input = "", cache = "") =
|
||||
## Executes an external process.
|
||||
log "exec: " & command:
|
||||
echo staticExec(command, input, cache)
|
||||
|
||||
proc put*(key, value: string) =
|
||||
## Sets a configuration 'key' like 'gcc.options.always' to its value.
|
||||
builtin
|
||||
|
||||
proc get*(key: string): string =
|
||||
## Retrieves a configuration 'key' like 'gcc.options.always'.
|
||||
builtin
|
||||
|
||||
proc exists*(key: string): bool =
|
||||
## Checks for the existance of a configuration 'key'
|
||||
## like 'gcc.options.always'.
|
||||
builtin
|
||||
|
||||
proc nimcacheDir*(): string =
|
||||
## Retrieves the location of 'nimcache'.
|
||||
builtin
|
||||
|
||||
proc thisDir*(): string =
|
||||
## Retrieves the location of the current ``nims`` script file.
|
||||
builtin
|
||||
|
||||
proc cd*(dir: string) {.raises: [OSError].} =
|
||||
## Changes the current directory.
|
||||
##
|
||||
## The change is permanent for the rest of the execution, since this is just
|
||||
## a shortcut for `os.setCurrentDir()
|
||||
## <http://nim-lang.org/os.html#setCurrentDir,string>`_ . Use the `withDir()
|
||||
## <#withDir>`_ template if you want to perform a temporary change only.
|
||||
setCurrentDir(dir)
|
||||
checkOsError()
|
||||
|
||||
template withDir*(dir: string; body: untyped): untyped =
|
||||
## Changes the current directory temporarily.
|
||||
##
|
||||
## If you need a permanent change, use the `cd() <#cd>`_ proc. Usage example:
|
||||
##
|
||||
## .. code-block:: nimrod
|
||||
## withDir "foo":
|
||||
## # inside foo
|
||||
## #back to last dir
|
||||
var curDir = getCurrentDir()
|
||||
try:
|
||||
cd(dir)
|
||||
body
|
||||
finally:
|
||||
cd(curDir)
|
||||
|
||||
template `==?`(a, b: string): bool = cmpIgnoreStyle(a, b) == 0
|
||||
|
||||
proc writeTask(name, desc: string) =
|
||||
if desc.len > 0:
|
||||
var spaces = " "
|
||||
for i in 0 ..< 20 - name.len: spaces.add ' '
|
||||
echo name, spaces, desc
|
||||
|
||||
template task*(name: untyped; description: string; body: untyped): untyped =
|
||||
## Defines a task. Hidden tasks are supported via an empty description.
|
||||
proc `name Task`() = body
|
||||
|
||||
let cmd = getCommand()
|
||||
if cmd.len == 0 or cmd ==? "help" or cmd == "nop":
|
||||
setCommand "nop"
|
||||
writeTask(astToStr(name), description)
|
||||
elif cmd ==? astToStr(name):
|
||||
setCommand "nop"
|
||||
`name Task`()
|
||||
|
|
@ -182,7 +182,10 @@ proc readAllFile(file: File): string =
|
|||
proc readAll(file: File): TaintedString =
|
||||
# Separate handling needed because we need to buffer when we
|
||||
# don't know the overall length of the File.
|
||||
let len = if file != stdin: rawFileSize(file) else: -1
|
||||
when declared(stdin):
|
||||
let len = if file != stdin: rawFileSize(file) else: -1
|
||||
else:
|
||||
let len = rawFileSize(file)
|
||||
if len > 0:
|
||||
result = readAllFile(file, len).TaintedString
|
||||
else:
|
||||
|
|
@ -216,9 +219,9 @@ proc writeLine[Ty](f: File, x: varargs[Ty, `$`]) =
|
|||
for i in items(x): write(f, i)
|
||||
write(f, "\n")
|
||||
|
||||
|
||||
proc rawEcho(x: string) {.inline, compilerproc.} = write(stdout, x)
|
||||
proc rawEchoNL() {.inline, compilerproc.} = write(stdout, "\n")
|
||||
when declared(stdout):
|
||||
proc rawEcho(x: string) {.inline, compilerproc.} = write(stdout, x)
|
||||
proc rawEchoNL() {.inline, compilerproc.} = write(stdout, "\n")
|
||||
|
||||
# interface to the C procs:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue