Lower memory consumption

This commit is contained in:
Yuriy Glukhov 2017-08-07 17:22:47 +03:00
commit 06a94ba28f
4 changed files with 69 additions and 64 deletions

View file

@ -445,7 +445,7 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options,
createDir(pkgDestDir) createDir(pkgDestDir)
# Copy this package's files based on the preferences specified in PkgInfo. # Copy this package's files based on the preferences specified in PkgInfo.
var filesInstalled = initSet[string]() var filesInstalled = initSet[string]()
for file in getInstallFiles(realDir, pkgInfo, options): discard forEachInstallFile(realDir, pkgInfo, options) do(file: string) -> bool:
createDir(changeRoot(realDir, pkgDestDir, file.splitFile.dir)) createDir(changeRoot(realDir, pkgDestDir, file.splitFile.dir))
let dest = changeRoot(realDir, pkgDestDir, file) let dest = changeRoot(realDir, pkgDestDir, file)
filesInstalled.incl copyFileD(file, dest) filesInstalled.incl copyFileD(file, dest)

View file

@ -21,6 +21,7 @@ type
showHelp*: bool showHelp*: bool
showVersion*: bool showVersion*: bool
noColor*: bool noColor*: bool
disableValidation*: bool
ActionType* = enum ActionType* = enum
actionNil, actionRefresh, actionInit, actionDump, actionPublish, actionNil, actionRefresh, actionInit, actionDump, actionPublish,
@ -107,6 +108,9 @@ proc writeHelp*(quit=true) =
proc writeVersion*() = proc writeVersion*() =
echo("nimble v$# compiled at $# $#" % echo("nimble v$# compiled at $# $#" %
[nimbleVersion, CompileDate, CompileTime]) [nimbleVersion, CompileDate, CompileTime])
const gitVersion = staticExec("git rev-parse HEAD")
when gitVersion.len > 0:
echo "git hash: ", gitVersion
raise NimbleQuit(msg: "") raise NimbleQuit(msg: "")
proc parseActionType*(action: string): ActionType = proc parseActionType*(action: string): ActionType =
@ -252,6 +256,7 @@ proc parseFlag*(flag, val: string, result: var Options, kind = cmdLongOption) =
of "verbose": result.verbosity = LowPriority of "verbose": result.verbosity = LowPriority
of "debug": result.verbosity = DebugPriority of "debug": result.verbosity = DebugPriority
of "nocolor": result.noColor = true of "nocolor": result.noColor = true
of "disablevalidation": result.disableValidation = true
# Action-specific flags. # Action-specific flags.
else: else:
case result.action.typ case result.action.typ

View file

@ -430,30 +430,30 @@ proc checkInstallDir(pkgInfo: PackageInfo,
if thisDir[0] == '.': result = true if thisDir[0] == '.': result = true
if thisDir == "nimcache": result = true if thisDir == "nimcache": result = true
proc findWithExt(dir: string, pkgInfo: PackageInfo): seq[string] = proc forEachFileWithExt(dir: string, pkgInfo: PackageInfo,
## Returns the filenames of the files that should be copied. action: proc(f: string): bool): bool =
result = @[] ## Runs `action` for each filename of the files that should be copied.
## Stops if `action` returns `true`.
for kind, path in walkDir(dir): for kind, path in walkDir(dir):
if kind == pcDir: if kind == pcDir:
result.add findWithExt(path, pkgInfo) if forEachFileWithExt(path, pkgInfo, action): return true
else: else:
if path.splitFile.ext[1 .. ^1] in pkgInfo.installExt: if path.splitFile.ext[1 .. ^1] in pkgInfo.installExt:
result.add path if action(path): return true
proc getFilesInDir(dir: string): seq[string] = proc forEachFileInDir(dir: string, action: proc(f: string): bool): bool =
## Returns a list of paths to files inside the specified directory and any ## Runs `action` for each file in ``dir`` and any
## subdirectories that are in it. ## subdirectories that are in it. Stops if `action` returns `true`.
result = @[]
for kind, path in walkDir(dir): for kind, path in walkDir(dir):
if kind == pcDir: if kind == pcDir:
result.add getFilesInDir(path) if forEachFileInDir(path, action): return true
else: else:
result.add path if action(path): return true
proc getInstallFiles*(realDir: string, pkgInfo: PackageInfo, proc forEachInstallFile*(realDir: string, pkgInfo: PackageInfo,
options: Options): seq[string] = options: Options, action: proc(f: string): bool): bool =
## Returns a list of files within the ``realDir`` that should be installed. ## Runs `action` for each file within the ``realDir`` that should be installed.
result = @[] ## Stops if `action` returns `true`.
let whitelistMode = let whitelistMode =
pkgInfo.installDirs.len != 0 or pkgInfo.installDirs.len != 0 or
pkgInfo.installFiles.len != 0 or pkgInfo.installFiles.len != 0 or
@ -466,7 +466,7 @@ proc getInstallFiles*(realDir: string, pkgInfo: PackageInfo,
continue continue
else: else:
raise NimbleQuit(msg: "") raise NimbleQuit(msg: "")
result.add src if action(src): return true
for dir in pkgInfo.installDirs: for dir in pkgInfo.installDirs:
# TODO: Allow skipping files inside dirs? # TODO: Allow skipping files inside dirs?
@ -477,9 +477,9 @@ proc getInstallFiles*(realDir: string, pkgInfo: PackageInfo,
else: else:
raise NimbleQuit(msg: "") raise NimbleQuit(msg: "")
result.add getFilesInDir(src) if forEachFileInDir(src, action): return true
result.add findWithExt(realDir, pkgInfo) if forEachFileWithExt(realDir, pkgInfo, action): return true
else: else:
for kind, file in walkDir(realDir): for kind, file in walkDir(realDir):
if kind == pcDir: if kind == pcDir:
@ -487,13 +487,13 @@ proc getInstallFiles*(realDir: string, pkgInfo: PackageInfo,
if skip: continue if skip: continue
result.add getInstallFiles(file, pkgInfo, options) if forEachInstallFile(file, pkgInfo, options, action): return true
else: else:
let skip = pkgInfo.checkInstallFile(realDir, file) let skip = pkgInfo.checkInstallFile(realDir, file)
if skip: continue if skip: continue
result.add file if action(file): return true
when isMainModule: when isMainModule:
doAssert getNameVersion("/home/user/.nimble/libs/packagea-0.1") == doAssert getNameVersion("/home/user/.nimble/libs/packagea-0.1") ==

View file

@ -79,7 +79,8 @@ proc validatePackageStructure(pkgInfo: PackageInfo, options: Options) =
pkgInfo.name & "pkg" pkgInfo.name & "pkg"
else: else:
pkgInfo.name pkgInfo.name
for path in getInstallFiles(realDir, pkgInfo, options):
discard forEachInstallFile(realDir, pkgInfo, options) do(path: string) -> bool:
# Remove the root to leave only the package subdirectories. # Remove the root to leave only the package subdirectories.
# ~/package-0.1/package/utils.nim -> package/utils.nim. # ~/package-0.1/package/utils.nim -> package/utils.nim.
var trailPath = changeRoot(realDir, "", path) var trailPath = changeRoot(realDir, "", path)
@ -87,46 +88,44 @@ proc validatePackageStructure(pkgInfo: PackageInfo, options: Options) =
let (dir, file, ext) = trailPath.splitFile let (dir, file, ext) = trailPath.splitFile
# We're only interested in nim files, because only they can pollute our # We're only interested in nim files, because only they can pollute our
# namespace. # namespace.
if ext != (ExtSep & "nim"): if ext == (ExtSep & "nim"):
continue if dir.len == 0:
if file != pkgInfo.name:
if dir.len == 0: # A source file was found in the top level of srcDir that doesn't share
if file != pkgInfo.name: # a name with the package.
# A source file was found in the top level of srcDir that doesn't share let
# a name with the package. msg = ("Package '$1' has an incorrect structure. " &
let "The top level of the package source directory " &
msg = ("Package '$1' has an incorrect structure. " & "should contain at most one module, " &
"The top level of the package source directory " & "named '$2', but a file named '$3' was found. This " &
"should contain at most one module, " & "will be an error in the future.") %
"named '$2', but a file named '$3' was found. This " & [pkgInfo.name, pkgInfo.name & ext, file & ext]
"will be an error in the future.") % hint = ("If this is the primary source file in the package, " &
[pkgInfo.name, pkgInfo.name & ext, file & ext] "rename it to '$1'. If it's a source file required by " &
hint = ("If this is the primary source file in the package, " & "the main module, or if it is one of several " &
"rename it to '$1'. If it's a source file required by " & "modules exposed by '$4', then move it into a '$2' subdirectory. " &
"the main module, or if it is one of several " & "If it's a test file or otherwise not required " &
"modules exposed by '$4', then move it into a '$2' subdirectory. " & "to build the the package '$1', prevent its installation " &
"If it's a test file or otherwise not required " & "by adding `skipFiles = @[\"$3\"]` to the .nimble file. See " &
"to build the the package '$1', prevent its installation " & "https://github.com/nim-lang/nimble#libraries for more info.") %
"by adding `skipFiles = @[\"$3\"]` to the .nimble file. See " & [pkgInfo.name & ext, correctDir & DirSep, file & ext, pkgInfo.name]
"https://github.com/nim-lang/nimble#libraries for more info.") % raiseNewValidationError(msg, true, hint, true)
[pkgInfo.name & ext, correctDir & DirSep, file & ext, pkgInfo.name] else:
raiseNewValidationError(msg, true, hint, true) assert(not pkgInfo.isMinimal)
else: # On Windows `pkgInfo.bin` has a .exe extension, so we need to normalize.
assert(not pkgInfo.isMinimal) if not (dir.startsWith(correctDir & DirSep) or dir == correctDir):
# On Windows `pkgInfo.bin` has a .exe extension, so we need to normalize. let
if not (dir.startsWith(correctDir & DirSep) or dir == correctDir): msg = ("Package '$2' has an incorrect structure. " &
let "It should contain a single directory hierarchy " &
msg = ("Package '$2' has an incorrect structure. " & "for source files, named '$3', but file '$1' " &
"It should contain a single directory hierarchy " & "is in a directory named '$4' instead. " &
"for source files, named '$3', but file '$1' " & "This will be an error in the future.") %
"is in a directory named '$4' instead. " & [file & ext, pkgInfo.name, correctDir, dir]
"This will be an error in the future.") % hint = ("If '$1' contains source files for building '$2', rename it " &
[file & ext, pkgInfo.name, correctDir, dir] "to '$3'. Otherwise, prevent its installation " &
hint = ("If '$1' contains source files for building '$2', rename it " & "by adding `skipDirs = @[\"$1\"]` to the .nimble file.") %
"to '$3'. Otherwise, prevent its installation " & [dir, pkgInfo.name, correctDir]
"by adding `skipDirs = @[\"$1\"]` to the .nimble file.") % raiseNewValidationError(msg, true, hint, true)
[dir, pkgInfo.name, correctDir]
raiseNewValidationError(msg, true, hint, true)
proc validatePackageInfo(pkgInfo: PackageInfo, options: Options) = proc validatePackageInfo(pkgInfo: PackageInfo, options: Options) =
let path = pkgInfo.myPath let path = pkgInfo.myPath
@ -317,8 +316,9 @@ proc readPackageInfo(nf: NimbleFile, options: Options,
options.pkgInfoCache[nf] = result options.pkgInfoCache[nf] = result
# Validate the rest of the package info last. # Validate the rest of the package info last.
validateVersion(result.version) if not options.disableValidation:
validatePackageInfo(result, options) validateVersion(result.version)
validatePackageInfo(result, options)
proc getPkgInfoFromFile*(file: NimbleFile, options: Options): PackageInfo = proc getPkgInfoFromFile*(file: NimbleFile, options: Options): PackageInfo =
## Reads the specified .nimble file and returns its data as a PackageInfo ## Reads the specified .nimble file and returns its data as a PackageInfo