Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 120 additions & 85 deletions src/nimble.nim

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/nimblepkg/build.nim
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ proc getDepsPkgInfo*(satResult: SATResult, pkgInfo: PackageInfo, options: Option
let depInfo = getPkgInfoFromSolution(satResult, solvedPkg, options)
result.add(depInfo)

proc expandPaths*(pkgInfo: PackageInfo, nimBin: string, options: Options): seq[string] =
proc expandPaths*(pkgInfo: PackageInfo, nimBin: Option[string], options: Options): seq[string] =
var pkgInfo = pkgInfo.toFullInfo(options, nimBin = nimBin) #TODO is this needed in VNEXT? I dont think so
pkgInfo = pkgInfo.toRequiresInfo(options, nimBin = nimBin)
let baseDir = pkgInfo.getRealDir()
Expand All @@ -65,7 +65,7 @@ proc expandPaths*(pkgInfo: PackageInfo, nimBin: string, options: Options): seq[s
result.add path

proc getPathsToBuildFor*(satResult: SATResult, pkgInfo: PackageInfo, recursive: bool, options: Options): HashSet[string] =
let nimBin = satResult.nimResolved.getNimBin()
let nimBin = some(satResult.nimResolved.getNimBin())
for depInfo in getDepsPkgInfo(satResult, pkgInfo, options):
for path in depInfo.expandPaths(nimBin, options):
result.incl(path)
Expand All @@ -74,7 +74,7 @@ proc getPathsToBuildFor*(satResult: SATResult, pkgInfo: PackageInfo, recursive:
result.incl(path)
result.incl(pkgInfo.expandPaths(nimBin, options))

proc getPathsAllPkgs*(options: Options, nimBin: string): HashSet[string] =
proc getPathsAllPkgs*(options: Options, nimBin: Option[string]): HashSet[string] =
let satResult = options.satResult
for pkg in satResult.pkgs:
if pkg.basicInfo.name.isNim:
Expand All @@ -83,7 +83,7 @@ proc getPathsAllPkgs*(options: Options, nimBin: string): HashSet[string] =
result.incl(path)

proc buildFromDir*(pkgInfo: PackageInfo, paths: HashSet[string],
args: seq[string], options: Options, nimBin: string) =
args: seq[string], options: Options, nimBin: Option[string]) =
## Builds a package as specified by ``pkgInfo``.
# Handle pre-`build` hook.
let
Expand Down Expand Up @@ -184,7 +184,7 @@ proc buildFromDir*(pkgInfo: PackageInfo, paths: HashSet[string],
realDir / src.changeFileExt("nim")

let cmd = "$# $# --colors:$# --noNimblePath $# $# $#" % [
nimBin.quoteShell, pkgInfo.backend, if options.noColor: "off" else: "on", join(args, " "),
nimBin.get.quoteShell, pkgInfo.backend, if options.noColor: "off" else: "on", join(args, " "),
outputOpt, input.quoteShell]
try:
doCmd(cmd)
Expand Down Expand Up @@ -247,7 +247,7 @@ proc createBinSymlink*(pkgInfo: PackageInfo, options: Options) =
binariesInstalled.incl(
setupBinSymlink(symlinkDest, symlinkFilename, options))

proc buildPkg*(nimBin: string, pkgToBuild: PackageInfo, isRootInRootDir: bool, options: Options) {.instrument.} =
proc buildPkg*(nimBin: Option[string], pkgToBuild: PackageInfo, isRootInRootDir: bool, options: Options) {.instrument.} =
# let paths = getPathsToBuildFor(options.satResult, pkgToBuild, recursive = true, options)
let paths = getPathsAllPkgs(options, nimBin)
# echo "Paths ", paths
Expand Down
4 changes: 4 additions & 0 deletions src/nimblepkg/common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ type
PackageNotFoundError* = object of NimbleError
## Raised when a package cannot be found in any repository

NeedsNimBinError* = object of NimbleError
## Raised by the declarative parser when VM fallback is needed but nimBin is
## not yet resolved. Callers catch this and retry after bootstrap resolution.

## Same as quit(QuitSuccess) or quit(QuitFailure), but allows cleanup.
## Inheriting from `Defect` is workaround to avoid accidental catching of
## `NimbleQuit` by `CatchableError` handlers.
Expand Down
30 changes: 19 additions & 11 deletions src/nimblepkg/declarativeparser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -642,14 +642,15 @@ proc getPkgInfoMaybeInTempDir(pkgDir: string, options: Options, nimBin: string,
## Runs getPkgInfo, potentially in a temp directory copy.
## Only copies to temp dir when the package is in pkgcache AND has state-modifying ops.
## This prevents the VM parser from creating files/directories in pkgcache.
let nimBinOpt = some(nimBin)
if not isInPkgCache(pkgDir, options):
return getPkgInfoVm(pkgDir, options, nimBin)
return getPkgInfoVm(pkgDir, options, nimBinOpt)
if not fileHasStateModifyingOps(nimbleFile):
return getPkgInfoVm(pkgDir, options, nimBin)
return getPkgInfoVm(pkgDir, options, nimBinOpt)
let tempDir = getNimbleTempDir() / "vmparse_" & $epochTime().int
try:
copyDirRec(pkgDir, tempDir)
result = getPkgInfoVm(tempDir, options, nimBin)
result = getPkgInfoVm(tempDir, options, nimBinOpt)
# Update myPath to point back to original location
let nimbleFileName = result.myPath.extractFilename
result.myPath = pkgDir / nimbleFileName
Expand All @@ -661,16 +662,23 @@ proc getPkgInfoMaybeInTempDir(pkgDir: string, options: Options, nimBin: string,
except CatchableError:
discard # Ignore cleanup errors

proc toRequiresInfo*(pkgInfo: PackageInfo, options: Options, nimBin: string, nimbleFileInfo: Option[NimbleFileInfo] = none(NimbleFileInfo)): PackageInfo =
proc toRequiresInfo*(pkgInfo: PackageInfo, options: Options, nimBin: Option[string], nimbleFileInfo: Option[NimbleFileInfo] = none(NimbleFileInfo)): PackageInfo =
#For nim we only need the version. Since version is usually in the form of `version = $NimMajor & "." & $NimMinor & "." & $NimPatch
#we need to use the vm to get the version. Another option could be to use the binary and ask for the version
# echo "toRequiresInfo: ", $pkgInfo.basicInfo, $pkgInfo.requires
result = pkgInfo
# Helper: resolve nimBin from parameter, memoized bootstrap, or raise NeedsNimBinError
proc resolveNimBin(nimBin: Option[string], options: Options): string =
if nimBin.isSome: return nimBin.get
if options.satResult.bootstrapNim.nimResolved.pkg.isSome:
return options.satResult.bootstrapNim.nimResolved.getNimBin()
raise newNimbleError[NeedsNimBinError]("VM parser needed but no Nim binary available yet")

if pkgInfo.myPath.splitFile.ext == ".babel":
let babelWarning = &"Package {pkgInfo.basicInfo.name} is a babel package, skipping declarative parser"
if options.verbosity <= LowPriority:
displayWarning babelWarning
result = getPkgInfoMaybeInTempDir(pkgInfo.myPath.parentDir, options, nimBin, pkgInfo.myPath)
result = getPkgInfoMaybeInTempDir(pkgInfo.myPath.parentDir, options, resolveNimBin(nimBin, options), pkgInfo.myPath)
fillMetaData(result, result.getRealDir(), false, options)
if babelWarning notin result.declarativeParserErrors:
result.declarativeParserErrors.add(babelWarning)
Expand All @@ -684,13 +692,13 @@ proc toRequiresInfo*(pkgInfo: PackageInfo, options: Options, nimBin: string, nim
result.infoKind = pikRequires

if nimbleFileInfo.nestedRequires and options.action.typ != actionCheck: #When checking we want to fail on porpuse
assert nimBin != "", "Cant fallback to the vm parser as there is no nim bin."
let resolvedBin = resolveNimBin(nimBin, options)

if options.verbosity <= LowPriority:
for line in nimbleFileInfo.declarativeParserErrorLines:
displayWarning line

result = getPkgInfoMaybeInTempDir(result.myPath.parentDir, options, nimBin, result.myPath)
result = getPkgInfoMaybeInTempDir(result.myPath.parentDir, options, resolvedBin, result.myPath)
for line in nimbleFileInfo.declarativeParserErrorLines:
if line notin result.declarativeParserErrors:
result.declarativeParserErrors.add(line)
Expand Down Expand Up @@ -725,15 +733,15 @@ proc fillPkgBasicInfo(pkgInfo: var PackageInfo, nimbleFileInfo: NimbleFileInfo)
pkgInfo.basicInfo.version = newVersion nimbleFileInfo.version
pkgInfo.srcDir = nimbleFileInfo.srcDir

proc getNimPkgInfo*(dir: string, options: Options, nimBin: string): PackageInfo =
proc getNimPkgInfo*(dir: string, options: Options, nimBin: Option[string]): PackageInfo =
let nimbleFile = dir / "nim.nimble"
assert fileExists(nimbleFile), "Nim.nimble file not found in " & dir
let nimbleFileInfo = extractRequiresInfo(nimbleFile, options)
result = initPackageInfo()
fillPkgBasicInfo(result, nimbleFileInfo)
result = toRequiresInfo(result, options, nimBin, some nimbleFileInfo)

proc getPkgInfoFromDirWithDeclarativeParser(dir: string, options: Options, nimBin: string, shouldError: bool = true): PackageInfo =
proc getPkgInfoFromDirWithDeclarativeParser(dir: string, options: Options, nimBin: Option[string], shouldError: bool = true): PackageInfo =
let nimbleFile = findNimbleFile(dir, shouldError, options)
let nimbleFileInfo = extractRequiresInfo(nimbleFile, options)
result = initPackageInfo()
Expand Down Expand Up @@ -775,7 +783,7 @@ proc getMinimalInfoFromContent*(content: string, name: string, version: Version,

return some(pkgInfo)

proc getPkgInfo*(dir: string, options: Options, nimBin: string,
proc getPkgInfo*(dir: string, options: Options, nimBin: Option[string],
level: PackageInfoKind = pikFull,
forValidation = false, shouldError = true): PackageInfo =
## Unified entry point for package parsing. Tries declarative parser first,
Expand All @@ -788,7 +796,7 @@ proc getPkgInfo*(dir: string, options: Options, nimBin: string,
# which the declarative parser can't provide
return getPkgInfoVm(dir, options, nimBin, forValidation)

proc getMinimalInfo*(nimbleFile: string, options: Options, nimBin: string): PackageMinimalInfo =
proc getMinimalInfo*(nimbleFile: string, options: Options, nimBin: Option[string]): PackageMinimalInfo =
#TODO we can use the new getPkgInfo to get the minimal info and add the features to the packageinfo type so this whole function can be removed
#TODO we need to handle the url here as well.
# declarative parser is always used
Expand Down
26 changes: 13 additions & 13 deletions src/nimblepkg/developfile.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## files.

import sets, sequtils, os, strformat, tables, hashes, strutils, math,
std/jsonutils
std/jsonutils, std/options

import typetraits except distinctBase
import compat/json
Expand Down Expand Up @@ -159,7 +159,7 @@ proc developFileExists*(pkg: PackageInfo): bool =
## the directory of the package's `pkg` `.nimble` file or `false` otherwise.
pkg.getNimbleFilePath.developFileExists

proc validatePackage(pkgPath: Path, options: Options, nimBin: string):
proc validatePackage(pkgPath: Path, options: Options, nimBin: Option[string]):
tuple[pkgInfo: PackageInfo, error: ref CatchableError] =
## By given file system path `pkgPath`, determines whether it points to a
## valid Nimble package.
Expand Down Expand Up @@ -314,7 +314,7 @@ proc mergeFollowedDevFileData(lhs: var DevelopFileData, rhs: DevelopFileData,
errors.collidingNames)

proc load(cache: var DevelopCache, path: Path, dependentPkg: PackageInfo, options: Options,
silentIfFileNotExists, raiseOnValidationErrors, loadGlobalDeps: bool, nimBin: string):
silentIfFileNotExists, raiseOnValidationErrors, loadGlobalDeps: bool, nimBin: Option[string]):
DevelopFileData

template load(cache: var DevelopCache, dependentPkg: PackageInfo, args: varargs[untyped]):
Expand All @@ -328,7 +328,7 @@ template load(cache: var DevelopCache, dependentPkg: PackageInfo, args: varargs[
proc loadGlobalDependencies(result: var DevelopFileData,
collidingNames: var CollidingNames,
options: Options,
nimBin: string) =
nimBin: Option[string]) =
## Loads data from the `links` subdirectory in the Nimble cache. The links
## in the cache are treated as paths in a global develop file used when a
## local one does not exist.
Expand Down Expand Up @@ -356,7 +356,7 @@ proc loadGlobalDependencies(result: var DevelopFileData,
displayDetails(error.msg)

proc load(cache: var DevelopCache, path: Path, dependentPkg: PackageInfo, options: Options,
silentIfFileNotExists, raiseOnValidationErrors, loadGlobalDeps: bool, nimBin: string):
silentIfFileNotExists, raiseOnValidationErrors, loadGlobalDeps: bool, nimBin: Option[string]):
DevelopFileData =
## Loads data from a develop file at path `path`.
##
Expand Down Expand Up @@ -485,7 +485,7 @@ proc addDevelopPackage(data: var DevelopFileData, pkg: PackageInfo): bool =
return true

proc addDevelopPackage(data: var DevelopFileData, path: Path,
options: Options, nimBin: string): bool =
options: Options, nimBin: Option[string]): bool =
## Adds path `path` to some package directory to the develop file.
##
## Returns `true` if:
Expand Down Expand Up @@ -604,7 +604,7 @@ proc removeDevelopPackageByName(data: var DevelopFileData, name: string): bool =
return success

proc includeDevelopFile(cache: var DevelopCache, data: var DevelopFileData, path: Path,
options: Options, nimBin: string): bool =
options: Options, nimBin: Option[string]): bool =
## Includes a develop file at path `path` to the current project's develop
## file.
##
Expand Down Expand Up @@ -681,7 +681,7 @@ proc assertDevelopActionIsSet(options: Options) =
assert options.action.typ == actionDevelop,
"This procedure must be called only on develop command."

proc updateDevelopFile*(dependentPkg: PackageInfo, options: Options, nimBin: string): bool =
proc updateDevelopFile*(dependentPkg: PackageInfo, options: Options, nimBin: Option[string]): bool =
## Updates a dependent package `dependentPkg`'s develop file with an
## information from the Nimble's command line.
## - Adds newly installed develop packages.
Expand Down Expand Up @@ -728,7 +728,7 @@ proc updateDevelopFile*(dependentPkg: PackageInfo, options: Options, nimBin: str

return not hasError

proc processDevelopDependencies*(dependentPkg: PackageInfo, options: Options, nimBin: string):
proc processDevelopDependencies*(dependentPkg: PackageInfo, options: Options, nimBin: Option[string]):
seq[PackageInfo] =
## Returns a sequence with the develop mode dependencies of the `dependentPkg`
## and recursively all of their develop mode dependencies.
Expand All @@ -743,7 +743,7 @@ proc processDevelopDependencies*(dependentPkg: PackageInfo, options: Options, ni
# echo "SAT RESULT ", options.satResult.pkgs.mapIt(it.basicInfo.name)
# options.debugSATResult()

proc getDevelopDependencies*(dependentPkg: PackageInfo, options: Options, raiseOnValidationErrors = true, nimBin: string):
proc getDevelopDependencies*(dependentPkg: PackageInfo, options: Options, raiseOnValidationErrors = true, nimBin: Option[string]):
Table[string, ref PackageInfo] =
## Returns a table with a mapping between names and `PackageInfo`s of develop
## mode dependencies of package `dependentPkg` and recursively all of their
Expand Down Expand Up @@ -924,7 +924,7 @@ template addError(error: ValidationErrorKind) =

proc findValidationErrorsOfDevDepsWithLockFile*(
dependentPkg: PackageInfo, options: Options,
errors: var ValidationErrors, nimBin: string) =
errors: var ValidationErrors, nimBin: Option[string]) =
## Collects validation errors for the develop mode dependencies with the
## content of the lock file by getting in consideration the information from
## the sync file. In the case of discrepancy, gives a useful advice what have
Expand Down Expand Up @@ -961,7 +961,7 @@ proc validationErrors*(errors: ValidationErrors): ref NimbleError =
hint = errors.getValidationsErrorsHint)

proc validateDevelopFileAgainstLockFile(
dependentPkg: PackageInfo, options: Options, nimBin: string) =
dependentPkg: PackageInfo, options: Options, nimBin: Option[string]) =
## Does validation of the develop file dependencies against the data written
## in the lock file.

Expand All @@ -971,7 +971,7 @@ proc validateDevelopFileAgainstLockFile(
if errors.len > 0:
raise validationErrors(errors)

proc validateDevelopFile*(dependentPkg: PackageInfo, options: Options, nimBin: string) =
proc validateDevelopFile*(dependentPkg: PackageInfo, options: Options, nimBin: Option[string]) =
## The procedure is used in the Nimble's `check` command to transitively
## validate the contents of the develop files.

Expand Down
6 changes: 3 additions & 3 deletions src/nimblepkg/download.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# BSD License. Look at license.txt for more info.

import parseutils, os, strutils, tables, uri, strformat,
httpclient, sequtils, urls, chronos
httpclient, sequtils, urls, chronos, std/options

import compat/[json, osproc]
from algorithm import SortOrder, sorted
Expand Down Expand Up @@ -871,7 +871,7 @@ proc downloadPkg*(url: string, verRange: VersionRange,
options: Options,
downloadPath: string,
vcsRevision: Sha1Hash,
nimBin: string,
nimBin: Option[string],
validateRange = true): DownloadPkgResult =
## Downloads the repository as specified by ``url`` and ``verRange`` using
## the download method specified.
Expand Down Expand Up @@ -947,7 +947,7 @@ proc downloadPkgAsync*(url: string, verRange: VersionRange,
options: Options,
downloadPath: string,
vcsRevision: Sha1Hash,
nimBin: string,
nimBin: Option[string],
validateRange = true): Future[DownloadPkgResult] {.async.} =
## Async version of downloadPkg that uses async operations for cloning and downloading.
## Downloads the repository as specified by ``url`` and ``verRange`` using
Expand Down
8 changes: 4 additions & 4 deletions src/nimblepkg/install.nim
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ proc addReverseDeps*(satResult: SATResult, options: Options) =
# This can happen when packages are installed recursively during hooks
displayInfo("Skipping reverse dependency for package not found in solution: " & $dep, MediumPriority)

proc executeHook(nimBin: string, dir: string, options: var Options, action: ActionType, before: bool) =
proc executeHook(nimBin: Option[string], dir: string, options: var Options, action: ActionType, before: bool) =
let nimbleFile = findNimbleFile(dir, false, options).splitFile.name
let hook = VisitedHook(pkgName: nimbleFile, action: action, before: before)
if hook in options.visitedHooks:
Expand All @@ -71,7 +71,7 @@ proc executeHook(nimBin: string, dir: string, options: var Options, action: Acti
else:
raise nimbleError("Post-hook prevented further execution.")

proc packageExists(nimBin: string, pkgInfo: PackageInfo, options: Options):
proc packageExists(nimBin: Option[string], pkgInfo: PackageInfo, options: Options):
Option[PackageInfo] =
## Checks whether a package `pkgInfo` already exists in the Nimble cache. If a
## package already exists returns the `PackageInfo` of the package in the
Expand Down Expand Up @@ -136,7 +136,7 @@ proc copyInstallFiles(srcDir, destDir: string, pkgInfo: PackageInfo,
copied


proc installFromDirDownloadInfo(nimBin: string, downloadDir: string, url: string, pv: PkgTuple, options: var Options): PackageInfo {.instrument.} =
proc installFromDirDownloadInfo(nimBin: Option[string], downloadDir: string, url: string, pv: PkgTuple, options: var Options): PackageInfo {.instrument.} =
## Installs a package from a download directory (pkgcache).
## flow: pkgcache -> buildtemp (build) -> pkgs2 (install minimum)

Expand Down Expand Up @@ -337,7 +337,7 @@ proc getVersionRangeFoPkgToInstall(satResult: SATResult, name: string, ver: Vers
return parseVersionRange(specialVersion)
return ver.toVersionRange()

proc installPkgs*(satResult: var SATResult, options: var Options, nimBin: string) {.instrument.} =
proc installPkgs*(satResult: var SATResult, options: var Options, nimBin: Option[string]) {.instrument.} =
# options.debugSATResult("installPkgs")
#At this point the packages are already downloaded.
#We still need to install them aka copy them from the cache to the nimbleDir + run preInstall and postInstall scripts
Expand Down
Loading
Loading