diff --git a/.travis.yml b/.travis.yml index f1ff69e..8cfa912 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ os: - - windows - linux - osx @@ -8,17 +7,23 @@ language: c env: - BRANCH=0.19.6 - BRANCH=0.20.2 - - BRANCH=1.0.6 # This is the latest working Nim version against which Nimble is being tested - - BRANCH=#ab525cc48abdbbbed1f772e58e9fe21474f70f07 + - BRANCH=#212ae2f1257628bd5d1760593ce0a1bad768831a cache: directories: - - "$HOME/.choosenim" + - "$HOME/.choosenim/toolchains/nim-0.19.6" + - "$HOME/.choosenim/toolchains/nim-0.20.2" install: - - curl https://gist.github.com/genotrance/fb53504a4fba88bc5201d3783df5c522/raw/travis.sh -LsSf -o travis.sh - - source travis.sh + - export CHOOSENIM_CHOOSE_VERSION=$BRANCH + - | + curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh + sh init.sh -y + +before_script: + - export CHOOSENIM_NO_ANALYTICS=1 + - export PATH=$HOME/.nimble/bin:$PATH script: - cd tests diff --git a/changelog.markdown b/changelog.markdown index 92f1d31..a011485 100644 --- a/changelog.markdown +++ b/changelog.markdown @@ -3,33 +3,7 @@ # Nimble changelog -## 0.11.0 - 22/09/2019 - -This is a major release containing nearly 60 commits. Most changes are -bug fixes, but this release also includes a couple new features: - -- Binaries can now be built and run using the new ``run`` command. -- The ``NimblePkgVersion`` is now defined so you can easily get the package - version in your source code - ([example](https://github.com/nim-lang/nimble/blob/4a2aaa07d/tests/nimbleVersionDefine/src/nimbleVersionDefine.nim)). - -Some other highlights: - -- Temporary files are now kept when the ``--debug`` flag is used. -- Fixed dependency resolution issues with "#head" packages (#432 and #672). -- The `install` command can now take Nim compiler flags via the new - ``--passNim`` flag. -- Command line arguments are now passed properly to tasks (#633). -- The ``test`` command now respects the specified backend (#631). -- The ``dump`` command will no longer prompt and now has an implicit ``-y``. -- Fixed bugs with the new nimscript executor (#665). - Fixed multiple downloads and installs of the same package (#678). -- Nimble init no longer overwrites existing files (#581). -- Fixed incorrect submodule version being pulled when in a non-master branch (#675). - ----- - -Full changelog: https://github.com/nim-lang/nimble/compare/v0.10.2...v0.11.0 ## 0.10.2 - 03/06/2019 diff --git a/readme.markdown b/readme.markdown index 89f7a22..9470aa8 100644 --- a/readme.markdown +++ b/readme.markdown @@ -15,7 +15,6 @@ Interested in learning **how to create a package**? Skip directly to that sectio - [nimble install](#nimble-install) - [nimble uninstall](#nimble-uninstall) - [nimble build](#nimble-build) - - [nimble run](#nimble-run) - [nimble c](#nimble-c) - [nimble list](#nimble-list) - [nimble search](#nimble-search) @@ -75,15 +74,10 @@ not need to install Nimble manually**. But in case you still want to install Nimble manually, you can follow the following instructions. -There are two ways to install Nimble manually. Using ``koch`` and using Nimble -itself. - -### Using koch - -The ``koch`` tool is included in the Nim distribution and +There are two ways to install Nimble manually. The first is using the +``koch`` tool included in the Nim distribution and [repository](https://github.com/nim-lang/Nim/blob/devel/koch.nim). -Simply navigate to the location of your Nim installation and execute the -following command to compile and install Nimble. +Simply execute the following command to compile and install Nimble. ``` ./koch nimble @@ -92,19 +86,6 @@ following command to compile and install Nimble. This will clone the Nimble repository, compile Nimble and copy it into Nim's bin directory. -### Using Nimble - -In most cases you will already have Nimble installed, you can install a newer -version of Nimble by simply running the following command: - -``` -nimble install nimble -``` - -This will download the latest release of Nimble and install it on your system. - -Note that you must have `~/.nimble/bin` in your PATH for this to work, if you're -using choosenim then you likely already have this set up correctly. ## Nimble usage @@ -172,13 +153,12 @@ example: This is of course Git-specific, for Mercurial, use ``tip`` instead of ``head``. A branch, tag, or commit hash may also be specified in the place of ``head``. -Instead of specifying a VCS branch, you may also specify a concrete version or a -version range, for example: +Instead of specifying a VCS branch, you may also specify a version range, for +example: - $ nimble install nimgame@0.5 $ nimble install nimgame@"> 0.5" -The latter command will install a version which is greater than ``0.5``. +In this case a version which is greater than ``0.5`` will be installed. If you don't specify a parameter and there is a ``package.nimble`` file in your current working directory then Nimble will install the package residing in @@ -239,13 +219,6 @@ flags, i.e. a debug build which includes stack traces but no GDB debug information. The ``install`` command will build the package in release mode instead. -### nimble run - -The ``run`` command can be used to build and run any binary specified in your -package's ``bin`` list. You can pass any compilation flags you wish by specifying -them before the ``run`` command, and you can specify arguments for your binary -by specifying them after the ``run`` command. - ### nimble c The ``c`` (or ``compile``, ``js``, ``cc``, ``cpp``) command can be used by @@ -505,7 +478,7 @@ For a package named "foobar", the recommended project structure is the following └── src └── foobar.nim # Imported via `import foobar` └── tests # Contains the tests - ├── config.nims + ├── nim.cfg ├── tfoo1.nim # First test └── tfoo2.nim # Second test diff --git a/src/nimble.nim b/src/nimble.nim index d7e011e..ac37d00 100644 --- a/src/nimble.nim +++ b/src/nimble.nim @@ -3,13 +3,12 @@ import system except TResult -import os, tables, strtabs, json, algorithm, sets, uri, sugar, sequtils, osproc +import os, tables, strtabs, json, algorithm, sets, uri, sugar, sequtils import std/options as std_opt import strutils except toLower from unicode import toLower from sequtils import toSeq -from strformat import fmt import nimblepkg/packageinfo, nimblepkg/version, nimblepkg/tools, nimblepkg/download, nimblepkg/config, nimblepkg/common, @@ -201,13 +200,12 @@ proc processDeps(pkginfo: PackageInfo, options: Options): seq[PackageInfo] = # in the path. var pkgsInPath: StringTableRef = newStringTable(modeCaseSensitive) for pkgInfo in result: - let currentVer = pkgInfo.getConcreteVersion(options) if pkgsInPath.hasKey(pkgInfo.name) and - pkgsInPath[pkgInfo.name] != currentVer: + pkgsInPath[pkgInfo.name] != pkgInfo.version: raise newException(NimbleError, "Cannot satisfy the dependency on $1 $2 and $1 $3" % - [pkgInfo.name, currentVer, pkgsInPath[pkgInfo.name]]) - pkgsInPath[pkgInfo.name] = currentVer + [pkgInfo.name, pkgInfo.version, pkgsInPath[pkgInfo.name]]) + pkgsInPath[pkgInfo.name] = pkgInfo.version # We add the reverse deps to the JSON file here because we don't want # them added if the above errorenous condition occurs @@ -218,24 +216,17 @@ proc processDeps(pkginfo: PackageInfo, options: Options): seq[PackageInfo] = proc buildFromDir( pkgInfo: PackageInfo, paths, args: seq[string], - options: Options + binToBuild: Option[string] = none[string]() ) = ## Builds a package as specified by ``pkgInfo``. - let binToBuild = options.getCompilationBinary(pkgInfo) - # Handle pre-`build` hook. - let realDir = pkgInfo.getRealDir() - cd realDir: # Make sure `execHook` executes the correct .nimble file. - if not execHook(options, actionBuild, true): - raise newException(NimbleError, "Pre-hook prevented further execution.") - if pkgInfo.bin.len == 0: raise newException(NimbleError, "Nothing to build. Did you specify a module to build using the" & " `bin` key in your .nimble file?") var args = args + let realDir = pkgInfo.getRealDir() let nimblePkgVersion = "-d:NimblePkgVersion=" & pkgInfo.version for path in paths: args.add("--path:\"" & path & "\" ") - var binariesBuilt = 0 for bin in pkgInfo.bin: # Check if this is the only binary that we want to build. if binToBuild.isSome() and binToBuild.get() != bin: @@ -251,15 +242,10 @@ proc buildFromDir( if not existsDir(outputDir): createDir(outputDir) - let input = realDir / bin.changeFileExt("nim") - # `quoteShell` would be more robust than `\"` (and avoid quoting when - # un-necessary) but would require changing `extractBin` - let cmd = "\"$#\" $# --noNimblePath $# $# $# \"$#\"" % - [getNimBin(), pkgInfo.backend, nimblePkgVersion, - join(args, " "), outputOpt, input] try: - doCmd(cmd, showCmd = true) - binariesBuilt.inc() + doCmd("\"" & getNimBin() & "\" $# --noNimblePath $# $# $# \"$#\"" % + [pkgInfo.backend, nimblePkgVersion, join(args, " "), outputOpt, + realDir / bin.changeFileExt("nim")]) except NimbleError: let currentExc = (ref NimbleError)(getCurrentException()) let exc = newException(BuildFailed, "Build failed for package: " & @@ -269,15 +255,6 @@ proc buildFromDir( exc.hint = hint raise exc - if binariesBuilt == 0: - raiseNimbleError( - "No binaries built, did you specify a valid binary name?" - ) - - # Handle post-`build` hook. - cd realDir: # Make sure `execHook` executes the correct .nimble file. - discard execHook(options, actionBuild, false) - proc removePkgDir(dir: string, options: Options) = ## Removes files belonging to the package in ``dir``. try: @@ -355,7 +332,7 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options, # Handle pre-`install` hook. if not options.depsOnly: cd dir: # Make sure `execHook` executes the correct .nimble file. - if not execHook(options, actionInstall, true): + if not execHook(options, true): raise newException(NimbleError, "Pre-hook prevented further execution.") var pkgInfo = getPkgInfo(dir, options) @@ -386,7 +363,7 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options, options.action.passNimFlags else: @[] - buildFromDir(pkgInfo, paths, "-d:release" & flags, options) + buildFromDir(pkgInfo, paths, flags & "-d:release") let pkgDestDir = pkgInfo.getPkgDest(options) if existsDir(pkgDestDir) and existsFile(pkgDestDir / "nimblemeta.json"): @@ -469,7 +446,7 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options, # executes the hook defined in the CWD, so we set it to where the package # has been installed. cd dest.splitFile.dir: - discard execHook(options, actionInstall, false) + discard execHook(options, false) proc getDownloadInfo*(pv: PkgTuple, options: Options, doPrompt: bool): (DownloadMethod, string, @@ -537,11 +514,11 @@ proc build(options: Options) = let deps = processDeps(pkginfo, options) let paths = deps.map(dep => dep.getRealDir()) var args = options.getCompilationFlags() - buildFromDir(pkgInfo, paths, args, options) + buildFromDir(pkgInfo, paths, args, options.getCompilationBinary()) -proc execBackend(pkgInfo: PackageInfo, options: Options) = +proc execBackend(options: Options) = let - bin = options.getCompilationBinary(pkgInfo).get() + bin = options.getCompilationBinary().get() binDotNim = bin.addFileExt("nim") if bin == "": raise newException(NimbleError, "You need to specify a file.") @@ -729,11 +706,6 @@ proc dump(options: Options) = echo "backend: ", p.backend.escape proc init(options: Options) = - # Check whether the vcs is installed. - let vcsBin = options.action.vcsOption - if vcsBin != "" and findExe(vcsBin, true) == "": - raise newException(NimbleError, "Please install git or mercurial first") - # Determine the package name. let pkgName = if options.action.projName != "": @@ -868,17 +840,6 @@ js - Compile using JavaScript backend.""", pkgRoot ) - # Create a git or hg repo in the new nimble project. - if vcsBin != "": - let cmd = fmt"cd {pkgRoot} && {vcsBin} init" - let ret: tuple[output: string, exitCode: int] = execCmdEx(cmd) - if ret.exitCode != 0: quit ret.output - - var ignoreFile = if vcsBin == "git": ".gitignore" else: ".hgignore" - var fd = open(joinPath(pkgRoot, ignoreFile), fmWrite) - fd.write(pkgName & "\n") - fd.close() - display("Success:", "Package $# created successfully" % [pkgName], Success, HighPriority) @@ -956,7 +917,7 @@ proc developFromDir(dir: string, options: Options) = raiseNimbleError("Cannot develop dependencies only.") cd dir: # Make sure `execHook` executes the correct .nimble file. - if not execHook(options, actionDevelop, true): + if not execHook(options, true): raise newException(NimbleError, "Pre-hook prevented further execution.") var pkgInfo = getPkgInfo(dir, options) @@ -1009,7 +970,7 @@ proc developFromDir(dir: string, options: Options) = # Execute the post-develop hook. cd dir: - discard execHook(options, actionDevelop, false) + discard execHook(options, false) proc develop(options: Options) = if options.action.packages == @[]: @@ -1074,21 +1035,17 @@ proc test(options: Options) = if options.continueTestsOnFailure: inc tests try: - execBackend(pkgInfo, optsCopy) + execBackend(optsCopy) except NimbleError: inc failures else: - execBackend(pkgInfo, optsCopy) + execBackend(optsCopy) let existsAfter = existsFile(binFileName) canRemove = not existsBefore and existsAfter if canRemove: - try: - removeFile(binFileName) - except OSError as exc: - display("Warning:", "Failed to delete " & binFileName & ": " & - exc.msg, Warning, MediumPriority) + removeFile(binFileName) if failures == 0: display("Success:", "All tests passed", Success, HighPriority) @@ -1117,27 +1074,27 @@ proc check(options: Options) = proc run(options: Options) = # Verify parameters. - var pkgInfo = getPkgInfo(getCurrentDir(), options) - - let binary = options.getCompilationBinary(pkgInfo).get("") + let binary = options.getCompilationBinary().get() if binary.len == 0: raiseNimbleError("Please specify a binary to run") + var pkgInfo = getPkgInfo(getCurrentDir(), options) if binary notin pkgInfo.bin: raiseNimbleError( "Binary '$#' is not defined in '$#' package." % [binary, pkgInfo.name] ) + let binaryPath = pkgInfo.getOutputDir(binary) + # Build the binary. build(options) - let binaryPath = pkgInfo.getOutputDir(binary) - let cmd = quoteShellCommand(binaryPath & options.action.runFlags) - displayDebug("Executing", cmd) - cmd.execCmd.quit + # Now run it. + let args = options.action.runFlags.join(" ") + doCmd("$# $#" % [binaryPath, args], showOutput = true) -proc doAction(options: var Options) = +proc doAction(options: Options) = if options.showHelp: writeHelp() if options.showVersion: @@ -1148,10 +1105,6 @@ proc doAction(options: var Options) = if not existsDir(options.getPkgsDir): createDir(options.getPkgsDir) - if options.action.typ in {actionTasks, actionRun, actionBuild, actionCompile}: - # Implicitly disable package validation for these commands. - options.disableValidation = true - case options.action.typ of actionRefresh: refresh(options) @@ -1180,8 +1133,7 @@ proc doAction(options: var Options) = of actionRun: run(options) of actionCompile, actionDoc: - var pkgInfo = getPkgInfo(getCurrentDir(), options) - execBackend(pkgInfo, options) + execBackend(options) of actionInit: init(options) of actionPublish: @@ -1198,7 +1150,7 @@ proc doAction(options: var Options) = of actionNil: assert false of actionCustom: - if not execHook(options, actionCustom, true): + if not execHook(options, true): display("Warning", "Pre-hook prevented further execution.", Warning, HighPriority) return @@ -1207,15 +1159,14 @@ proc doAction(options: var Options) = var execResult: ExecutionResult[bool] if execCustom(options, execResult, failFast=not isPreDefined): if execResult.hasTaskRequestedCommand(): - var options = execResult.getOptionsForCommand(options) - doAction(options) + doAction(execResult.getOptionsForCommand(options)) else: # If there is no task defined for the `test` task, we run the pre-defined # fallback logic. if isPreDefined: test(options) # Run the post hook for `test` in case it exists. - discard execHook(options, actionCustom, false) + discard execHook(options, false) when isMainModule: var error = "" diff --git a/src/nimblepkg/common.nim b/src/nimblepkg/common.nim index ab83175..c40a82d 100644 --- a/src/nimblepkg/common.nim +++ b/src/nimblepkg/common.nim @@ -22,8 +22,7 @@ when not defined(nimscript): preHooks*: HashSet[string] name*: string ## The version specified in the .nimble file.Assuming info is non-minimal, - ## it will always be a non-special version such as '0.1.4'. - ## If in doubt, use `getConcreteVersion` instead. + ## it will always be a non-special version such as '0.1.4' version*: string specialVersion*: string ## Either `myVersion` or a special version such as #head. author*: string diff --git a/src/nimblepkg/download.nim b/src/nimblepkg/download.nim index 3bbfa25..85bf54f 100644 --- a/src/nimblepkg/download.nim +++ b/src/nimblepkg/download.nim @@ -300,17 +300,4 @@ when isMainModule: }) doAssert expected == getVersionList(data) - - block: - let data2 = @["v0.1.0", "v0.1.1", "v0.2.0", - "0.4.0", "v0.4.2"] - let expected2 = toOrderedTable[Version, string]({ - newVersion("0.4.2"): "v0.4.2", - newVersion("0.4.0"): "0.4.0", - newVersion("0.2.0"): "v0.2.0", - newVersion("0.1.1"): "v0.1.1", - newVersion("0.1.0"): "v0.1.0", - }) - doAssert expected2 == getVersionList(data2) - echo("Everything works!") diff --git a/src/nimblepkg/nimscriptapi.nim b/src/nimblepkg/nimscriptapi.nim index ec2f46c..a8b4ba3 100644 --- a/src/nimblepkg/nimscriptapi.nim +++ b/src/nimblepkg/nimscriptapi.nim @@ -17,7 +17,7 @@ var author*: string ## The package's author. description*: string ## The package's description. license*: string ## The package's license. - srcDir*: string ## The package's source directory. + srcdir*: string ## The package's source directory. binDir*: string ## The package's binary directory. backend*: string ## The package's backend. @@ -101,7 +101,7 @@ proc printPkgInfo(): string = printIfLen author printIfLen description printIfLen license - printIfLen srcDir + printIfLen srcdir printIfLen binDir printIfLen backend diff --git a/src/nimblepkg/nimscriptexecutor.nim b/src/nimblepkg/nimscriptexecutor.nim index 122c41c..bf8afd1 100644 --- a/src/nimblepkg/nimscriptexecutor.nim +++ b/src/nimblepkg/nimscriptexecutor.nim @@ -6,12 +6,12 @@ import os, strutils, sets import packageparser, common, packageinfo, options, nimscriptwrapper, cli, version -proc execHook*(options: Options, hookAction: ActionType, before: bool): bool = +proc execHook*(options: Options, before: bool): bool = ## Returns whether to continue. result = true # For certain commands hooks should not be evaluated. - if hookAction in noHookActions: + if options.action.typ in noHookActions: return var nimbleFile = "" @@ -21,8 +21,8 @@ proc execHook*(options: Options, hookAction: ActionType, before: bool): bool = # PackageInfos are cached so we can read them as many times as we want. let pkgInfo = getPkgInfoFromFile(nimbleFile, options) let actionName = - if hookAction == actionCustom: options.action.command - else: ($hookAction)[6 .. ^1] + if options.action.typ == actionCustom: options.action.command + else: ($options.action.typ)[6 .. ^1] let hookExists = if before: actionName.normalize in pkgInfo.preHooks else: actionName.normalize in pkgInfo.postHooks @@ -58,7 +58,7 @@ proc execCustom*(options: Options, HighPriority) return - if not execHook(options, actionCustom, false): + if not execHook(options, false): return return true diff --git a/src/nimblepkg/nimscriptwrapper.nim b/src/nimblepkg/nimscriptwrapper.nim index 4cfe6ec..d7b7a3b 100644 --- a/src/nimblepkg/nimscriptwrapper.nim +++ b/src/nimblepkg/nimscriptwrapper.nim @@ -4,9 +4,8 @@ ## Implements the new configuration system for Nimble. Uses Nim as a ## scripting language. -import hashes, json, os, strutils, tables, times, osproc, strtabs - import version, options, cli, tools +import hashes, json, os, strutils, tables, times, osproc, strtabs type Flags = TableRef[string, seq[string]] @@ -16,29 +15,13 @@ type arguments*: seq[string] flags*: Flags retVal*: T - stdout*: string const internalCmd = "e" nimscriptApi = staticRead("nimscriptapi.nim") - printPkgInfo = "printPkgInfo" -proc isCustomTask(actionName: string, options: Options): bool = - options.action.typ == actionCustom and actionName != printPkgInfo - -proc needsLiveOutput(actionName: string, options: Options, isHook: bool): bool = - let isCustomTask = isCustomTask(actionName, options) - return isCustomTask or isHook or actionName == "" - -proc writeExecutionOutput(data: string) = - # TODO: in the future we will likely want this to be live, users will - # undoubtedly be doing loops and other crazy things in their top-level - # Nimble files. - display("Info", data) - -proc execNimscript( - nimsFile, projectDir, actionName: string, options: Options, isHook: bool -): tuple[output: string, exitCode: int, stdout: string] = +proc execNimscript(nimsFile, projectDir, actionName: string, options: Options): + tuple[output: string, exitCode: int] = let nimsFileCopied = projectDir / nimsFile.splitFile().name & "_" & getProcessId() & ".nims" outFile = getNimbleTempDir() & ".out" @@ -56,18 +39,11 @@ proc execNimscript( if not isScriptResultCopied and options.shouldRemoveTmp(nimsFileCopied): nimsFileCopied.removeFile() - var cmd = ( - "nim e $# -p:$# $# $# $#" % [ - "--hints:off --verbosity:0", - (getTempDir() / "nimblecache").quoteShell, - nimsFileCopied.quoteShell, - outFile.quoteShell, - actionName - ] - ).strip() + var + cmd = ("nim e --hints:off --verbosity:0 -p:" & (getTempDir() / "nimblecache").quoteShell & + " " & nimsFileCopied.quoteShell & " " & outFile.quoteShell & " " & actionName).strip() - let isCustomTask = isCustomTask(actionName, options) - if isCustomTask: + if options.action.typ == actionCustom and actionName != "printPkgInfo": for i in options.action.arguments: cmd &= " " & i.quoteShell() for key, val in options.action.flags.pairs(): @@ -77,12 +53,7 @@ proc execNimscript( displayDebug("Executing " & cmd) - if needsLiveOutput(actionName, options, isHook): - result.exitCode = execCmd(cmd) - else: - # We want to capture any possible errors when parsing a .nimble - # file's metadata. See #710. - (result.stdout, result.exitCode) = execCmdEx(cmd) + result.exitCode = execCmd(cmd) if outFile.fileExists(): result.output = outFile.readFile() if options.shouldRemoveTmp(outFile): @@ -135,30 +106,27 @@ proc getIniFile*(scriptName: string, options: Options): string = scriptName.getLastModificationTime() if not isIniResultCached: - let (output, exitCode, stdout) = execNimscript( - nimsFile, scriptName.parentDir(), printPkgInfo, options, isHook=false - ) + let + (output, exitCode) = + execNimscript(nimsFile, scriptName.parentDir(), "printPkgInfo", options) if exitCode == 0 and output.len != 0: result.writeFile(output) - stdout.writeExecutionOutput() else: - raise newException(NimbleError, stdout & "\nprintPkgInfo() failed") + raise newException(NimbleError, output & "\nprintPkgInfo() failed") -proc execScript( - scriptName, actionName: string, options: Options, isHook: bool -): ExecutionResult[bool] = - let nimsFile = getNimsFile(scriptName, options) +proc execScript(scriptName, actionName: string, options: Options): + ExecutionResult[bool] = + let + nimsFile = getNimsFile(scriptName, options) - let (output, exitCode, stdout) = - execNimscript( - nimsFile, scriptName.parentDir(), actionName, options, isHook - ) + let + (output, exitCode) = execNimscript(nimsFile, scriptName.parentDir(), actionName, options) if exitCode != 0: let errMsg = - if stdout.len != 0: - stdout + if output.len != 0: + output else: "Exception raised during nimble script execution" raise newException(NimbleError, errMsg) @@ -182,8 +150,6 @@ proc execScript( result.flags[flag].add val.getStr() result.retVal = j{"retVal"}.getBool() - stdout.writeExecutionOutput() - proc execTask*(scriptName, taskName: string, options: Options): ExecutionResult[bool] = ## Executes the specified task in the specified script. @@ -192,7 +158,7 @@ proc execTask*(scriptName, taskName: string, display("Executing", "task $# in $#" % [taskName, scriptName], priority = HighPriority) - result = execScript(scriptName, taskName, options, isHook=false) + result = execScript(scriptName, taskName, options) proc execHook*(scriptName, actionName: string, before: bool, options: Options): ExecutionResult[bool] = @@ -206,11 +172,11 @@ proc execHook*(scriptName, actionName: string, before: bool, display("Attempting", "to execute hook $# in $#" % [hookName, scriptName], priority = MediumPriority) - result = execScript(scriptName, hookName, options, isHook=true) + result = execScript(scriptName, hookName, options) proc hasTaskRequestedCommand*(execResult: ExecutionResult): bool = ## Determines whether the last executed task used ``setCommand`` return execResult.command != internalCmd proc listTasks*(scriptName: string, options: Options) = - discard execScript(scriptName, "", options, isHook=false) + discard execScript(scriptName, "", options) diff --git a/src/nimblepkg/options.nim b/src/nimblepkg/options.nim index 14d1c31..28560e7 100644 --- a/src/nimblepkg/options.nim +++ b/src/nimblepkg/options.nim @@ -51,13 +51,12 @@ type search*: seq[string] # Search string. of actionInit, actionDump: projName*: string - vcsOption*: string of actionCompile, actionDoc, actionBuild: file*: string backend*: string compileOptions: seq[string] of actionRun: - runFile: Option[string] + runFile: string compileFlags: seq[string] runFlags*: seq[string] of actionCustom: @@ -81,19 +80,13 @@ Commands: init [pkgname] Initializes a new Nimble project in the current directory or if a name is provided a new directory of the same name. - --git - --hg Create a git or hg repo in the new nimble project. publish Publishes a package on nim-lang/packages. The current working directory needs to be the toplevel directory of the Nimble package. uninstall [pkgname, ...] Uninstalls a list of packages. [-i, --inclDeps] Uninstall package and dependent package(s). - build [opts, ...] [bin] Builds a package. - run [opts, ...] [bin] Builds and runs a package. - Binary needs to be specified after any - compilation options if there are several - binaries defined, any flags after the binary - or -- arg are passed to the binary when it is run. + build [opts, ...] Builds a package. + run [opts, ...] bin Builds and runs a package. c, cc, js [opts, ...] f.nim Builds a file inside a package. Passes options to the Nim compiler. test Compiles and executes tests @@ -204,10 +197,8 @@ proc initAction*(options: var Options, key: string) = else: options.action.backend = keyNorm of actionInit: options.action.projName = "" - options.action.vcsOption = "" of actionDump: options.action.projName = "" - options.action.vcsOption = "" options.forcePrompts = forcePromptYes of actionRefresh: options.action.optionalURL = "" @@ -266,12 +257,6 @@ proc parseCommand*(key: string, result: var Options) = result.action = Action(typ: parseActionType(key)) initAction(result, key) -proc setRunOptions(result: var Options, key, val: string, isArg: bool) = - if result.action.runFile.isNone() and (isArg or val == "--"): - result.action.runFile = some(key) - else: - result.action.runFlags.add(val) - proc parseArgument*(key: string, result: var Options) = case result.action.typ of actionNil: @@ -303,7 +288,10 @@ proc parseArgument*(key: string, result: var Options) = of actionBuild: result.action.file = key of actionRun: - result.setRunOptions(key, key, true) + if result.action.runFile.len == 0: + result.action.runFile = key + else: + result.action.runFlags.add(key) of actionCustom: result.action.arguments.add(key) else: @@ -357,12 +345,6 @@ proc parseFlag*(flag, val: string, result: var Options, kind = cmdLongOption) = result.action.passNimFlags.add(val) else: wasFlagHandled = false - of actionInit: - case f - of "git", "hg": - result.action.vcsOption = f - else: - wasFlagHandled = false of actionUninstall: case f of "incldeps", "i": @@ -373,8 +355,7 @@ proc parseFlag*(flag, val: string, result: var Options, kind = cmdLongOption) = if not isGlobalFlag: result.action.compileOptions.add(getFlagString(kind, flag, val)) of actionRun: - result.showHelp = false - result.setRunOptions(flag, getFlagString(kind, flag, val), false) + result.action.runFlags.add(getFlagString(kind, flag, val)) of actionCustom: if result.action.command.normalize == "test": if f == "continue" or f == "c": @@ -386,8 +367,7 @@ proc parseFlag*(flag, val: string, result: var Options, kind = cmdLongOption) = if not wasFlagHandled and not isGlobalFlag: result.unknownFlags.add((kind, flag, val)) -proc initOptions*(): Options = - # Exported for choosenim +proc initOptions(): Options = Options( action: Action(typ: actionNil), pkgInfoCache: newTable[string, PackageInfo](), @@ -410,18 +390,9 @@ proc parseMisc(options: var Options) = proc handleUnknownFlags(options: var Options) = if options.action.typ == actionRun: - # ActionRun uses flags that come before the command as compilation flags - # and flags that come after as run flags. options.action.compileFlags = map(options.unknownFlags, x => getFlagString(x[0], x[1], x[2])) options.unknownFlags = @[] - else: - # For everything else, handle the flags that came before the command - # normally. - let unknownFlags = options.unknownFlags - options.unknownFlags = @[] - for flag in unknownFlags: - parseFlag(flag[1], flag[2], options, flag[0]) # Any unhandled flags? if options.unknownFlags.len > 0: @@ -444,7 +415,7 @@ proc parseCmdLine*(): Options = else: parseArgument(key, result) of cmdLongOption, cmdShortOption: - parseFlag(key, val, result, kind) + parseFlag(key, val, result, kind) of cmdEnd: assert(false) # cannot happen handleUnknownFlags(result) @@ -529,23 +500,15 @@ proc getCompilationFlags*(options: Options): seq[string] = var opt = options return opt.getCompilationFlags() -proc getCompilationBinary*(options: Options, pkgInfo: PackageInfo): Option[string] = +proc getCompilationBinary*(options: Options): Option[string] = case options.action.typ of actionBuild, actionDoc, actionCompile: let file = options.action.file.changeFileExt("") if file.len > 0: return some(file) of actionRun: - let optRunFile = options.action.runFile - let runFile = - if optRunFile.get("").len > 0: - optRunFile.get() - elif pkgInfo.bin.len == 1: - pkgInfo.bin[0] - else: - "" - + let runFile = options.action.runFile.changeFileExt("") if runFile.len > 0: - return some(runFile.changeFileExt(ExeExt)) + return some(runFile) else: - discard + discard \ No newline at end of file diff --git a/src/nimblepkg/packageparser.nim b/src/nimblepkg/packageparser.nim index 9458074..59c2ca8 100644 --- a/src/nimblepkg/packageparser.nim +++ b/src/nimblepkg/packageparser.nim @@ -487,15 +487,6 @@ proc toFullInfo*(pkg: PackageInfo, options: Options): PackageInfo = else: return pkg -proc getConcreteVersion*(pkgInfo: PackageInfo, options: Options): string = - ## Returns a non-special version from the specified ``pkgInfo``. If the - ## ``pkgInfo`` is minimal it looks it up and retrieves the concrete version. - result = pkgInfo.version - if pkgInfo.isMinimal: - let pkgInfo = pkgInfo.toFullInfo(options) - result = pkgInfo.version - assert(not newVersion(result).isSpecial) - when isMainModule: validatePackageName("foo_bar") validatePackageName("f_oo_b_a_r") diff --git a/src/nimblepkg/tools.nim b/src/nimblepkg/tools.nim index a0e6a0e..b39fea7 100644 --- a/src/nimblepkg/tools.nim +++ b/src/nimblepkg/tools.nim @@ -11,7 +11,7 @@ proc extractBin(cmd: string): string = else: return cmd.split(' ')[0] -proc doCmd*(cmd: string, showOutput = false, showCmd = false) = +proc doCmd*(cmd: string, showOutput = false) = let bin = extractBin(cmd) if findExe(bin) == "": raise newException(NimbleError, "'" & bin & "' not in PATH.") @@ -20,10 +20,7 @@ proc doCmd*(cmd: string, showOutput = false, showCmd = false) = stdout.flushFile() stderr.flushFile() - if showCmd: - display("Executing", cmd, priority = MediumPriority) - else: - displayDebug("Executing", cmd) + displayDebug("Executing", cmd) if showOutput: let exitCode = execCmd(cmd) displayDebug("Finished", "with exit code " & $exitCode) diff --git a/src/nimblepkg/version.nim b/src/nimblepkg/version.nim index e4114f1..4834b6d 100644 --- a/src/nimblepkg/version.nim +++ b/src/nimblepkg/version.nim @@ -147,7 +147,7 @@ proc makeRange*(version: string, op: string): VersionRange = result = VersionRange(kind: verEqLater) of "<=": result = VersionRange(kind: verEqEarlier) - of "", "==": + of "": result = VersionRange(kind: verEq) else: raise newException(ParseVersionError, "Invalid operator: " & op) @@ -298,10 +298,9 @@ when isMainModule: doAssert(newVersion("0.1.0") <= newVersion("0.1")) var inter1 = parseVersionRange(">= 1.0 & <= 1.5") - doAssert(inter1.kind == verIntersect) + doAssert inter1.kind == verIntersect var inter2 = parseVersionRange("1.0") doAssert(inter2.kind == verEq) - doAssert(parseVersionRange("== 3.4.2") == parseVersionRange("3.4.2")) doAssert(not withinRange(newVersion("1.5.1"), inter1)) doAssert(withinRange(newVersion("1.0.2.3.4.5.6.7.8.9.10.11.12"), inter1)) diff --git a/tests/invalidPackage/invalidPackage.nimble b/tests/invalidPackage/invalidPackage.nimble deleted file mode 100644 index 08fcfcb..0000000 --- a/tests/invalidPackage/invalidPackage.nimble +++ /dev/null @@ -1,13 +0,0 @@ -# Package - -version = "0.1.0" -author = "Dominik Picheta" -description = "A new awesome nimble package" -license = "MIT" -srcDir = "src" - -thisFieldDoesNotExist = "hello" - -# Dependencies - -requires "nim >= 0.20.0" diff --git a/tests/issue432/issue432.nimble b/tests/issue432/issue432.nimble deleted file mode 100644 index 92937c5..0000000 --- a/tests/issue432/issue432.nimble +++ /dev/null @@ -1,15 +0,0 @@ -# Package - -version = "0.1.0" -author = "Dominik Picheta" -description = "A new awesome nimble package" -license = "MIT" -srcDir = "src" - - - -# Dependencies - -requires "nim >= 0.16.0" -requires "https://github.com/nimble-test/packagea#head", - "https://github.com/nimble-test/packagebin2" diff --git a/tests/issue564/issue564.nimble b/tests/issue564/issue564.nimble deleted file mode 100644 index 7dc0013..0000000 --- a/tests/issue564/issue564.nimble +++ /dev/null @@ -1,14 +0,0 @@ -# Package - -version = "0.1.0" -author = "Dominik Picheta" -description = "A new awesome nimble package" -license = "MIT" -srcDir = "src" -bin = @["issue564/issue564build"] - - - -# Dependencies - -requires "nim >= 0.16.0" diff --git a/tests/issue564/src/issue564/issue564build.nim b/tests/issue564/src/issue564/issue564build.nim deleted file mode 100644 index 862d40c..0000000 --- a/tests/issue564/src/issue564/issue564build.nim +++ /dev/null @@ -1,5 +0,0 @@ -# This is just an example to get you started. A typical binary package -# uses this file as the main entry point of the application. - -when isMainModule: - echo("Hello, World!") diff --git a/tests/issue708/issue708.nimble b/tests/issue598/issue598.nimble similarity index 79% rename from tests/issue708/issue708.nimble rename to tests/issue598/issue598.nimble index ebb079d..7db6c70 100644 --- a/tests/issue708/issue708.nimble +++ b/tests/issue598/issue598.nimble @@ -11,7 +11,4 @@ srcDir = "src" # Dependencies requires "nim >= 0.16.0" - - -echo "hello" -echo "hello2" +requires "https://github.com/nimble-test/packageb/" diff --git a/tests/issue432/src/issue432.nim b/tests/issue598/src/issue598.nim similarity index 100% rename from tests/issue432/src/issue432.nim rename to tests/issue598/src/issue598.nim diff --git a/tests/issue708/src/issue708.nim b/tests/issue708/src/issue708.nim deleted file mode 100644 index 4b2a270..0000000 --- a/tests/issue708/src/issue708.nim +++ /dev/null @@ -1,7 +0,0 @@ -# This is just an example to get you started. A typical library package -# exports the main API in this file. Note that you cannot rename this file -# but you can remove it if you wish. - -proc add*(x, y: int): int = - ## Adds two files together. - return x + y diff --git a/tests/nimbleVersionDefine/src/nimbleVersionDefine b/tests/nimbleVersionDefine/src/nimbleVersionDefine index af3cc22..3b089c0 100755 Binary files a/tests/nimbleVersionDefine/src/nimbleVersionDefine and b/tests/nimbleVersionDefine/src/nimbleVersionDefine differ diff --git a/tests/nimscript/nimscript.nimble b/tests/nimscript/nimscript.nimble index 39f3710..f27631a 100644 --- a/tests/nimscript/nimscript.nimble +++ b/tests/nimscript/nimscript.nimble @@ -54,9 +54,3 @@ before install: after install: echo("After PkgDir: ", getPkgDir()) - -before build: - echo("Before build") - -after build: - echo("After build") \ No newline at end of file diff --git a/tests/recursive/recursive.nimble b/tests/recursive/recursive.nimble index d6b155d..972dd0b 100644 --- a/tests/recursive/recursive.nimble +++ b/tests/recursive/recursive.nimble @@ -9,9 +9,10 @@ license = "BSD" requires "nim >= 0.12.1" -let - callNimble = getEnv("NIMBLE_TEST_BINARY_PATH") -doAssert callNimble.len != 0, "NIMBLE_TEST_BINARY_PATH not set" +when defined(windows): + let callNimble = "..\\..\\src\\nimble.exe" +else: + let callNimble = "../../src/nimble" task recurse, "Level 1": echo 1 diff --git a/tests/tester.nim b/tests/tester.nim index 446fecb..b7cc78c 100644 --- a/tests/tester.nim +++ b/tests/tester.nim @@ -12,9 +12,6 @@ var installDir = rootDir / "tests" / "nimbleDir" const path = "../src/nimble" const stringNotFound = -1 -# Set env var to propagate nimble binary path -putEnv("NIMBLE_TEST_BINARY_PATH", nimblePath) - # Clear nimble dir. removeDir(installDir) createDir(installDir) @@ -38,7 +35,7 @@ proc execNimble(args: varargs[string]): tuple[output: string, exitCode: int] = var quotedArgs = @args quotedArgs.insert("--nimbleDir:" & installDir) quotedArgs.insert(nimblePath) - quotedArgs = quotedArgs.map((x: string) => x.quoteShell) + quotedArgs = quotedArgs.map((x: string) => ("\"" & x & "\"")) let path {.used.} = getCurrentDir().parentDir() / "src" @@ -82,34 +79,17 @@ proc hasLineStartingWith(lines: seq[string], prefix: string): bool = return true return false -test "issue 708": - cd "issue708": - # TODO: We need a way to filter out compiler messages from the messages - # written by our nimble scripts. - var (output, exitCode) = execNimble("install", "-y", "--verbose") - check exitCode == QuitSuccess - let lines = output.strip.processOutput() - check(inLines(lines, "hello")) - check(inLines(lines, "hello2")) +test "issues #598": + check execNimble( + "install", "-y", + "https://github.com/nimble-test/packageb@#9f3bd9f7ad7254d156e" + ).exitCode == QuitSuccess + + cd "issue598": + let (output, exitCode) = execNimble("install", "-n") -test "issue 564": - cd "issue564": - var (_, exitCode) = execNimble("build") - check exitCode == QuitSuccess -test "depsOnly + flag order test": - var (output, exitCode) = execNimble( - "--depsOnly", "install", "-y", "https://github.com/nimble-test/packagebin2" - ) - check(not output.contains("Success: packagebin2 installed successfully.")) - check exitCode == QuitSuccess -test "nimscript evaluation error message": - cd "invalidPackage": - var (output, exitCode) = execNimble("check") - let lines = output.strip.processOutput() - check(lines[^2].endsWith("Error: undeclared identifier: 'thisFieldDoesNotExist'")) - check exitCode == QuitFailure test "caching of nims and ini detects changes": cd "caching": @@ -318,21 +298,12 @@ suite "nimscript": cd "nimscript": let (output, exitCode) = execNimble(["install", "-y"]) check exitCode == QuitSuccess - check output.contains("Before build") - check output.contains("After build") let lines = output.strip.processOutput() check lines[0].startsWith("Before PkgDir:") check lines[0].endsWith("tests" / "nimscript") check lines[^1].startsWith("After PkgDir:") check lines[^1].endsWith("tests" / "nimbleDir" / "pkgs" / "nimscript-0.1.0") - test "before/after on build": - cd "nimscript": - let (output, exitCode) = execNimble(["build"]) - check exitCode == QuitSuccess - check output.contains("Before build") - check output.contains("After build") - test "can execute nimscript tasks": cd "nimscript": let (output, exitCode) = execNimble("--verbose", "work") @@ -483,17 +454,17 @@ test "issue #349": ] proc checkName(name: string) = + when defined(windows): + if name.toLowerAscii() in @["con", "nul"]: + return let (outp, code) = execNimble("init", "-y", name) let msg = outp.strip.processOutput() check code == QuitFailure check inLines(msg, "\"$1\" is an invalid package name: reserved name" % name) - try: - removeFile(name.changeFileExt("nimble")) - removeDir("src") - removeDir("tests") - except OSError: - discard + removeFile(name.changeFileExt("nimble")) + removeDir("src") + removeDir("tests") for reserved in reservedNames: checkName(reserved.toUpperAscii()) @@ -933,8 +904,7 @@ suite "nimble run": "blahblah", # The command to run ) check exitCode == QuitFailure - check output.contains("Binary '$1' is not defined in 'run' package." % - "blahblah".changeFileExt(ExeExt)) + check output.contains("Binary 'blahblah' is not defined in 'run' package.") test "Parameters passed to executable": cd "run": @@ -946,54 +916,9 @@ suite "nimble run": "check" # Second argument passed to the executed command. ) check exitCode == QuitSuccess - check output.contains("tests$1run$1$2 --debug check" % - [$DirSep, "run".changeFileExt(ExeExt)]) + check output.contains("tests/run/run --debug check") check output.contains("""Testing `nimble run`: @["--debug", "check"]""") - test "Parameters not passed to single executable": - cd "run": - var (output, exitCode) = execNimble( - "--debug", # Flag to enable debug verbosity in Nimble - "run", # Run command invokation - "--debug" # First argument passed to the executed command - ) - check exitCode == QuitSuccess - check output.contains("tests$1run$1$2 --debug" % - [$DirSep, "run".changeFileExt(ExeExt)]) - check output.contains("""Testing `nimble run`: @["--debug"]""") - - test "Parameters passed to single executable": - cd "run": - var (output, exitCode) = execNimble( - "--debug", # Flag to enable debug verbosity in Nimble - "run", # Run command invokation - "--", # Flag to set run file to "" before next argument - "--debug", # First argument passed to the executed command - "check" # Second argument passed to the executed command. - ) - check exitCode == QuitSuccess - check output.contains("tests$1run$1$2 --debug check" % - [$DirSep, "run".changeFileExt(ExeExt)]) - check output.contains("""Testing `nimble run`: @["--debug", "check"]""") - - test "Executable output is shown even when not debugging": - cd "run": - var (output, exitCode) = - execNimble("run", "run", "--option1", "arg1") - check exitCode == QuitSuccess - check output.contains("""Testing `nimble run`: @["--option1", "arg1"]""") - - test "Quotes and whitespace are well handled": - cd "run": - var (output, exitCode) = execNimble( - "run", "run", "\"", "\'", "\t", "arg with spaces" - ) - check exitCode == QuitSuccess - check output.contains( - """Testing `nimble run`: @["\"", "\'", "\t", "arg with spaces"]""" - ) - - test "NimbleVersion is defined": cd "nimbleVersionDefine": var (output, exitCode) = execNimble("c", "-r", "src/nimbleVersionDefine.nim") @@ -1004,11 +929,6 @@ test "NimbleVersion is defined": check output2.contains("0.1.0") check exitCode2 == QuitSuccess -test "issue 432": - cd "issue432": - check execNimble("install", "-y", "--depsOnly").exitCode == QuitSuccess - check execNimble("install", "-y", "--depsOnly").exitCode == QuitSuccess - test "compilation without warnings": const buildDir = "./buildDir/" const filesToBuild = [