Copy files during prepare, NEP1 conformance
This commit is contained in:
parent
7fbc8fbcde
commit
4b91f1bbbe
3 changed files with 93 additions and 73 deletions
|
|
@ -101,6 +101,8 @@ The following keys can be used to prepare dependencies such as downloading ZIP f
|
||||||
|
|
||||||
```execute``` = command to run during preparation
|
```execute``` = command to run during preparation
|
||||||
|
|
||||||
|
```copy``` = copy a file to another location. Preferred over moving to preserve original. Comma separate for multiple entries. E.g. copy = "output/config.h.in=output/config.h"
|
||||||
|
|
||||||
_[n.wildcard]_
|
_[n.wildcard]_
|
||||||
|
|
||||||
File wildcards such as *.nim, ssl*.h, etc. can be used to perform tasks across a group of files. This is useful to define common operations such as global text replacements without having to specify an explicit section for every single file. These operations will be performed on every matching file that is defined as a _sourcefile_ or recursed files. Only applies on source files following the wildcard declarations.
|
File wildcards such as *.nim, ssl*.h, etc. can be used to perform tasks across a group of files. This is useful to define common operations such as global text replacements without having to specify an explicit section for every single file. These operations will be performed on every matching file that is defined as a _sourcefile_ or recursed files. Only applies on source files following the wildcard declarations.
|
||||||
|
|
|
||||||
162
nimgen.nim
162
nimgen.nim
|
|
@ -1,17 +1,17 @@
|
||||||
import nre, os, ospaths, osproc, parsecfg, pegs, ropes, sequtils, streams, strutils, tables
|
import nre, os, ospaths, osproc, parsecfg, pegs, ropes, sequtils, streams, strutils, tables
|
||||||
|
|
||||||
var
|
var
|
||||||
DONE: seq[string] = @[]
|
gDoneRecursive: seq[string] = @[]
|
||||||
DONE_INLINE: seq[string] = @[]
|
gDoneInline: seq[string] = @[]
|
||||||
|
|
||||||
CONFIG: Config
|
gConfig: Config
|
||||||
FILTER = ""
|
gFilter = ""
|
||||||
QUOTES = true
|
gQuotes = true
|
||||||
OUTPUT = ""
|
gOutput = ""
|
||||||
INCLUDES: seq[string] = @[]
|
gIncludes: seq[string] = @[]
|
||||||
EXCLUDES: seq[string] = @[]
|
gExcludes: seq[string] = @[]
|
||||||
RENAMES = initTable[string, string]()
|
gRenames = initTable[string, string]()
|
||||||
WILDCARDS = newConfig()
|
gWildcards = newConfig()
|
||||||
|
|
||||||
const DOC = """
|
const DOC = """
|
||||||
Nimgen is a helper for c2nim to simpilfy and automate the wrapping of C libraries
|
Nimgen is a helper for c2nim to simpilfy and automate the wrapping of C libraries
|
||||||
|
|
@ -52,7 +52,7 @@ proc extractZip(zipfile: string) =
|
||||||
if defined(Windows):
|
if defined(Windows):
|
||||||
cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\""
|
cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\""
|
||||||
|
|
||||||
setCurrentDir(OUTPUT)
|
setCurrentDir(gOutput)
|
||||||
defer: setCurrentDir("..")
|
defer: setCurrentDir("..")
|
||||||
|
|
||||||
echo "Extracting " & zipfile
|
echo "Extracting " & zipfile
|
||||||
|
|
@ -67,9 +67,9 @@ proc downloadUrl(url: string) =
|
||||||
if defined(Windows):
|
if defined(Windows):
|
||||||
cmd = "powershell wget $# -OutFile $#"
|
cmd = "powershell wget $# -OutFile $#"
|
||||||
|
|
||||||
if not (ext == ".zip" and fileExists(OUTPUT/file)):
|
if not (ext == ".zip" and fileExists(gOutput/file)):
|
||||||
echo "Downloading " & file
|
echo "Downloading " & file
|
||||||
discard execProc(cmd % [url, OUTPUT/file])
|
discard execProc(cmd % [url, gOutput/file])
|
||||||
|
|
||||||
if ext == ".zip":
|
if ext == ".zip":
|
||||||
extractZip(file)
|
extractZip(file)
|
||||||
|
|
@ -77,18 +77,18 @@ proc downloadUrl(url: string) =
|
||||||
proc gitReset() =
|
proc gitReset() =
|
||||||
echo "Resetting Git repo"
|
echo "Resetting Git repo"
|
||||||
|
|
||||||
setCurrentDir(OUTPUT)
|
setCurrentDir(gOutput)
|
||||||
defer: setCurrentDir("..")
|
defer: setCurrentDir("..")
|
||||||
|
|
||||||
discard execProc("git reset --hard HEAD")
|
discard execProc("git reset --hard HEAD")
|
||||||
|
|
||||||
proc gitRemotePull(url: string, pull=true) =
|
proc gitRemotePull(url: string, pull=true) =
|
||||||
if dirExists(OUTPUT/".git"):
|
if dirExists(gOutput/".git"):
|
||||||
if pull:
|
if pull:
|
||||||
gitReset()
|
gitReset()
|
||||||
return
|
return
|
||||||
|
|
||||||
setCurrentDir(OUTPUT)
|
setCurrentDir(gOutput)
|
||||||
defer: setCurrentDir("..")
|
defer: setCurrentDir("..")
|
||||||
|
|
||||||
echo "Setting up Git repo"
|
echo "Setting up Git repo"
|
||||||
|
|
@ -101,11 +101,11 @@ proc gitRemotePull(url: string, pull=true) =
|
||||||
|
|
||||||
proc gitSparseCheckout(plist: string) =
|
proc gitSparseCheckout(plist: string) =
|
||||||
let sparsefile = ".git/info/sparse-checkout"
|
let sparsefile = ".git/info/sparse-checkout"
|
||||||
if fileExists(OUTPUT/sparsefile):
|
if fileExists(gOutput/sparsefile):
|
||||||
gitReset()
|
gitReset()
|
||||||
return
|
return
|
||||||
|
|
||||||
setCurrentDir(OUTPUT)
|
setCurrentDir(gOutput)
|
||||||
defer: setCurrentDir("..")
|
defer: setCurrentDir("..")
|
||||||
|
|
||||||
discard execProc("git config core.sparsecheckout true")
|
discard execProc("git config core.sparsecheckout true")
|
||||||
|
|
@ -114,6 +114,20 @@ proc gitSparseCheckout(plist: string) =
|
||||||
echo "Checking out artifacts"
|
echo "Checking out artifacts"
|
||||||
discard execProc("git pull --depth=1 origin master")
|
discard execProc("git pull --depth=1 origin master")
|
||||||
|
|
||||||
|
proc doCopy(flist: string) =
|
||||||
|
for pair in flist.split(","):
|
||||||
|
let spl = pair.split("=")
|
||||||
|
if spl.len() != 2:
|
||||||
|
echo "Bad copy syntax: " & flist
|
||||||
|
quit(1)
|
||||||
|
|
||||||
|
let
|
||||||
|
lfile = spl[0].strip()
|
||||||
|
rfile = spl[1].strip()
|
||||||
|
|
||||||
|
copyFile(lfile, rfile)
|
||||||
|
echo "Copied $# to $#" % [lfile, rfile]
|
||||||
|
|
||||||
proc getKey(ukey: string): tuple[key: string, val: bool] =
|
proc getKey(ukey: string): tuple[key: string, val: bool] =
|
||||||
var kv = ukey.replace(re"\..*", "").split("-", 1)
|
var kv = ukey.replace(re"\..*", "").split("-", 1)
|
||||||
if kv.len() == 1:
|
if kv.len() == 1:
|
||||||
|
|
@ -132,20 +146,20 @@ proc getKey(ukey: string): tuple[key: string, val: bool] =
|
||||||
|
|
||||||
proc getNimout(file: string, rename=true): string =
|
proc getNimout(file: string, rename=true): string =
|
||||||
result = file.splitFile().name.replace(re"[\-\.]", "_") & ".nim"
|
result = file.splitFile().name.replace(re"[\-\.]", "_") & ".nim"
|
||||||
if OUTPUT != "":
|
if gOutput != "":
|
||||||
result = OUTPUT/result
|
result = gOutput/result
|
||||||
|
|
||||||
if not rename:
|
if not rename:
|
||||||
return
|
return
|
||||||
|
|
||||||
if RENAMES.hasKey(file):
|
if gRenames.hasKey(file):
|
||||||
result = RENAMES[file]
|
result = gRenames[file]
|
||||||
|
|
||||||
if not dirExists(parentDir(result)):
|
if not dirExists(parentDir(result)):
|
||||||
createDir(parentDir(result))
|
createDir(parentDir(result))
|
||||||
|
|
||||||
proc exclude(file: string): bool =
|
proc exclude(file: string): bool =
|
||||||
for excl in EXCLUDES:
|
for excl in gExcludes:
|
||||||
if excl in file:
|
if excl in file:
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
|
|
@ -159,7 +173,7 @@ proc search(file: string): string =
|
||||||
result = getNimout(file)
|
result = getNimout(file)
|
||||||
elif not fileExists(result) and not dirExists(result):
|
elif not fileExists(result) and not dirExists(result):
|
||||||
var found = false
|
var found = false
|
||||||
for inc in INCLUDES:
|
for inc in gIncludes:
|
||||||
result = inc/file
|
result = inc/file
|
||||||
if fileExists(result) or dirExists(result):
|
if fileExists(result) or dirExists(result):
|
||||||
found = true
|
found = true
|
||||||
|
|
@ -265,7 +279,6 @@ proc rename(file: string, renfile: string) =
|
||||||
nimout = getNimout(file, false)
|
nimout = getNimout(file, false)
|
||||||
newname = renfile.replace("$nimout", extractFilename(nimout))
|
newname = renfile.replace("$nimout", extractFilename(nimout))
|
||||||
|
|
||||||
#if newname =~ peg"(!\$.)*{'$replace'\s*'('\s*{(!\,\S)+}\s*','\s*{(!\)\S)+}\s*')'}":
|
|
||||||
if newname =~ peg"(!\$.)*{'$replace'\s*'('\s*{(!\)\S)+}')'}":
|
if newname =~ peg"(!\$.)*{'$replace'\s*'('\s*{(!\)\S)+}')'}":
|
||||||
var final = nimout.extractFilename()
|
var final = nimout.extractFilename()
|
||||||
for entry in matches[1].split(","):
|
for entry in matches[1].split(","):
|
||||||
|
|
@ -274,14 +287,14 @@ proc rename(file: string, renfile: string) =
|
||||||
echo "Bad replace syntax: " & renfile
|
echo "Bad replace syntax: " & renfile
|
||||||
quit(1)
|
quit(1)
|
||||||
|
|
||||||
var
|
let
|
||||||
srch = spl[0].strip()
|
srch = spl[0].strip()
|
||||||
repl = spl[1].strip()
|
repl = spl[1].strip()
|
||||||
|
|
||||||
final = final.replace(srch, repl)
|
final = final.replace(srch, repl)
|
||||||
newname = newname.replace(matches[0], final)
|
newname = newname.replace(matches[0], final)
|
||||||
|
|
||||||
RENAMES[file] = OUTPUT/newname
|
gRenames[file] = gOutput/newname
|
||||||
|
|
||||||
proc compile(dir="", file=""): string =
|
proc compile(dir="", file=""): string =
|
||||||
proc fcompile(file: string): string =
|
proc fcompile(file: string): string =
|
||||||
|
|
@ -309,19 +322,19 @@ proc fixFuncProtos(file: string) =
|
||||||
|
|
||||||
proc getIncls(file: string, inline=false): seq[string] =
|
proc getIncls(file: string, inline=false): seq[string] =
|
||||||
result = @[]
|
result = @[]
|
||||||
if inline and file in DONE_INLINE:
|
if inline and file in gDoneInline:
|
||||||
return
|
return
|
||||||
|
|
||||||
withFile(file):
|
withFile(file):
|
||||||
for f in content.findIter(re"(?m)^\s*#\s*include\s+(.*?)$"):
|
for f in content.findIter(re"(?m)^\s*#\s*include\s+(.*?)$"):
|
||||||
var inc = f.captures[0].strip()
|
var inc = f.captures[0].strip()
|
||||||
if ((QUOTES and inc.contains("\"")) or (FILTER != "" and FILTER in inc)) and (not exclude(inc)):
|
if ((gQuotes and inc.contains("\"")) or (gFilter != "" and gFilter in inc)) and (not exclude(inc)):
|
||||||
result.add(
|
result.add(
|
||||||
inc.replace(re"""[<>"]""", "").replace(re"\/[\*\/].*$", "").strip())
|
inc.replace(re"""[<>"]""", "").replace(re"\/[\*\/].*$", "").strip())
|
||||||
|
|
||||||
result = result.deduplicate()
|
result = result.deduplicate()
|
||||||
|
|
||||||
DONE_INLINE.add(file)
|
gDoneInline.add(file)
|
||||||
|
|
||||||
if inline:
|
if inline:
|
||||||
var sres = newSeq[string]()
|
var sres = newSeq[string]()
|
||||||
|
|
@ -353,7 +366,7 @@ proc runPreprocess(file, ppflags, flags: string, inline: bool): string =
|
||||||
pproc = if flags.contains("cpp"): "g++" else: "gcc"
|
pproc = if flags.contains("cpp"): "g++" else: "gcc"
|
||||||
cmd = "$# -E $# $#" % [pproc, ppflags, file]
|
cmd = "$# -E $# $#" % [pproc, ppflags, file]
|
||||||
|
|
||||||
for inc in INCLUDES:
|
for inc in gIncludes:
|
||||||
cmd &= " -I " & inc
|
cmd &= " -I " & inc
|
||||||
|
|
||||||
# Run preprocessor
|
# Run preprocessor
|
||||||
|
|
@ -414,11 +427,11 @@ proc c2nim(fl, outfile, flags, ppflags: string, recurse, inline, preprocess, cta
|
||||||
if file == "":
|
if file == "":
|
||||||
return
|
return
|
||||||
|
|
||||||
if file in DONE:
|
if file in gDoneRecursive:
|
||||||
return
|
return
|
||||||
|
|
||||||
echo "Processing $# => $#" % [file, outfile]
|
echo "Processing $# => $#" % [file, outfile]
|
||||||
DONE.add(file)
|
gDoneRecursive.add(file)
|
||||||
|
|
||||||
fixFuncProtos(file)
|
fixFuncProtos(file)
|
||||||
|
|
||||||
|
|
@ -455,10 +468,11 @@ proc c2nim(fl, outfile, flags, ppflags: string, recurse, inline, preprocess, cta
|
||||||
passC = ""
|
passC = ""
|
||||||
outlib = ""
|
outlib = ""
|
||||||
outpragma = ""
|
outpragma = ""
|
||||||
|
outcompile = ""
|
||||||
|
|
||||||
passC = "import strutils\n"
|
passC = "import strutils\n"
|
||||||
for inc in INCLUDES:
|
for inc in gIncludes:
|
||||||
passC &= ("""{.passC: "-I\"" & gorge("nimble path $#").strip() & "/$#\"".}""" % [OUTPUT, inc]) & "\n"
|
passC &= ("""{.passC: "-I\"" & gorge("nimble path $#").strip() & "/$#\"".}""" % [gOutput, inc]) & "\n"
|
||||||
|
|
||||||
for prag in pragma:
|
for prag in pragma:
|
||||||
outpragma &= "{." & prag & ".}\n"
|
outpragma &= "{." & prag & ".}\n"
|
||||||
|
|
@ -517,6 +531,8 @@ proc c2nim(fl, outfile, flags, ppflags: string, recurse, inline, preprocess, cta
|
||||||
freplace(outfile, " {.cdecl.})", ")")
|
freplace(outfile, " {.cdecl.})", ")")
|
||||||
|
|
||||||
# Include {.compile.} directives
|
# Include {.compile.} directives
|
||||||
|
outcompile = compile(compile)
|
||||||
|
|
||||||
for cpl in compile:
|
for cpl in compile:
|
||||||
let fcpl = search(cpl)
|
let fcpl = search(cpl)
|
||||||
if getFileInfo(fcpl).kind == pcFile:
|
if getFileInfo(fcpl).kind == pcFile:
|
||||||
|
|
@ -544,12 +560,12 @@ proc runFile(file: string, cfgin: OrderedTableRef) =
|
||||||
cfg = cfgin
|
cfg = cfgin
|
||||||
sfile = search(file)
|
sfile = search(file)
|
||||||
|
|
||||||
for pattern in WILDCARDS.keys():
|
for pattern in gWildcards.keys():
|
||||||
let pat = pattern.replace(".", "\\.").replace("*", ".*").replace("?", ".?")
|
let pat = pattern.replace(".", "\\.").replace("*", ".*").replace("?", ".?")
|
||||||
if file.find(re(pat)).isSome():
|
if file.find(re(pat)).isSome():
|
||||||
echo "Appending " & file & " " & pattern
|
echo "Appending " & file & " " & pattern
|
||||||
for key in WILDCARDS[pattern].keys():
|
for key in gWildcards[pattern].keys():
|
||||||
cfg[key & "." & pattern] = WILDCARDS[pattern][key]
|
cfg[key & "." & pattern] = gWildcards[pattern][key]
|
||||||
|
|
||||||
var
|
var
|
||||||
srch = ""
|
srch = ""
|
||||||
|
|
@ -634,73 +650,75 @@ proc runCfg(cfg: string) =
|
||||||
echo "Config doesn't exist: " & cfg
|
echo "Config doesn't exist: " & cfg
|
||||||
quit(1)
|
quit(1)
|
||||||
|
|
||||||
CONFIG = loadConfig(cfg)
|
gConfig = loadConfig(cfg)
|
||||||
|
|
||||||
if CONFIG.hasKey("n.global"):
|
if gConfig.hasKey("n.global"):
|
||||||
if CONFIG["n.global"].hasKey("output"):
|
if gConfig["n.global"].hasKey("output"):
|
||||||
OUTPUT = CONFIG["n.global"]["output"]
|
gOutput = gConfig["n.global"]["output"]
|
||||||
if dirExists(OUTPUT):
|
if dirExists(gOutput):
|
||||||
if "-f" in commandLineParams():
|
if "-f" in commandLineParams():
|
||||||
try:
|
try:
|
||||||
removeDir(OUTPUT)
|
removeDir(gOutput)
|
||||||
except OSError:
|
except OSError:
|
||||||
echo "Directory in use: " & OUTPUT
|
echo "Directory in use: " & gOutput
|
||||||
quit(1)
|
quit(1)
|
||||||
else:
|
else:
|
||||||
for f in walkFiles(OUTPUT/"*.nim"):
|
for f in walkFiles(gOutput/"*.nim"):
|
||||||
try:
|
try:
|
||||||
removeFile(f)
|
removeFile(f)
|
||||||
except OSError:
|
except OSError:
|
||||||
echo "Unable to delete: " & f
|
echo "Unable to delete: " & f
|
||||||
quit(1)
|
quit(1)
|
||||||
createDir(OUTPUT)
|
createDir(gOutput)
|
||||||
|
|
||||||
if CONFIG["n.global"].hasKey("filter"):
|
if gConfig["n.global"].hasKey("filter"):
|
||||||
FILTER = CONFIG["n.global"]["filter"]
|
gFilter = gConfig["n.global"]["filter"]
|
||||||
if CONFIG["n.global"].hasKey("quotes"):
|
if gConfig["n.global"].hasKey("quotes"):
|
||||||
if CONFIG["n.global"]["quotes"] == "false":
|
if gConfig["n.global"]["quotes"] == "false":
|
||||||
QUOTES = false
|
gQuotes = false
|
||||||
|
|
||||||
if CONFIG.hasKey("n.include"):
|
if gConfig.hasKey("n.include"):
|
||||||
for inc in CONFIG["n.include"].keys():
|
for inc in gConfig["n.include"].keys():
|
||||||
INCLUDES.add(inc)
|
gIncludes.add(inc)
|
||||||
|
|
||||||
if CONFIG.hasKey("n.exclude"):
|
if gConfig.hasKey("n.exclude"):
|
||||||
for excl in CONFIG["n.exclude"].keys():
|
for excl in gConfig["n.exclude"].keys():
|
||||||
EXCLUDES.add(excl)
|
gExcludes.add(excl)
|
||||||
|
|
||||||
if CONFIG.hasKey("n.prepare"):
|
if gConfig.hasKey("n.prepare"):
|
||||||
for prep in CONFIG["n.prepare"].keys():
|
for prep in gConfig["n.prepare"].keys():
|
||||||
let (key, val) = getKey(prep)
|
let (key, val) = getKey(prep)
|
||||||
if val == true:
|
if val == true:
|
||||||
if key == "download":
|
if key == "download":
|
||||||
downloadUrl(CONFIG["n.prepare"][prep])
|
downloadUrl(gConfig["n.prepare"][prep])
|
||||||
elif key == "extract":
|
elif key == "extract":
|
||||||
extractZip(CONFIG["n.prepare"][prep])
|
extractZip(gConfig["n.prepare"][prep])
|
||||||
elif key == "git":
|
elif key == "git":
|
||||||
gitRemotePull(CONFIG["n.prepare"][prep])
|
gitRemotePull(gConfig["n.prepare"][prep])
|
||||||
elif key == "gitremote":
|
elif key == "gitremote":
|
||||||
gitRemotePull(CONFIG["n.prepare"][prep], false)
|
gitRemotePull(gConfig["n.prepare"][prep], false)
|
||||||
elif key == "gitsparse":
|
elif key == "gitsparse":
|
||||||
gitSparseCheckout(CONFIG["n.prepare"][prep])
|
gitSparseCheckout(gConfig["n.prepare"][prep])
|
||||||
elif key == "execute":
|
elif key == "execute":
|
||||||
discard execProc(CONFIG["n.prepare"][prep])
|
discard execProc(gConfig["n.prepare"][prep])
|
||||||
|
elif key == "copy":
|
||||||
|
doCopy(gConfig["n.prepare"][prep])
|
||||||
|
|
||||||
if CONFIG.hasKey("n.wildcard"):
|
if gConfig.hasKey("n.wildcard"):
|
||||||
var wildcard = ""
|
var wildcard = ""
|
||||||
for wild in CONFIG["n.wildcard"].keys():
|
for wild in gConfig["n.wildcard"].keys():
|
||||||
let (key, val) = getKey(wild)
|
let (key, val) = getKey(wild)
|
||||||
if val == true:
|
if val == true:
|
||||||
if key == "wildcard":
|
if key == "wildcard":
|
||||||
wildcard = CONFIG["n.wildcard"][wild]
|
wildcard = gConfig["n.wildcard"][wild]
|
||||||
else:
|
else:
|
||||||
WILDCARDS.setSectionKey(wildcard, wild, CONFIG["n.wildcard"][wild])
|
gWildcards.setSectionKey(wildcard, wild, gConfig["n.wildcard"][wild])
|
||||||
|
|
||||||
for file in CONFIG.keys():
|
for file in gConfig.keys():
|
||||||
if file in @["n.global", "n.include", "n.exclude", "n.prepare", "n.wildcard"]:
|
if file in @["n.global", "n.include", "n.exclude", "n.prepare", "n.wildcard"]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
runFile(file, CONFIG[file])
|
runFile(file, gConfig[file])
|
||||||
|
|
||||||
# ###
|
# ###
|
||||||
# Main loop
|
# Main loop
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
author = "genotrance"
|
author = "genotrance"
|
||||||
description = "c2nim helper to simplify and automate the wrapping of C libraries"
|
description = "c2nim helper to simplify and automate the wrapping of C libraries"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue