summary refs log tree commit diff stats
path: root/tools/niminst/niminst.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tools/niminst/niminst.nim')
-rw-r--r--tools/niminst/niminst.nim202
1 files changed, 95 insertions, 107 deletions
diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim
index e2cc8cf3a..40ee79814 100644
--- a/tools/niminst/niminst.nim
+++ b/tools/niminst/niminst.nim
@@ -7,15 +7,16 @@
 #    distribution, for details about the copyright.
 #
 
-const
-  haveZipLib = false # zip not in stdlib anymore
+import
+  os, strutils, parseopt, parsecfg, strtabs, streams, debcreation
 
-when haveZipLib:
-  import zipfiles
+import ../../dist/checksums/src/checksums/sha1
 
-import
-  os, osproc, strutils, parseopt, parsecfg, strtabs, streams, debcreation,
-  std / sha1
+when defined(nimPreviewSlimSystem):
+  import std/syncio
+
+when not defined(nimHasEffectsOf):
+  {.pragma: effectsOf.}
 
 const
   maxOS = 20 # max number of OSes
@@ -36,7 +37,7 @@ type
     actionInno,   # action: create Inno Setup installer
     actionNsis,   # action: create NSIS installer
     actionScripts # action: create install and deinstall scripts
-    actionZip,    # action: create zip file
+    actionZip     # action: create zip file
     actionXz,     # action: create xz file
     actionDeb     # action: prepare deb package
 
@@ -75,7 +76,7 @@ const
     "$configdir", "$datadir", "$docdir", "$libdir"
   ]
 
-proc iniConfigData(c: var ConfigData) =
+func iniConfigData(c: var ConfigData) =
   c.actions = {}
   for i in low(FileCategory)..high(FileCategory): c.cat[i] = @[]
   c.binPaths = @[]
@@ -107,17 +108,17 @@ proc iniConfigData(c: var ConfigData) =
   c.debOpts.shortDesc = ""
   c.debOpts.licenses = @[]
 
-proc firstBinPath(c: ConfigData): string =
+func firstBinPath(c: ConfigData): string =
   if c.binPaths.len > 0: result = c.binPaths[0]
   else: result = ""
 
-proc `\`(a, b: string): string =
+func `\`(a, b: string): string =
   result = if a.len == 0: b else: a & '\\' & b
 
 template toUnix(s: string): string = s.replace('\\', '/')
 template toWin(s: string): string = s.replace('/', '\\')
 
-proc skipRoot(f: string): string =
+func skipRoot(f: string): string =
   # "abc/def/xyz" --> "def/xyz"
   var i = 0
   result = ""
@@ -126,13 +127,13 @@ proc skipRoot(f: string): string =
     inc i
   if result.len == 0: result = f
 
-include "inno.tmpl"
-include "nsis.tmpl"
-include "buildsh.tmpl"
-include "makefile.tmpl"
-include "buildbat.tmpl"
-include "install.tmpl"
-include "deinstall.tmpl"
+include "inno.nimf"
+include "nsis.nimf"
+include "buildsh.nimf"
+include "makefile.nimf"
+include "buildbat.nimf"
+include "install.nimf"
+include "deinstall.nimf"
 
 # ------------------------- configuration file -------------------------------
 
@@ -167,11 +168,11 @@ proc parseCmdLine(c: var ConfigData) =
     next(p)
     var kind = p.kind
     var key = p.key
-    var val = p.val.string
+    var val = p.val
     case kind
     of cmdArgument:
       if c.actions == {}:
-        for a in split(normalize(key.string), {';', ','}):
+        for a in split(normalize(key), {';', ','}):
           case a
           of "csource": incl(c.actions, actionCSource)
           of "scripts": incl(c.actions, actionScripts)
@@ -182,11 +183,11 @@ proc parseCmdLine(c: var ConfigData) =
           of "deb": incl(c.actions, actionDeb)
           else: quit(Usage)
       else:
-        c.infile = addFileExt(key.string, "ini")
-        c.nimArgs = cmdLineRest(p).string
+        c.infile = addFileExt(key, "ini")
+        c.nimArgs = cmdLineRest(p)
         break
-    of cmdLongoption, cmdShortOption:
-      case normalize(key.string)
+    of cmdLongOption, cmdShortOption:
+      case normalize(key)
       of "help", "h":
         stdout.write(Usage)
         quit(0)
@@ -204,7 +205,7 @@ proc parseCmdLine(c: var ConfigData) =
   if c.infile.len == 0: quit(Usage)
   if c.mainfile.len == 0: c.mainfile = changeFileExt(c.infile, "nim")
 
-proc eqT(a, b: string; t: proc (a: char): char{.nimcall.}): bool =
+proc eqT(a, b: string; t: proc (a: char): char {.nimcall.}): bool {.effectsOf: t.} =
   ## equality under a transformation ``t``. candidate for the stdlib?
   var i = 0
   var j = 0
@@ -221,11 +222,11 @@ proc eqT(a, b: string; t: proc (a: char): char{.nimcall.}): bool =
       inc j
   result = i >= a.len and j >= b.len
 
-proc tPath(c: char): char =
+func tPath(c: char): char =
   if c == '\\': '/'
   else: c
 
-proc ignoreFile(f, explicit: string, allowHtml: bool): bool =
+func ignoreFile(f, explicit: string, allowHtml: bool): bool =
   let (_, name, ext) = splitFile(f)
   let html = if not allowHtml: ".html" else: ""
   result = (ext in ["", ".exe", ".idx", ".o", ".obj", ".dylib"] or
@@ -251,12 +252,12 @@ proc walkDirRecursively(s: var seq[string], root, explicit: string,
 
 proc addFiles(s: var seq[string], patterns: seq[string]) =
   for p in items(patterns):
-    if existsDir(p):
+    if dirExists(p):
       walkDirRecursively(s, p, p, false)
     else:
       var i = 0
       for f in walkPattern(p):
-        if existsDir(f):
+        if dirExists(f):
           walkDirRecursively(s, f, p, false)
         elif not ignoreFile(f, p, false):
           add(s, unixToNativePath(f))
@@ -283,13 +284,13 @@ proc yesno(p: var CfgParser, v: string): bool =
     result = false
   else: quit(errorStr(p, "unknown value; use: yes|no"))
 
-proc incl(s: var seq[string], x: string): int =
+func incl(s: var seq[string], x: string): int =
   for i in 0 ..< s.len:
     if cmpIgnoreStyle(s[i], x) == 0: return i
   s.add(x)
   result = s.len-1
 
-proc platforms(c: var ConfigData, v: string) =
+func platforms(c: var ConfigData, v: string) =
   for line in splitLines(v):
     let p = line.find(": ")
     if p <= 1: continue
@@ -462,10 +463,10 @@ proc readCFiles(c: var ConfigData, osA, cpuA: int) =
   else:
     quit("Cannot open: " & f)
 
-proc buildDir(os, cpu: int): string =
-  return "c_code" / ($os & "_" & $cpu)
+func buildDir(os, cpu: int): string =
+  "c_code" / ($os & "_" & $cpu)
 
-proc getOutputDir(c: var ConfigData): string =
+func getOutputDir(c: var ConfigData): string =
   if c.outdir.len > 0: c.outdir else: "build"
 
 proc writeFile(filename, content, newline: string) =
@@ -483,7 +484,6 @@ proc deduplicateFiles(c: var ConfigData) =
   let build = getOutputDir(c)
   for osA in countup(1, c.oses.len):
     for cpuA in countup(1, c.cpus.len):
-      if c.cfiles[osA][cpuA].isNil: c.cfiles[osA][cpuA] = @[]
       if c.explicitPlatforms and not c.platforms[osA][cpuA]: continue
       for dup in mitems(c.cfiles[osA][cpuA]):
         let key = $secureHashFile(build / dup)
@@ -504,12 +504,32 @@ proc writeInstallScripts(c: var ConfigData) =
     writeFile(deinstallShFile, generateDeinstallScript(c), "\10")
     inclFilePermissions(deinstallShFile, {fpUserExec, fpGroupExec, fpOthersExec})
 
+template gatherFiles(fun, libpath, outDir) =
+  block:
+    template copySrc(src) =
+      let dst = outDir / extractFilename(src)
+      when false: echo (dst, dst)
+      fun(src, dst)
+
+    for f in walkFiles(libpath / "lib/*.h"): copySrc(f)
+    # commenting out for now, see discussion in https://github.com/nim-lang/Nim/pull/13413
+    # copySrc(libpath / "lib/wrappers/linenoise/linenoise.h")
+
+proc exe(f: string): string =
+  result = addFileExt(f, ExeExt)
+  when defined(windows):
+    result = result.replace('/','\\')
+
+proc findNim(): string =
+  let nim = "nim".exe
+  result = quoteShell("bin" / nim)
+  if not fileExists(result):
+    result = "nim"
+
 proc srcdist(c: var ConfigData) =
-  if not existsDir(getOutputDir(c) / "c_code"):
-    createDir(getOutputDir(c) / "c_code")
-  for x in walkFiles(c.libpath / "lib/*.h"):
-    when false: echo(getOutputDir(c) / "c_code" / extractFilename(x))
-    copyFile(dest=getOutputDir(c) / "c_code" / extractFilename(x), source=x)
+  let cCodeDir = getOutputDir(c) / "c_code"
+  if not dirExists(cCodeDir): createDir(cCodeDir)
+  gatherFiles(copyFile, c.libpath, cCodeDir)
   var winIndex = -1
   var intel32Index = -1
   var intel64Index = -1
@@ -522,12 +542,12 @@ proc srcdist(c: var ConfigData) =
       if cpuname.cmpIgnoreStyle("i386") == 0: intel32Index = cpuA
       elif cpuname.cmpIgnoreStyle("amd64") == 0: intel64Index = cpuA
       var dir = getOutputDir(c) / buildDir(osA, cpuA)
-      if existsDir(dir): removeDir(dir)
+      if dirExists(dir): removeDir(dir)
       createDir(dir)
-      var cmd = ("nim compile -f --symbolfiles:off --compileonly " &
+      var cmd = ("$# compile -f --incremental:off --compileonly " &
                  "--gen_mapping --cc:gcc --skipUserCfg" &
                  " --os:$# --cpu:$# $# $#") %
-                 [osname, cpuname, c.nimArgs, c.mainfile]
+                 [findNim(), osname, cpuname, c.nimArgs, c.mainfile]
       echo(cmd)
       if execShellCmd(cmd) != 0:
         quit("Error: call to nim compiler failed")
@@ -586,41 +606,6 @@ proc setupDist2(c: var ConfigData) =
     else:
       quit("External program failed")
 
-# ------------------ generate ZIP file ---------------------------------------
-when haveZipLib:
-  proc zipDist(c: var ConfigData) =
-    var proj = toLowerAscii(c.name) & "-" & c.version
-    var n = "$#.zip" % proj
-    if c.outdir.len == 0: n = "build" / n
-    else: n = c.outdir / n
-    var z: ZipArchive
-    if open(z, n, fmWrite):
-      addFile(z, proj / buildBatFile, "build" / buildBatFile)
-      addFile(z, proj / buildBatFile32, "build" / buildBatFile32)
-      addFile(z, proj / buildBatFile64, "build" / buildBatFile64)
-      addFile(z, proj / buildShFile, "build" / buildShFile)
-      addFile(z, proj / makeFile, "build" / makeFile)
-      addFile(z, proj / installShFile, installShFile)
-      addFile(z, proj / deinstallShFile, deinstallShFile)
-      for f in walkFiles(c.libpath / "lib/*.h"):
-        addFile(z, proj / "c_code" / extractFilename(f), f)
-      for osA in 1..c.oses.len:
-        for cpuA in 1..c.cpus.len:
-          var dir = buildDir(osA, cpuA)
-          for k, f in walkDir("build" / dir):
-            if k == pcFile: addFile(z, proj / dir / extractFilename(f), f)
-
-      for cat in items({fcConfig..fcOther, fcUnix, fcNimble}):
-        for f in items(c.cat[cat]): addFile(z, proj / f, f)
-
-      # Copy the .nimble file over
-      let nimbleFile = c.nimblePkgName & ".nimble"
-      processFile(z, proj / nimbleFile, nimbleFile)
-
-      close(z)
-    else:
-      quit("Cannot open for writing: " & n)
-
 proc xzDist(c: var ConfigData; windowsZip=false) =
   let proj = toLowerAscii(c.name) & "-" & c.version
   let tmpDir = if c.outdir.len == 0: "build" else: c.outdir
@@ -628,15 +613,15 @@ proc xzDist(c: var ConfigData; windowsZip=false) =
   proc processFile(destFile, src: string) =
     let dest = tmpDir / destFile
     when false: echo "Copying ", src, " to ", dest
-    if not existsFile(src):
+    if not fileExists(src):
       echo "[Warning] Source file doesn't exist: ", src
     let destDir = dest.splitFile.dir
     if not dirExists(destDir): createDir(destDir)
     copyFileWithPermissions(src, dest)
 
-  if not windowsZip and not existsFile("build" / buildBatFile):
+  if not windowsZip and not fileExists("build" / buildBatFile):
     quit("No C sources found in ./build/, please build by running " &
-         "./koch csource -d:release.")
+         "./koch csource -d:danger.")
 
   if not windowsZip:
     processFile(proj / buildBatFile, "build" / buildBatFile)
@@ -646,8 +631,8 @@ proc xzDist(c: var ConfigData; windowsZip=false) =
     processFile(proj / makeFile, "build" / makeFile)
     processFile(proj / installShFile, installShFile)
     processFile(proj / deinstallShFile, deinstallShFile)
-    for f in walkFiles(c.libpath / "lib/*.h"):
-      processFile(proj / "c_code" / extractFilename(f), f)
+    template processFileAux(src, dst) = processFile(dst, src)
+    gatherFiles(processFileAux, c.libpath, proj / "c_code")
     for osA in 1..c.oses.len:
       for cpuA in 1..c.cpus.len:
         var dir = buildDir(osA, cpuA)
@@ -683,7 +668,7 @@ RunProgram="tools\downloader.exe"
           if execShellCmd("7z a -sfx7zS2.sfx -t7z $1.exe $1" % proj) != 0:
             echo("External program failed (7z)")
       else:
-        if execShellCmd("gtar cf $1.tar $1 --exclude=.DS_Store" %
+        if execShellCmd("gtar cf $1.tar --exclude=.DS_Store $1" %
                         proj) != 0:
           # try old 'tar' without --exclude feature:
           if execShellCmd("tar cf $1.tar $1" % proj) != 0:
@@ -697,8 +682,8 @@ RunProgram="tools\downloader.exe"
 # -- prepare build files for .deb creation
 
 proc debDist(c: var ConfigData) =
-  if not existsFile(getOutputDir(c) / "build.sh"): quit("No build.sh found.")
-  if not existsFile(getOutputDir(c) / "install.sh"): quit("No install.sh found.")
+  if not fileExists(getOutputDir(c) / "build.sh"): quit("No build.sh found.")
+  if not fileExists(getOutputDir(c) / "install.sh"): quit("No install.sh found.")
 
   if c.debOpts.shortDesc == "": quit("shortDesc must be set in the .ini file.")
   if c.debOpts.licenses.len == 0:
@@ -721,8 +706,7 @@ proc debDist(c: var ConfigData) =
   copyNimDist(makeFile, makeFile)
   copyNimDist(installShFile, installShFile)
   createDir(workingDir / upstreamSource / "build")
-  for f in walkFiles(c.libpath / "lib/*.h"):
-    copyNimDist(f, "build" / extractFilename(f))
+  gatherFiles(copyNimDist, c.libpath, "build")
   for osA in 1..c.oses.len:
     for cpuA in 1..c.cpus.len:
       var dir = buildDir(osA, cpuA)
@@ -743,21 +727,25 @@ proc debDist(c: var ConfigData) =
 
 # ------------------- main ----------------------------------------------------
 
-var c: ConfigData
-iniConfigData(c)
-parseCmdLine(c)
-parseIniFile(c)
-if actionInno in c.actions:
-  setupDist(c)
-if actionNsis in c.actions:
-  setupDist2(c)
-if actionCSource in c.actions:
-  srcdist(c)
-if actionScripts in c.actions:
-  writeInstallScripts(c)
-if actionZip in c.actions:
-  xzDist(c, true)
-if actionXz in c.actions:
-  xzDist(c)
-if actionDeb in c.actions:
-  debDist(c)
+proc main() =
+  var c: ConfigData
+  iniConfigData(c)
+  parseCmdLine(c)
+  parseIniFile(c)
+  if actionInno in c.actions:
+    setupDist(c)
+  if actionNsis in c.actions:
+    setupDist2(c)
+  if actionCSource in c.actions:
+    srcdist(c)
+  if actionScripts in c.actions:
+    writeInstallScripts(c)
+  if actionZip in c.actions:
+    xzDist(c, true)
+  if actionXz in c.actions:
+    xzDist(c)
+  if actionDeb in c.actions:
+    debDist(c)
+
+when isMainModule:
+  main()