Implemented command execution.
h3rald h3rald@h3rald.com
Sat, 19 Nov 2016 21:25:11 +0100
3 files changed,
81 insertions(+),
18 deletions(-)
M
lib/logger.nim
→
lib/logger.nim
@@ -35,8 +35,8 @@ let prefix = level.logPrefix()
f.setForegroundColor(prefix.color) f.write(prefix.msg) f.write(ln) - f.write("\n") resetAttributes() + f.write("\n") if level in {lvlError, lvlFatal}: flushFile(f) proc newStyledConsoleLogger*(levelThreshold = lvlAll; fmtStr = " "): StyledConsoleLogger =@@ -68,4 +68,4 @@ else:
val = "warn" lvl = lvlWarn setLogFilter(lvl) - return val+ return val
M
lib/project.nim
→
lib/project.nim
@@ -2,18 +2,21 @@ import
os, json, logging, - strutils + strutils, + sequtils, + pegs type NiftyProject* = object - dir: string - storage: string - commands: JsonNode - packages: JsonNode + dir*: string + storage*: string + commands*: JsonNode + packages*: JsonNode +let placeholder = peg"'{{' {[^}]+} '}}'" proc newNiftyProject*(dir: string): NiftyProject = - result.dir = dir + result.dir = dir.expandFileName proc configFile*(prj: NiftyProject): string = return prj.dir/"nifty.json"@@ -28,15 +31,23 @@ var o = newJObject()
o["storage"] = %prj.storage o["commands"] = newJObject() o["commands"]["install"] = newJObject() - o["commands"]["install"]["git+src"] = %"git clone {{src}} --depth 1" - o["commands"]["install"]["git+src+tag"] = %"git clone --branch {{tag}} {{src}} --depth 1" + o["commands"]["install"]["git+src"] = newJObject() + o["commands"]["install"]["git+src"]["cmd"] = %"git clone {{src}} --depth 1" + o["commands"]["install"]["git+src+tag"] = newJObject() + o["commands"]["install"]["git+src+tag"]["cmd"] = %"git clone --branch {{tag}} {{src}} --depth 1" o["commands"]["update"] = newJObject() - o["commands"]["update"]["git+name"] = %"cd {{name}} && git pull; cd .." + o["commands"]["update"]["git+name"] = newJObject() + o["commands"]["update"]["git+name"]["cmd"] = %"git pull" + o["commands"]["update"]["git+name"]["pwd"] = %"{{name}}" o["packages"] = newJObject() prj.configFile.writeFile(o.pretty) proc load*(prj: var NiftyProject) = + if not prj.configFile.fileExists: + fatal "Project not initialized - configuration file not found." + quit(10) let cfg = prj.configFile.parseFile + prj.storage = cfg["storage"].getStr.expandFileName prj.commands = cfg["commands"] prj.packages = cfg["packages"]@@ -69,3 +80,49 @@ return
prj.packages.delete(alias) prj.save notice "Package definition '$1' removed." % alias + +proc lookupCommand(prj: NiftyProject, command: string, props: seq[string], cmd: var JsonNode): bool = + if not prj.commands.hasKey command: + warn "Command '$1' not found" % command + return + var cmds = prj.commands[command] + var score = 0 + # Cycle through command definitions + for key, val in cmds: + var params = key.split("+") + # Check if all params are available + var match = params.all do (x: string) -> bool: + props.contains(x) + if match and params.len > score: + score = params.len + cmd = val + return score > 0 + +proc execute*(prj: var NiftyProject, command, alias: string) = + prj.load + if not prj.packages.hasKey alias: + warn "Package definition '$1' not found. Nothing to do." % alias + return + notice "$1: $2" % [command, alias] + let package = prj.packages[alias] + var keys = newSeq[string](0) + for key, val in package.pairs: + keys.add key + var res: JsonNode + var cmd: string + var pwd = prj.storage + if prj.lookupCommand(command, keys, res): + cmd = res["cmd"].getStr.replace(placeholder) do (m: int, n: int, c: openArray[string]) -> string: + return package[c[0]].getStr + if res.hasKey("pwd"): + pwd = res["pwd"].getStr.replace(placeholder) do (m: int, n: int, c: openArray[string]) -> string: + return package[c[0]].getStr + notice "Executing: $1" % cmd + pwd = (prj.storage/pwd).expandFileName() + pwd.createDir() + pwd.setCurrentDir() + discard execShellCmd cmd + else: + warn "Command '$1' not available for package '$2'" % [command, alias] + setCurrentDir(prj.dir) +
M
nifty.nim
→
nifty.nim
@@ -9,7 +9,7 @@ import
lib/logger newStyledConsoleLogger().addHandler() -setLogFilter(lvlNotice) +setLogFilter(lvlInfo) import lib/config,@@ -66,20 +66,26 @@ case args[0]:
of "init": if prj.configured: fatal "Project already configured." - quit(1) + quit(2) prj.init(storage) notice "Project initialized using '$1' as storage directory." % storage of "map": if args.len < 2: fatal "No alias specified." - quit(2) + quit(3) prj.map(args[1], %opts) of "unmap": if args.len < 2: fatal "No alias specified." - quit(2) + quit(3) prj.unmap(args[1]) else: - #TODO - echo usage - discard + if args.len < 1: + echo usage + quit(1) + if args.len < 2: + prj.load + for key, val in prj.packages.pairs: + prj.execute(args[0], key) + else: + prj.execute(args[0], args[1])