#
#
# Maintenance program for Nim
# (c) Copyright 2017 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
# See doc/koch.txt for documentation.
#
const
NimbleStableCommit = "63695f490728e3935692c29f3d71944d83bb1e83" # master
when not defined(windows):
const
Z3StableCommit = "65de3f748a6812eecd7db7c478d5fc54424d368b" # the version of Z3 that DrNim uses
when defined(gcc) and defined(windows):
when defined(x86):
{.link: "icons/koch.res".}
else:
{.link: "icons/koch_icon.o".}
when defined(amd64) and defined(windows) and defined(vcc):
{.link: "icons/koch-amd64-windows-vcc.res".}
when defined(i386) and defined(windows) and defined(vcc):
{.link: "icons/koch-i386-windows-vcc.res".}
import std/[os, strutils, parseopt, osproc]
# Using `std/os` instead of `os` to fail early if config isn't set up properly.
# If this fails with: `Error: cannot open file: std/os`, see
# https://github.com/nim-lang/Nim/pull/14291 for explanation + how to fix.
import tools / kochdocs
import tools / deps
const VersionAsString = system.NimVersion
const
HelpText = """
+-----------------------------------------------------------------+
| Maintenance program for Nim |
| Version $1|
| (c) 2017 Andreas Rumpf |
+-----------------------------------------------------------------+
Build time: $2, $3
Usage:
koch [options] command [options for command]
Options:
--help, -h shows this help and quits
--latest bundle the installers with a bleeding edge Nimble
--stable bundle the installers with a stable Nimble (default)
--nim:path use specified path for nim binary
Possible Commands:
boot [options] bootstraps with given command line options
distrohelper [bindir] helper for distro packagers
tools builds Nim related tools
toolsNoNimble builds Nim related tools (except nimble)
doesn't require network connectivity
nimble builds the Nimble tool
Boot options:
-d:release produce a release version of the compiler
-d:nimUseLinenoise use the linenoise library for interactive mode
`nim secret` (not needed on Windows)
-d:leanCompiler produce a compiler without JS codegen or
documentation generator in order to use less RAM
for bootstrapping
Commands for core developers:
runCI runs continuous integration (CI), eg from travis
docs [options] generates the full documentation
csource -d:release builds the C sources for installation
pdf builds the PDF documentation
zip builds the installation zip package
xz builds the installation tar.xz package
testinstall test tar.xz package; Unix only!
installdeps [options] installs external dependency (eg tinyc) to dist/
tests [options] run the testsuite (run a subset of tests by
specifying a category, e.g. `tests cat async`)
temp options creates a temporary compiler for testing
pushcsource push generated C sources to its repo
Web options:
--googleAnalytics:UA-... add the given google analytics code to the docs. To
build the official docs, use UA-48159761-1
"""
let kochExe* = when isMainModule: os.getAppFilename() # always correct when koch is main program, even if `koch` exe renamed eg: `nim c -o:koch_debug koch.nim`
else: getAppDir() / "koch".exe # works for winrelease
proc kochExec*(cmd: string) =
exec kochExe.quoteShell & " " & cmd
proc kochExecFold*(desc, cmd: string) =
execFold(desc, kochExe.quoteShell & " " & cmd)
template withDir(dir, body) =
let old = getCurrentDir()
try:
setCurrentDir(dir)
body
finally:
setCurrentDir(old)
let origDir = getCurrentDir()
setCurrentDir(getAppDir())
proc tryExec(cmd: string): bool =
echo(cmd)
result = execShellCmd(cmd) == 0
proc safeRemove(filename: string) =
if existsFile(filename): removeFile(filename)
proc overwriteFile(source, dest: string) =
safeRemove(dest)
moveFile(source, dest)
proc copyExe(source, dest: string) =
safeRemove(dest)
copyFile(dest=dest, source=source)
inclFilePermissions(dest, {fpUserExec, fpGroupExec, fpOthersExec})
const
compileNimInst = "tools/niminst/niminst"
distDir = "dist"
proc csource(args: string) =
nimexec(("cc $1 -r $3 --var:version=$2 --var:mingw=none csource " &
"--main:compiler/nim.nim compiler/installer.ini $1") %
[args, VersionAsString, compileNimInst])
proc bundleC2nim(args: string) =
cloneDependency(distDir, "https://github.com/nim-lang/c2nim.git")
nimCompile("dist/c2nim/c2nim",
options = "--noNimblePath --path:. " & args)
proc bundleNimbleExe(latest: bool, args: string) =
let commit = if latest: "HEAD" else: NimbleStableCommit
cloneDependency(distDir, "https://github.com/nim-lang/nimble.git", commit = commit)
# installer.ini expects it under $nim/bin
nimCompile("dist/nimble/src/nimble.nim",
options = "-d:release --nilseqs:on " & args)
proc buildNimble(latest: bool, args: string) =
# if koch is used for a tar.xz, build the dist/nimble we shipped
# with the tarball:
var installDir = "dist/nimble"
if not latest and dirExists(installDir) and not dirExists("dist/nimble/.git"):
discard "don't do the git dance"
else:
if not dirExists("dist/nimble/.git"):
if dirExists(installDir):
var id = 0
while dirExists("dist/nimble" & $id):
inc id
installDir = "dist/nimble" & $id
# consider using/adapting cloneDependency
exec("git clone -q https://github.com/nim-lang/nimble.git " & installDir)
withDir(installDir):
if latest:
exec("git checkout -f master")
exec("git pull")
else:
exec("git fetch")
exec("git checkout " & NimbleStableCommit)
nimCompile(installDir / "src/nimble.nim",
options = "--noNimblePath --nilseqs:on -d:release " & args)
proc bundleNimsuggest(args: string) =
nimCompileFold("Compile nimsuggest", "nimsuggest/nimsuggest.nim",
options = "-d:release -d:danger " & args)
proc buildVccTool(args: string) =
nimCompileFold("Compile Vcc", "tools/vccexe/vccexe.nim ", options = args)
proc bundleNimpretty(args: string) =
nimCompileFold("Compile nimpretty", "nimpretty/nimpretty.nim",
options = "-d:release " & args)
proc bundleWinTools(args: string) =
nimCompile("tools/finish.nim", outputDir = "", options = args)
buildVccTool(args)
nimCompile("tools/nimgrab.nim", options = "-d:ssl " & args)
nimCompile("tools/nimgrep.nim", options = args)
bundleC2nim(args)
nimCompile("testament/testament.nim", options = args)
when false:
# not yet a tool worth including
nimCompile(r"tools\downloader.nim",
options = r"--cc:vcc --app:gui -d:ssl --noNimblePath --path:..\ui " & args)
proc zip(latest: bool; args: string) =
bundleNimbleExe(latest, args)
bundleNimsuggest(args)
bundleNimpretty(args)
bundleWinTools(args)
nimexec("cc -r $2 --var:version=$1 --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" %
[VersionAsString, compileNimInst])
exec("$# --var:version=$# --var:mingw=none --main:compiler/nim.nim zip compiler/installer.ini" %
["tools/niminst/niminst".exe, VersionAsString])
proc ensureCleanGit() =
let (outp, status) = osproc.execCmdEx("git diff")
if outp.len != 0:
quit "Not a clean git repository; 'git diff' not empty!"
if status != 0:
quit "Not a clean git repository; 'git diff' returned non-zero!"
proc xz(latest: bool; args: string) =
ensureCleanGit()
nimexec("cc -r $2 --var:version=$1 --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" %
[VersionAsString, compileNimInst])
exec("$# --var:version=$# --var:mingw=none --main:compiler/nim.nim xz compiler/installer.ini" %
["tools" / "niminst" / "niminst".exe, VersionAsString])
proc buildTool(toolname, args: string) =
nimexec("cc $# $#" % [args, toolname])
copyFile(dest="bin" / splitFile(toolname).name.exe, source=toolname.exe)
proc buildTools(args: string = "") =
bundleNimsuggest(args)
nimCompileFold("Compile nimgrep", "tools/nimgrep.nim",
options = "-d:release " & args)
when defined(windows): buildVccTool(args)
bundleNimpretty(args)
nimCompileFold("Compile nimfind", "tools/nimfind.nim",
options = "-d:release " & args)
nimCompileFold("Compile testament", "testament/testament.nim",
options = "-d:release " & args)
proc nsis(latest: bool; args: string) =
bundleNimbleExe(latest, args)
bundleNimsuggest(args)
bundleWinTools(args)
# make sure we have generated the niminst executables:
buildTool("tools/niminst/niminst", args)
#buildTool("tools/nimgrep", args)
# produce 'nim_debug.exe':
#exec "nim c compiler" / "nim.nim"
#copyExe("compiler/nim".exe, "bin/nim_debug".exe)
exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw$#" &
" nsis compiler/installer.ini") % [VersionAsString, $(sizeof(pointer)*8)])
proc geninstall(args="") =
nimexec("cc -r $# --var:version=$# --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini $#" %
[compileNimInst, VersionAsString, args])
proc install(args: string) =
geninstall()
exec("sh ./install.sh $#" % args)
when false:
proc web(args: string) =
nimexec("js tools/dochack/dochack.nim")
nimexec("cc -r tools/nimweb.nim $# web/website.ini --putenv:nimversion=$#" %
[args, VersionAsString])
proc website(args: string) =
nimexec("cc -r tools/nimweb.nim $# --website web/website.ini --putenv:nimversion=$#" %
[args, VersionAsString])
proc pdf(args="") =
exec("$# cc -r tools/nimweb.nim $# --pdf web/website.ini --putenv:nimversion=$#" %
[findNim().quoteShell(), args, VersionAsString], additionalPATH=findNim().splitFile.dir)
# -------------- boot ---------------------------------------------------------
proc findStartNim: string =
# we try several things before giving up:
# * nimExe
# * bin/nim
# * $PATH/nim
# If these fail, we try to build nim with the "build.(sh|bat)" script.
let (nim, ok) = findNimImpl()
if ok: return nim
when defined(Posix):
const buildScript = "build.sh"
if existsFile(buildScript):
if tryExec("./" & buildScript): return "bin" / nim
else:
const buildScript = "build.bat"
if existsFile(buildScript):
if tryExec(buildScript): return "bin" / nim
echo("Found no nim compiler and every attempt to build one failed!")
quit("FAILURE")
proc thVersion(i: int): string =
result = ("compiler" / "nim" & $i).exe
template doUseCpp(): bool = getEnv("NIM_COMPILE_TO_CPP", "false") == "true"
proc boot(args: string) =
var output = "compiler" / "nim".exe
var finalDest = "bin" / "nim".exe
# default to use the 'c' command:
let useCpp = doUseCpp()
let smartNimcache = (if "release" in args or "danger" in args: "nimcache/r_" else: "nimcache/d_") &
hostOS & "_" & hostCPU
let nimStart = findStartNim().quoteShell()
for i in 0..2:
# Nim versions < (1, 1) expect Nim's exception type to have a 'raiseId' field for
# C++ interop. Later Nim versions do this differently and removed the 'raiseId' field.
# Thus we always bootstrap the first iteration with "c" and not with "cpp" as
# a workaround.
let defaultCommand = if useCpp and i > 0: "cpp" else: "c"
let bootOptions = if args.len == 0 or args.startsWith("-"): defaultCommand else: ""
echo "iteration: ", i+1
var extraOption = ""
var nimi = i.thVersion
if i == 0:
nimi = nimStart
extraOption.add " --skipUserCfg --skipParentCfg"
# The configs are skipped for bootstrap
# (1st iteration) to prevent newer flags from breaking bootstrap phase.
let ret = execCmdEx(nimStart & " --version")
doAssert ret.exitCode == 0
let version = ret.output.splitLines[0]
# remove these when csources get updated
template addLib() =
extraOption.add " --lib:lib" # see https://github.com/nim-lang/Nim/pull/14291
if version.startsWith "Nim Compiler Version 0.19.0":
extraOption.add " -d:nimBoostrapCsources0_19_0"
addLib()
elif version.startsWith "Nim Compiler Version 0.20.0": addLib()
# in order to use less memory, we split the build into two steps:
# --compileOnly produces a $project.json file and does not run GCC/Clang.
# jsonbuild then uses the $project.json file to build the Nim binary.
exec "$# $# $# --nimcache:$# $# --compileOnly compiler" / "nim.nim" %
[nimi, bootOptions, extraOption, smartNimcache, args]
exec "$# jsonscript --nimcache:$# $# compiler" / "nim.nim" %
[nimi, smartNimcache, args]
if sameFileContent(output, i.thVersion):
copyExe(output, finalDest)
echo "executables are equal: SUCCESS!"
return
copyExe(output, (i+1).thVersion)
copyExe(output, finalDest)
when not defined(windows): echo "[Warning] executables are still not equal"
# -------------- clean --------------------------------------------------------
const
cleanExt = [
".ppu", ".o", ".obj", ".dcu", ".~pas", ".~inc", ".~dsk", ".~dpr",
".map", ".tds", ".err", ".bak", ".pyc", ".exe", ".rod", ".pdb", ".idb",
".idx", ".ilk"
]
ignore = [
".bzrignore", "nim", "nim.exe", "koch", "koch.exe", ".gitignore"
]
proc cleanAux(dir: string) =
for kind, path in walkDir(dir):
case kind
of pcFile:
var (_, name, ext) = splitFile(path)
if ext == "" or cleanExt.contains(ext):
if not ignore.contains(name):
echo "removing: ", path
removeFile(path)
of pcDir:
case splitPath(path).tail
of "nimcache":
echo "removing dir: ", path
removeDir(path)
of "dist", ".git", "icons": discard
else: cleanAux(path)
else: discard
proc removePattern(pattern: string) =
for f in walkFiles(pattern):
echo "removing: ", f
removeFile(f)
proc clean(args: string) =
removePattern("web/*.html")
removePattern("doc/*.html")
cleanAux(getCurrentDir())
for kind, path in walkDir(getCurrentDir() / "build"):
if kind == pcDir:
echo "removing dir: ", path
removeDir(path)
# -------------- builds a release ---------------------------------------------
proc winReleaseArch(arch: string) =
doAssert arch in ["32", "64"]
let cpu = if arch == "32": "i386" else: "amd64"
template withMingw(path, body) =
let prevPath = getEnv("PATH")
putEnv("PATH", (if path.len > 0: path & PathSep else: "") & prevPath)
try:
body
finally:
putEnv("PATH", prevPath)
withMingw r"..\mingw" & arch & r"\bin":
# Rebuilding koch is necessary because it uses its pointer size to
# determine which mingw link to put in the NSIS installer.
inFold "winrelease koch":
nimexec "c --cpu:$# koch" % cpu
kochExecFold("winrelease boot", "boot -d:release --cpu:$#" % cpu)
kochExecFold("winrelease zip", "zip -d:release")
overwriteFile r"build\nim-$#.zip" % VersionAsString,
r"web\upload\download\nim-$#_x$#.zip" % [VersionAsString, arch]
proc winRelease*() =
# Now used from "tools/winrelease" and not directly supported by koch
# anymore!
# Build -docs file:
when true:
inFold "winrelease buildDocs":
buildDocs(gaCode)
withDir "web/upload/" & VersionAsString:
inFold "winrelease zipdocs":
exec "7z a -tzip docs-$#.zip *.html" % VersionAsString
overwriteFile "web/upload/$1/docs-$1.zip" % VersionAsString,
"web/upload/download/docs-$1.zip" % VersionAsString
when true:
inFold "winrelease csource":
csource("-d:release")
when sizeof(pointer) == 4:
winReleaseArch "32"
when sizeof(pointer) == 8:
winReleaseArch "64"
# -------------- tests --------------------------------------------------------
template `|`(a, b): string = (if a.len > 0: a else: b)
proc tests(args: string) =
nimexec "cc --opt:speed testament/testament"
let tester = quoteShell(getCurrentDir() / "testament/testament".exe)
let success = tryExec tester & " " & (args|"all")
if not success:
quit("tests failed", QuitFailure)
proc temp(args: string) =
proc splitArgs(a: string): (string, string) =
# every --options before the command (indicated by starting
# with not a dash) is part of the bootArgs, the rest is part
# of the programArgs:
let args = os.parseCmdLine a
result = ("", "")
var i = 0
while i < args.len and args[i][0] == '-':
result[0].add " " & quoteShell(args[i])
inc i
while i < args.len:
result[1].add " " & quoteShell(args[i])
inc i
let d = getAppDir()
var output = d / "compiler" / "nim".exe
var finalDest = d / "bin" / "nim_temp".exe
# 125 is the magic number to tell git bisect to skip the current commit.
var (bootArgs, programArgs) = splitArgs(args)
if "doc" notin programArgs and
"threads" notin programArgs and
"js" notin programArgs:
bootArgs.add " -d:leanCompiler"
let nimexec = findNim().quoteShell()
exec(nimexec & " c -d:debug --debugger:native -d:nimBetterRun " & bootArgs & " " & (d / "compiler" / "nim"), 125)
copyExe(output, finalDest)
setCurrentDir(origDir)
if programArgs.len > 0: exec(finalDest & " " & programArgs)
proc xtemp(cmd: string) =
let d = getAppDir()
copyExe(d / "bin" / "nim".exe, d / "bin" / "nim_backup".exe)
try:
withDir(d):
temp""
copyExe(d / "bin" / "nim_temp".exe, d / "bin" / "nim".exe)
exec(cmd)
finally:
copyExe(d / "bin" / "nim_backup".exe, d / "bin" / "nim".exe)
proc buildDrNim(args: string) =
if not dirExists("dist/nimz3"):
exec("git clone https://github.com/zevv/nimz3.git dist/nimz3")
when defined(windows):
if not dirExists("dist/dlls"):
exec("git clone -q https://github.com/nim-lang/dlls.git dist/dlls")
copyExe("dist/dlls/libz3.dll", "bin/libz3.dll")
execFold("build drnim", "nim c -o:$1 $2 drnim/drnim" % ["bin/drnim".exe, args])
else:
if not dirExists("dist/z3"):
exec("git clone -q https://github.com/Z3Prover/z3.git dist/z3")
withDir("dist/z3"):
exec("git fetch")
exec("git checkout " & Z3StableCommit)
createDir("build")
withDir("build"):
exec("""cmake -DZ3_BUILD_LIBZ3_SHARED=FALSE -G "Unix Makefiles" ../""")
exec("make -j4")
execFold("build drnim", "nim cpp --dynlibOverride=libz3 -o:$1 $2 drnim/drnim" % ["bin/drnim".exe, args])
# always run the tests for now:
exec("testament/testament".exe & " --nim:" & "drnim".exe & " pat drnim/tests")
proc hostInfo(): string =
"hostOS: $1, hostCPU: $2, int: $3, float: $4, cpuEndian: $5, cwd: $6" %
[hostOS, hostCPU, $int.sizeof, $float.sizeof, $cpuEndian, getCurrentDir()]
proc installDeps(dep: string, commit = "") =
# the hashes/urls are version controlled here, so can be changed seamlessly
# and tied to a nim release (mimicking git submodules)
var commit = commit
case dep
of "tinyc":
if commit.len == 0: commit = "916cc2f94818a8a382dd8d4b8420978816c1dfb3"
cloneDependency(distDir, "https://github.com/timotheecour/nim-tinyc-archive", commit)
else: doAssert false, "unsupported: " & dep
# xxx: also add linenoise, niminst etc, refs https://github.com/nim-lang/RFCs/issues/206
proc runCI(cmd: string) =
doAssert cmd.len == 0, cmd # avoid silently ignoring
echo "runCI: ", cmd
echo hostInfo()
# boot without -d:nimHasLibFFI to make sure this still works
kochExecFold("Boot in release mode", "boot -d:release")
## build nimble early on to enable remainder to depend on it if needed
kochExecFold("Build Nimble", "nimble")
if getEnv("NIM_TEST_PACKAGES", "0") == "1":
execFold("Test selected Nimble packages (1)", "nim c -r testament/testament cat nimble-packages-1")
elif getEnv("NIM_TEST_PACKAGES", "0") == "2":
execFold("Test selected Nimble packages (2)", "nim c -r testament/testament cat nimble-packages-2")
else:
buildTools()
## run tests
execFold("Test nimscript", "nim e tests/test_nimscript.nims")
when defined(windows):
# note: will be over-written below
execFold("Compile tester", "nim c -d:nimCoroutines --os:genode -d:posix --compileOnly testament/testament")
# main bottleneck here
execFold("Run tester", "nim c -r -d:nimCoroutines testament/testament --pedantic all -d:nimCoroutines")
block CT_FFI:
when defined(posix): # windows can be handled in future PR's
execFold("nimble install -y libffi", "nimble install -y libffi")
const nimFFI = "./bin/nim.ctffi"
# no need to bootstrap with koch boot (would be slower)
let backend = if doUseCpp(): "cpp" else: "c"
execFold("build with -d:nimHasLibFFI", "nim $1 -d:release -d:nimHasLibFFI -o:$2 compiler/nim.nim" % [backend, nimFFI])
execFold("test with -d:nimHasLibFFI", "$1 $2 -r testament/testament --nim:$1 r tests/misc/trunner.nim -d:nimTrunnerFfi" % [nimFFI, backend])
execFold("Run nimdoc tests", "nim c -r nimdoc/tester")
execFold("Run nimpretty tests", "nim c -r nimpretty/tester.nim")
when defined(posix):
execFold("Run nimsuggest tests", "nim c -r nimsuggest/tester")
proc pushCsources() =
if not dirExists("../csources/.git"):
quit "[Error] no csources git repository found"
csource("-d:release")
let cwd = getCurrentDir()
try:
copyDir("build/c_code", "../csources/c_code")
copyFile("build/build.sh", "../csources/build.sh")
copyFile("build/build.bat", "../csources/build.bat")
copyFile("build/build64.bat", "../csources/build64.bat")
copyFile("build/makefile", "../csources/makefile")
setCurrentDir("../csources")
for kind, path in walkDir("c_code"):
if kind == pcDir:
exec("git add " & path / "*.c")
exec("git commit -am \"updated csources to version " & NimVersion & "\"")
exec("git push origin master")
exec("git tag -am \"Version $1\" v$1" % NimVersion)
exec("git push origin v$1" % NimVersion)
finally:
setCurrentDir(cwd)
proc testUnixInstall(cmdLineRest: string) =
csource("-d:release " & cmdLineRest)
xz(false, cmdLineRest)
let oldCurrentDir = getCurrentDir()
try:
let destDir = getTempDir()
copyFile("build/nim-$1.tar.xz" % VersionAsString,
destDir / "nim-$1.tar.xz" % VersionAsString)
setCurrentDir(destDir)
execCleanPath("tar -xJf nim-$1.tar.xz" % VersionAsString)
setCurrentDir("nim-$1" % VersionAsString)
execCleanPath("sh build.sh")
# first test: try if './bin/nim --version' outputs something sane:
let output = execProcess("./bin/nim --version").splitLines
if output.len > 0 and output[0].contains(VersionAsString):
echo "Version check: success"
execCleanPath("./bin/nim c koch.nim")
execCleanPath("./koch boot -d:release", destDir / "bin")
# check the docs build:
execCleanPath("./koch docs", destDir / "bin")
# check nimble builds:
execCleanPath("./koch tools")
# check the tests work:
putEnv("NIM_EXE_NOT_IN_PATH", "NOT_IN_PATH")
execCleanPath("./koch tests --nim:./bin/nim cat megatest", destDir / "bin")
else:
echo "Version check: failure"
finally:
setCurrentDir oldCurrentDir
proc valgrind(cmd: string) =
# somewhat hacky: '=' sign means "pass to valgrind" else "pass to Nim"
let args = parseCmdLine(cmd)
var nimcmd = ""
var valcmd = ""
for i, a in args:
if i == args.len-1:
# last element is the filename:
valcmd.add ' '
valcmd.add changeFileExt(a, ExeExt)
nimcmd.add ' '
nimcmd.add a
elif '=' in a:
valcmd.add ' '
valcmd.add a
else:
nimcmd.add ' '
nimcmd.add a
exec("nim c" & nimcmd)
let supp = getAppDir() / "tools" / "nimgrind.supp"
exec("valgrind --suppressions=" & supp & valcmd)
proc showHelp() =
quit(HelpText % [VersionAsString & spaces(44-len(VersionAsString)),
CompileDate, CompileTime], QuitSuccess)
when isMainModule:
var op = initOptParser()
var latest = false
while true:
op.next()
case op.kind
of cmdLongOption, cmdShortOption:
case normalize(op.key)
of "latest": latest = true
of "stable": latest = false
of "nim": nimExe = op.val.absolutePath # absolute so still works with changeDir
of "docslocal":
# undocumented for now, allows to rebuild local docs in < 40s as follows:
# `./koch --nim:$nimb --docslocal:htmldocs2 --doccmd:skip --warnings:off --hints:off`
# whereas `./koch docs` takes 190s; useful for development.
doAssert op.val.len > 0
buildDocsDir(op.cmdLineRest, op.val)
break
else: showHelp()
of cmdArgument:
case normalize(op.key)
of "boot": boot(op.cmdLineRest)
of "clean": clean(op.cmdLineRest)
of "doc", "docs": buildDocs(op.cmdLineRest)
of "doc0", "docs0":
# undocumented command for Araq-the-merciful:
buildDocs(op.cmdLineRest & gaCode)
of "pdf": buildPdfDoc(op.cmdLineRest, "doc/pdf")
of "csource", "csources": csource(op.cmdLineRest)
of "zip": zip(latest, op.cmdLineRest)
of "xz": xz(latest, op.cmdLineRest)
of "nsis": nsis(latest, op.cmdLineRest)
of "geninstall": geninstall(op.cmdLineRest)
of "distrohelper": geninstall()
of "install": install(op.cmdLineRest)
of "testinstall": testUnixInstall(op.cmdLineRest)
of "installdeps": installDeps(op.cmdLineRest)
of "runci": runCI(op.cmdLineRest)
of "test", "tests": tests(op.cmdLineRest)
of "temp": temp(op.cmdLineRest)
of "xtemp": xtemp(op.cmdLineRest)
of "wintools": bundleWinTools(op.cmdLineRest)
of "nimble": buildNimble(latest, op.cmdLineRest)
of "nimsuggest": bundleNimsuggest(op.cmdLineRest)
of "toolsnonimble":
buildTools(op.cmdLineRest)
of "tools":
buildTools(op.cmdLineRest)
buildNimble(latest, op.cmdLineRest)
of "pushcsource", "pushcsources": pushCsources()
of "valgrind": valgrind(op.cmdLineRest)
of "c2nim": bundleC2nim(op.cmdLineRest)
of "drnim": buildDrNim(op.cmdLineRest)
else: showHelp()
break
of cmdEnd: break