diff --git a/src/nimble.nim b/src/nimble.nim index 18ec04f..c309137 100644 --- a/src/nimble.nim +++ b/src/nimble.nim @@ -596,9 +596,9 @@ proc downloadPkg(pkg: Package, verRange: VersionRangeRef): string = proc install(packages: seq[PkgTuple], options: Options, doPrompt = true): tuple[paths: seq[string], pkg: PackageInfo] = - if packages == @[]: + if packages == @[]: result = installFromDir(getCurrentDir(), false, options, "") - else: + else: # If packages.json is not present ask the user if they want to download it. if not existsFile(options.getNimbleDir / "packages.json"): if doPrompt and diff --git a/src/nimblepkg/tools.nim b/src/nimblepkg/tools.nim index f642ebc..f0e7d3a 100644 --- a/src/nimblepkg/tools.nim +++ b/src/nimblepkg/tools.nim @@ -9,8 +9,13 @@ proc doCmd*(cmd: string) = let bin = cmd.split(' ')[0] if findExe(bin) == "": raise newException(NimbleError, "'" & bin & "' not in PATH.") + + # To keep output in sequence + stdout.flushFile() + stderr.flushFile() let exitCode = execCmd(cmd) + if exitCode != QuitSuccess: raise newException(NimbleError, "Execution failed with exit code " & $exitCode) diff --git a/tests/tester.nim b/tests/tester.nim index 7fedb0b..f95e76f 100644 --- a/tests/tester.nim +++ b/tests/tester.nim @@ -1,6 +1,6 @@ # Copyright (C) Dominik Picheta. All rights reserved. # BSD License. Look at license.txt for more info. -import osproc, unittest, strutils, os, sequtils, future +import osproc, streams, unittest, strutils, os, sequtils, future const path = "../src/nimble" @@ -15,6 +15,35 @@ template cd*(dir: string, body: stmt) = body setCurrentDir(lastDir) +proc execCmdEx2*(command: string, options: set[ProcessOption] = { + poUsePath}): tuple[ + output: TaintedString, + error: TaintedString, + exitCode: int] {.tags: [ExecIOEffect, ReadIOEffect], gcsafe.} = + ## A slightly altered version of osproc.execCmdEx + ## Runs the `command` and returns the standard output, error output, and + ## exit code. + var p = startProcess(command = command, options = options + {poEvalCommand}) + var outp = outputStream(p) + var errp = errorStream(p) + result = (TaintedString"", TaintedString"", -1) + var outLine = newStringOfCap(120).TaintedString + var errLine = newStringOfCap(120).TaintedString + while true: + var checkForExit = true + if outp.readLine(outLine): + result[0].string.add(outLine.string) + result[0].string.add("\n") + checkForExit = false + if errp.readLine(errLine): + result[1].string.add(errLine.string) + result[1].string.add("\n") + checkForExit = false + if checkForExit: + result[2] = peekExitCode(p) + if result[2] != -1: break + close(p) + proc processOutput(output: string): seq[string] = output.strip.splitLines().filter((x: string) => (x.len > 0)) @@ -24,11 +53,11 @@ test "can install packagebin2": QuitSuccess test "can reject same version dependencies": - let (outp, exitCode) = execCmdEx(path & + let (outp, errp, exitCode) = execCmdEx2(path & " install -y https://github.com/nimble-test/packagebin.git") - #echo outp - # TODO: outp is not in the correct order. - let ls = outp.strip.splitLines() + # We look at the error output here to avoid out-of-order problems caused by + # stderr output being generated and flushed without first flushing stdout + let ls = errp.strip.splitLines() check exitCode != QuitSuccess check ls[ls.len-1] == "Error: unhandled exception: Cannot satisfy the " & "dependency on PackageA 0.2.0 and PackageA 0.5.0 [NimbleError]" @@ -50,8 +79,9 @@ test "issue #27": test "can uninstall": block: - let (outp, exitCode) = execCmdEx(path & " uninstall -y issue27b") - let ls = outp.processOutput() + let (outp, errp, exitCode) = execCmdEx2(path & " uninstall -y issue27b") + # let ls = outp.processOutput() + let ls = errp.strip.splitLines() check exitCode != QuitSuccess check ls[ls.len-1] == " Cannot uninstall issue27b (0.1.0) because " & "issue27a (0.1.0) depends on it [NimbleError]" @@ -62,9 +92,9 @@ test "can uninstall": # Remove Package* check execCmdEx(path & " uninstall -y PackageA@0.5").exitCode == QuitSuccess - let (outp, exitCode) = execCmdEx(path & " uninstall -y PackageA") + let (outp, errp, exitCode) = execCmdEx2(path & " uninstall -y PackageA") check exitCode != QuitSuccess - let ls = outp.processOutput() + let ls = errp.processOutput() check ls[ls.len-2].startsWith(" Cannot uninstall PackageA ") check ls[ls.len-1].startsWith(" Cannot uninstall PackageA ") check execCmdEx(path & " uninstall -y PackageBin2").exitCode == QuitSuccess