From 2e0f9c8bf77a4baad539bfa162866f324ee94225 Mon Sep 17 00:00:00 2001 From: Amrykid Date: Sat, 24 Dec 2011 12:14:17 -0600 Subject: [PATCH 1/6] - Added extractFile and extractAll to zipfiles.nim -- Need to wait until libzip_all.c is updated to support Windows. - Started working on "koch update". -- Waiting on above to finish work. --- koch.nim | 20 ++++++++++++++++++++ lib/impure/zipfiles.nim | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/koch.nim b/koch.nim index d3caa27dfd..2e67cd3d46 100755 --- a/koch.nim +++ b/koch.nim @@ -34,6 +34,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) @@ -78,6 +79,24 @@ proc web(args: string) = exec("nimrod cc -r tools/nimweb.nim web/nimrod --putenv:nimrodversion=$#" % NimrodVersion) +proc update(args: string) = + if ExistFile("./.git"): + # use git to download latest source + exec("git pull") + else: + # use dom96's httpclient to download zip + import httpclient + import zipfiles + downloadFile("https://github.com/Araq/Nimrod/zipball/master","./update.zip") + + var zip :TZipArchive + discard open(zip,fmRead) # will add error checking later + extractAll(zip,"./") + + exec("./koch boot -d:release") + + + # -------------- boot --------------------------------------------------------- const @@ -204,6 +223,7 @@ of cmdArgument: of "inno": inno(op.cmdLineRest) of "install": install(op.cmdLineRest) of "test", "tests": tests(op.cmdLineRest) + of "update", "up": update(op.cmdLineRest) else: showHelp() of cmdEnd: showHelp() diff --git a/lib/impure/zipfiles.nim b/lib/impure/zipfiles.nim index bdefc2c932..bf26f93bfc 100755 --- a/lib/impure/zipfiles.nim +++ b/lib/impure/zipfiles.nim @@ -142,3 +142,25 @@ 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) = + var strm = getStream(z, srcFile) + while true: + if not strm.atEnd: + dest.write(strm.readStr(1)) + else: break + dest.flush() + strm.close() + dest.close() + +proc extractFile*(z: var TZipArchive, srcFile: string, dest: string) = + var file = newFileStream(dest, fmReadWrite) + extractFile(z, srcFile, file) + +proc extractAll*(z: var TZipArchive, dest: string) = + for file in walkFiles(z): + extractFile(z, file, dest & "/" & extractFilename(file)) + + + \ No newline at end of file From f0ccc2e779bb6e5db15b7a19efe90d99b6518b3e Mon Sep 17 00:00:00 2001 From: Amrykid Date: Sat, 24 Dec 2011 16:45:28 -0600 Subject: [PATCH 2/6] - Koch update is nearly finished. -- Checks if libzip is available as a fallback. -- Echos what its doing. -- Actually compiles now. --- koch.nim | 57 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/koch.nim b/koch.nim index 2e67cd3d46..1af3a4d86b 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 +when defined(haveZipLib): + import zipfiles const HelpText = """ @@ -80,20 +82,49 @@ proc web(args: string) = NimrodVersion) proc update(args: string) = - if ExistFile("./.git"): + var thisDir = getAppDir() + echo("Checking for git repo...") + if existsDir(thisDir & "/.git"): + echo("Git repo found!") # use git to download latest source - exec("git pull") - else: - # use dom96's httpclient to download zip - import httpclient - import zipfiles - downloadFile("https://github.com/Araq/Nimrod/zipball/master","./update.zip") + var output = execProcess("git diff origin/master master") + if output == "\r\n": + # 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 - var zip :TZipArchive - discard open(zip,fmRead) # will add error checking later - extractAll(zip,"./") - + else: + + 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...") exec("./koch boot -d:release") + echo("Update complete!") @@ -223,7 +254,7 @@ of cmdArgument: of "inno": inno(op.cmdLineRest) of "install": install(op.cmdLineRest) of "test", "tests": tests(op.cmdLineRest) - of "update", "up": update(op.cmdLineRest) + of "update": update(op.cmdLineRest) else: showHelp() of cmdEnd: showHelp() From d0d0c79540c4c887935b39c3ced5fdf01f2900d1 Mon Sep 17 00:00:00 2001 From: Amrykid Date: Sun, 25 Dec 2011 14:37:10 -0600 Subject: [PATCH 3/6] Final bits added. Needs testing. --- koch.nim | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/koch.nim b/koch.nim index 1af3a4d86b..98c9b72020 100755 --- a/koch.nim +++ b/koch.nim @@ -11,7 +11,7 @@ when defined(gcc) and defined(windows): {.link: "icons/koch.res".} import - os, strutils, parseopt, osproc, httpclient + os, strutils, parseopt, osproc, httpclient, streams when defined(haveZipLib): import zipfiles @@ -45,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) = @@ -82,26 +84,39 @@ proc web(args: string) = 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...") - if existsDir(thisDir & "/.git"): + if existsDir(thisDir & "/.git") and git != "": echo("Git repo found!") # use git to download latest source - var output = execProcess("git diff origin/master master") - if output == "\r\n": - # 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.") + 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: - 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 + 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: @@ -123,7 +138,7 @@ proc update(args: string) = return echo("Starting update...") - exec("./koch boot -d:release") + boot(args) echo("Update complete!") From 3321523ee4d12ee3db89a69f5ea381c2ad3440ed Mon Sep 17 00:00:00 2001 From: Amrykid Date: Tue, 27 Dec 2011 08:59:31 -0600 Subject: [PATCH 4/6] Last bits, etc. --- koch.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/koch.nim b/koch.nim index 98c9b72020..98067404b2 100755 --- a/koch.nim +++ b/koch.nim @@ -90,10 +90,11 @@ proc update(args: string) = var thisDir = getAppDir() var git = findExe("git") - echo("Checking for git repo...") + 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() @@ -119,7 +120,7 @@ proc update(args: string) = 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 @@ -143,6 +144,7 @@ proc update(args: string) = + # -------------- boot --------------------------------------------------------- const From e978272d3c8da588292af8b7a95eb8ea03befbf4 Mon Sep 17 00:00:00 2001 From: Amrykid Date: Tue, 27 Dec 2011 09:06:06 -0600 Subject: [PATCH 5/6] Allowed waitForExit to have a specified timeout. (osproc.nim) --- lib/pure/osproc.nim | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index dc107b3825..99c128e4d5 100755 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -382,8 +382,11 @@ 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 = + if timeout is -1: + discard WaitForSingleObject(p.FProcessHandle, Infinite) + else: discard WaitForSingleObject(p.FProcessHandle, timeout) + var res: int32 discard GetExitCodeProcess(p.FProcessHandle, res) result = res From f0f904ac70abec7bbab2c00075c9c4148a9b5132 Mon Sep 17 00:00:00 2001 From: Amrykid Date: Tue, 27 Dec 2011 09:34:45 -0600 Subject: [PATCH 6/6] Documentation comments + slight code modifications to zipfiles.nim. Changes made to osproc.nim so it will compile. --- lib/impure/zipfiles.nim | 5 ++++- lib/pure/osproc.nim | 8 +++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/impure/zipfiles.nim b/lib/impure/zipfiles.nim index bf26f93bfc..2f0be6b99f 100755 --- a/lib/impure/zipfiles.nim +++ b/lib/impure/zipfiles.nim @@ -145,6 +145,7 @@ iterator walkFiles*(z: var TZipArchive): string = 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: @@ -152,13 +153,15 @@ proc extractFile*(z: var TZipArchive, srcFile: string, dest: PStream) = else: break dest.flush() strm.close() - dest.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)) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 99c128e4d5..510dff232c 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 @@ -383,9 +383,7 @@ when defined(Windows) and not defined(useNimRtl): discard TerminateProcess(p.FProcessHandle, 0) proc waitForExit(p: PProcess, timeout: int = -1): int = - if timeout is -1: - discard WaitForSingleObject(p.FProcessHandle, Infinite) - else: discard WaitForSingleObject(p.FProcessHandle, timeout) + discard WaitForSingleObject(p.FProcessHandle, timeout) var res: int32 discard GetExitCodeProcess(p.FProcessHandle, res) @@ -643,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