summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-12-27 19:47:50 +0100
committerAraq <rumpf_a@web.de>2011-12-27 19:47:50 +0100
commita26433b6ece813d8e14efe4f65b4be3a893c2116 (patch)
tree45b0a0866a20f4d74530dc8164b051533dea0341
parent8e7917c3f7e259c33917e2c1e3774598e3f80869 (diff)
parent0ad42bd0586ec6b7c8264a401748f05030e428ef (diff)
downloadNim-a26433b6ece813d8e14efe4f65b4be3a893c2116.tar.gz
Merge branch 'master' of github.com:Araq/Nimrod
-rwxr-xr-xkoch.nim70
-rwxr-xr-xlib/impure/zipfiles.nim25
-rwxr-xr-xlib/pure/osproc.nim9
3 files changed, 99 insertions, 5 deletions
diff --git a/koch.nim b/koch.nim
index d3caa27df..98067404b 100755
--- a/koch.nim
+++ b/koch.nim
@@ -11,7 +11,9 @@ when defined(gcc) and defined(windows):
   {.link: "icons/koch.res".}
 
 import
-  os, strutils, parseopt
+  os, strutils, parseopt, osproc, httpclient, streams
+when defined(haveZipLib):
+  import zipfiles
 
 const
   HelpText = """
@@ -34,6 +36,7 @@ Possible Commands:
   zip                      builds the installation ZIP package
   inno [options]           builds the Inno Setup installer (for Windows)
   tests                    run the testsuite
+  update                   updates nimrod to the latest version from the repo.	
 Boot options:
   -d:release               produce a release version of the compiler
   -d:tinyc                 include the Tiny C backend (not supported on Windows)
@@ -42,6 +45,8 @@ Boot options:
   -d:nativeStacktrace      use native stack traces (only for Mac OS X or Linux)
 """
 
+proc boot(args: string) # Forward declaration
+
 proc exe(f: string): string = return addFileExt(f, ExeExt)
 
 proc exec(cmd: string) =
@@ -78,6 +83,68 @@ proc web(args: string) =
   exec("nimrod cc -r tools/nimweb.nim web/nimrod --putenv:nimrodversion=$#" %
        NimrodVersion)
 
+proc update(args: string) =
+  when defined(windows):
+    echo("Windows Users: Make sure to be running this in Bash. If you aren't, press CTRL+C now.")
+
+
+  var thisDir = getAppDir()
+  var git = findExe("git")
+  echo("Checking for git repo and git executable...")
+  if existsDir(thisDir & "/.git") and git != "":
+    echo("Git repo found!")
+    # use git to download latest source
+    echo("Checking for updates...")
+    discard startCmd(git & " fetch origin master")
+    var procs = startCmd(git & " diff origin/master master")
+    var errcode = procs.waitForExit()
+    var output = readLine(procs.outputStream)
+    echo(output)
+    if errcode == 0:
+      if output == "":
+        # No changes
+        echo("No update. Exiting..")
+        return
+      else:
+        echo("Fetching updates from repo...")
+        var pullout = execCmdEx(git & " pull origin master")
+        if pullout[1] != 0:
+          echo("An error has occured.")
+          return
+        else:
+          if pullout[0] == "Already up-to-date.\r\n":
+             echo("No new changes fetched from the repo. Local branch must be ahead of it. Exiting...")
+             return
+    else:
+        echo("An error has occured.")
+        return
+    
+  else:
+    echo("No repo or executable found!")
+    when defined(haveZipLib):
+      echo("Falling back.. Downloading source code from repo...")
+      # use dom96's httpclient to download zip
+      downloadFile("https://github.com/Araq/Nimrod/zipball/master",thisDir & "/update.zip")
+    
+      try:
+        echo("Extracting source code from archive...")
+        var zip :TZipArchive
+        discard open(zip,thisDir & "/update.zip", fmRead) # will add error checking later
+        extractAll(zip, thisDir & "/")
+      except:
+        echo("Error reading archive.")
+        return
+    else:
+      echo("No failback available. Exiting...")
+      return
+  
+  echo("Starting update...")
+  boot(args)
+  echo("Update complete!")
+
+
+
+
 # -------------- boot ---------------------------------------------------------
 
 const
@@ -204,6 +271,7 @@ of cmdArgument:
   of "inno": inno(op.cmdLineRest)
   of "install": install(op.cmdLineRest)
   of "test", "tests": tests(op.cmdLineRest)
+  of "update": update(op.cmdLineRest)
   else: showHelp()
 of cmdEnd: showHelp()
 
diff --git a/lib/impure/zipfiles.nim b/lib/impure/zipfiles.nim
index bdefc2c93..2f0be6b99 100755
--- a/lib/impure/zipfiles.nim
+++ b/lib/impure/zipfiles.nim
@@ -142,3 +142,28 @@ iterator walkFiles*(z: var TZipArchive): string =
   while i < num:
     yield $zip_get_name(z.w, i, 0'i32)
     inc(i)
+
+
+proc extractFile*(z: var TZipArchive, srcFile: string, dest: PStream) =
+  ## extracts a file from the zip archive 'z' to the destination stream.
+  var strm = getStream(z, srcFile)
+  while true:
+    if not strm.atEnd:
+        dest.write(strm.readStr(1))
+    else: break
+  dest.flush()
+  strm.close()
+
+proc extractFile*(z: var TZipArchive, srcFile: string, dest: string) =
+  ## extracts a file from the zip archive 'z' to the destination filename.
+  var file = newFileStream(dest, fmReadWrite)
+  extractFile(z, srcFile, file)
+  file.close()
+
+proc extractAll*(z: var TZipArchive, dest: string) =
+  ## extracts all files from archive 'z' to the destination directory.
+  for file in walkFiles(z):
+    extractFile(z, file, dest & "/" & extractFilename(file))
+
+   
+   
\ No newline at end of file
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index dc107b382..510dff232 100755
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -102,7 +102,7 @@ proc processID*(p: PProcess): int {.rtl, extern: "nosp$1".} =
   ## returns `p`'s process ID.
   return p.id
 
-proc waitForExit*(p: PProcess): int {.rtl, extern: "nosp$1".}
+proc waitForExit*(p: PProcess, timeout: int = -1): int {.rtl, extern: "nosp$1".}
   ## waits for the process to finish and returns `p`'s error code.
 
 proc peekExitCode*(p: PProcess): int
@@ -382,8 +382,9 @@ when defined(Windows) and not defined(useNimRtl):
     if running(p):
       discard TerminateProcess(p.FProcessHandle, 0)
 
-  proc waitForExit(p: PProcess): int =
-    discard WaitForSingleObject(p.FProcessHandle, Infinite)
+  proc waitForExit(p: PProcess, timeout: int = -1): int =
+    discard WaitForSingleObject(p.FProcessHandle, timeout)
+
     var res: int32
     discard GetExitCodeProcess(p.FProcessHandle, res)
     result = res
@@ -640,7 +641,7 @@ elif not defined(useNimRtl):
         if kill(-p.id, SIGKILL) != 0'i32: OSError()
     else: OSError()
 
-  proc waitForExit(p: PProcess): int =
+  proc waitForExit(p: PProcess, timeout: int = -1): int =
     #if waitPid(p.id, p.exitCode, 0) == int(p.id):
     # ``waitPid`` fails if the process is not running anymore. But then
     # ``running`` probably set ``p.exitCode`` for us. Since ``p.exitCode`` is