From 09769143d8219589df33012e16fdf7c9980b1584 Mon Sep 17 00:00:00 2001 From: jmgomez Date: Sat, 17 Feb 2024 14:05:06 +0000 Subject: [PATCH 1/4] Adds the `paths` feature option #https://github.com/nim-lang/nimble/issues/1166 --- readme.markdown | 1 + src/nimble.nim | 21 +++++++++----- src/nimblepkg/nimscriptapi.nim | 3 +- src/nimblepkg/packageinfotypes.nim | 3 +- src/nimblepkg/packageparser.nim | 2 ++ tests/testdump/testdump.nimble | 1 + tests/tester.nim | 46 +++++++++++++++--------------- tests/tnimbledump.nim | 6 +++- 8 files changed, 50 insertions(+), 33 deletions(-) diff --git a/readme.markdown b/readme.markdown index 4dd419a7..86211b58 100644 --- a/readme.markdown +++ b/readme.markdown @@ -1103,6 +1103,7 @@ Nimble includes a ``publish`` command which does this for you automatically. listed in ``bin``. Possible values include: ``c``, ``cc``, ``cpp``, ``objc``, ``js``. **Default**: c +* ``paths`` - A list of relative paths that will be expanded on `nimble.paths` and the search paths options to the compiler. ### [Deps]/[Dependencies] diff --git a/src/nimble.nim b/src/nimble.nim index ee8c240b..e31d042e 100644 --- a/src/nimble.nim +++ b/src/nimble.nim @@ -164,7 +164,7 @@ proc processFreeDependencies(pkgInfo: PackageInfo, for i in reverseDependencies: addRevDep(options.nimbleData, i, pkgInfo) -proc buildFromDir(pkgInfo: PackageInfo, paths: HashSet[string], +proc buildFromDir(pkgInfo: PackageInfo, paths: HashSet[seq[string]], args: seq[string], options: Options) = ## Builds a package as specified by ``pkgInfo``. # Handle pre-`build` hook. @@ -186,7 +186,8 @@ proc buildFromDir(pkgInfo: PackageInfo, paths: HashSet[string], args = args args.add "-d:NimblePkgVersion=" & $pkgInfo.basicInfo.version for path in paths: - args.add("--path:" & path.quoteShell) + for p in path: + args.add("--path:" & p.quoteShell) if options.verbosity >= HighPriority: # Hide Nim hints by default args.add("--hints:off") @@ -336,7 +337,7 @@ proc processLockedDependencies(pkgInfo: PackageInfo, options: Options): HashSet[PackageInfo] proc getDependenciesPaths(pkgInfo: PackageInfo, options: Options): - HashSet[string] + HashSet[seq[string]] proc processAllDependencies(pkgInfo: PackageInfo, options: Options): HashSet[PackageInfo] = @@ -355,6 +356,10 @@ proc allDependencies(pkgInfo: PackageInfo, options: Options): HashSet[PackageInf for requires in pkgInfo.taskRequires.values: result.incl pkgInfo.processFreeDependencies(requires, options) +proc expandPaths(pkgInfo: PackageInfo, options: Options): seq[string] = + var pkgInfo = pkgInfo.toFullInfo(options) + return @[pkgInfo.getRealDir()] & pkgInfo.paths.mapIt(pkgInfo.getRealDir() & "/" & it) + proc installFromDir(dir: string, requestedVer: VersionRange, options: Options, url: string, first: bool, fromLockFile: bool, vcsRevision = notSetSha1Hash, @@ -439,7 +444,7 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options, # if the build fails then the old package will still be installed. if pkgInfo.bin.len > 0 and not isNimPackage: - let paths = result.deps.map(dep => dep.getRealDir()) + let paths = result.deps.map(dep => dep.expandPaths(options)) let flags = if options.action.typ in {actionInstall, actionPath, actionUninstall, actionDevelop}: options.action.passNimFlags else: @@ -780,9 +785,9 @@ proc install(packages: seq[PkgTuple], options: Options, raise proc getDependenciesPaths(pkgInfo: PackageInfo, options: Options): - HashSet[string] = + HashSet[seq[string]] = let deps = pkgInfo.processAllDependencies(options) - return deps.map(dep => dep.getRealDir()) + return deps.map(dep => dep.expandPaths(options)) proc build(pkgInfo: PackageInfo, options: Options) = ## Builds the package `pkgInfo`. @@ -1037,6 +1042,7 @@ proc dump(options: Options) = fn "binDir", p.binDir fn "srcDir", p.srcDir fn "backend", p.backend + fn "paths", p.paths if json: s = j.pretty echo s @@ -1416,7 +1422,8 @@ proc updatePathsFile(pkgInfo: PackageInfo, options: Options) = let paths = pkgInfo.getDependenciesPaths(options) var pathsFileContent = "--noNimblePath\n" for path in paths: - pathsFileContent &= &"--path:{path.escape}\n" + for p in path: + pathsFileContent &= &"--path:{p.escape}\n" var action = if fileExists(nimblePathsFileName): "updated" else: "generated" writeFile(nimblePathsFileName, pathsFileContent) displayInfo(&"\"{nimblePathsFileName}\" is {action}.") diff --git a/src/nimblepkg/nimscriptapi.nim b/src/nimblepkg/nimscriptapi.nim index 9cefad37..3f1700c7 100644 --- a/src/nimblepkg/nimscriptapi.nim +++ b/src/nimblepkg/nimscriptapi.nim @@ -26,7 +26,7 @@ var backend*: string ## The package's backend. skipDirs*, skipFiles*, skipExt*, installDirs*, installFiles*, - installExt*, bin*: seq[string] = @[] ## Nimble metadata. + installExt*, bin*, paths*: seq[string] = @[] ## Nimble metadata. requiresData*: seq[string] = @[] ## The package's dependencies. taskRequiresData*: Table[string, seq[string]] ## Task dependencies foreignDeps*: seq[string] = @[] ## The foreign dependencies. Only @@ -141,6 +141,7 @@ proc printPkgInfo(): string = printSeqIfLen installDirs printSeqIfLen installFiles printSeqIfLen installExt + printSeqIfLen paths printSeqIfLen bin printSeqIfLen "nimbleTasks", nimbleTasks.unzip()[0] printSeqIfLen beforeHooks diff --git a/src/nimblepkg/packageinfotypes.nim b/src/nimblepkg/packageinfotypes.nim index 8f2cf531..d1c0d3cb 100644 --- a/src/nimblepkg/packageinfotypes.nim +++ b/src/nimblepkg/packageinfotypes.nim @@ -69,7 +69,8 @@ type lockedDeps*: AllLockFileDeps metaData*: PackageMetaData isLink*: bool - + paths*: seq[string] + Package* = object ## Definition of package from packages.json. # Required fields in a package. name*: string diff --git a/src/nimblepkg/packageparser.nim b/src/nimblepkg/packageparser.nim index 3a8c6fca..acb10dd6 100644 --- a/src/nimblepkg/packageparser.nim +++ b/src/nimblepkg/packageparser.nim @@ -271,6 +271,8 @@ proc readPackageInfoFromNimble(path: string; result: var PackageInfo) = of "afterhooks": for i in ev.value.multiSplit: result.postHooks.incl(i.normalize) + of "paths": + result.paths.add(ev.value.multiSplit) else: raise nimbleError("Invalid field: " & ev.key) of "deps", "dependencies": diff --git a/tests/testdump/testdump.nimble b/tests/testdump/testdump.nimble index 630b52ac..3e388975 100644 --- a/tests/testdump/testdump.nimble +++ b/tests/testdump/testdump.nimble @@ -2,3 +2,4 @@ description = "Test package for dump command" version = "0.1.0" author = "nigredo-tori" license = "BSD" +paths = @["path"] \ No newline at end of file diff --git a/tests/tester.nim b/tests/tester.nim index 69cbde84..5f919ed4 100644 --- a/tests/tester.nim +++ b/tests/tester.nim @@ -1,33 +1,33 @@ # Copyright (C) Dominik Picheta. All rights reserved. # BSD License. Look at license.txt for more info. -import testscommon +# import testscommon # suits imports -import tinitcommand -import tcheckcommand -import tcleancommand -import tdevelopfeature -import tissues -import tlocaldeps -import tlockfile -import tmisctests -import tmoduletests -import tmultipkgs -import tnimbledump -import tnimblerefresh -import tnimbletasks -import tnimscript -import tshellenv -import tpathcommand -import treversedeps -import truncommand +# import tinitcommand +# import tcheckcommand +# import tcleancommand +# import tdevelopfeature +# import tissues +# import tlocaldeps +# import tlockfile +# import tmisctests +# import tmoduletests +# import tmultipkgs +# import tnimbledump +# import tnimblerefresh +# import tnimbletasks +# import tnimscript +# import tshellenv +# import tpathcommand +# import treversedeps +# import truncommand import tsetupcommand -import ttestcommand -import ttwobinaryversions -import tuninstall -import ttaskdeps +# import ttestcommand +# import ttwobinaryversions +# import tuninstall +# import ttaskdeps # nonim tests are very slow and (often) break the CI. diff --git a/tests/tnimbledump.nim b/tests/tnimbledump.nim index 9e1fab61..1c6513c6 100644 --- a/tests/tnimbledump.nim +++ b/tests/tnimbledump.nim @@ -54,6 +54,7 @@ bin: "" binDir: "" srcDir: "" backend: "c" +paths: "path" """ let (outp, exitCode) = execNimble("dump", "--ini", "testdump") check: exitCode == 0 @@ -77,7 +78,10 @@ backend: "c" "bin": [], "binDir": "", "srcDir": "", - "backend": "c" + "backend": "c", + "paths": [ + "path" + ] } """ let (outp, exitCode) = execNimble("dump", "--json", "testdump") From 4ed0fe26c10a3c5ebe2500463ac6856ea1864163 Mon Sep 17 00:00:00 2001 From: jmgomez Date: Sat, 17 Feb 2024 20:11:41 +0000 Subject: [PATCH 2/4] re-enable tests --- tests/tester.nim | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/tests/tester.nim b/tests/tester.nim index 5f919ed4..69cbde84 100644 --- a/tests/tester.nim +++ b/tests/tester.nim @@ -1,33 +1,33 @@ # Copyright (C) Dominik Picheta. All rights reserved. # BSD License. Look at license.txt for more info. -# import testscommon +import testscommon # suits imports -# import tinitcommand -# import tcheckcommand -# import tcleancommand -# import tdevelopfeature -# import tissues -# import tlocaldeps -# import tlockfile -# import tmisctests -# import tmoduletests -# import tmultipkgs -# import tnimbledump -# import tnimblerefresh -# import tnimbletasks -# import tnimscript -# import tshellenv -# import tpathcommand -# import treversedeps -# import truncommand +import tinitcommand +import tcheckcommand +import tcleancommand +import tdevelopfeature +import tissues +import tlocaldeps +import tlockfile +import tmisctests +import tmoduletests +import tmultipkgs +import tnimbledump +import tnimblerefresh +import tnimbletasks +import tnimscript +import tshellenv +import tpathcommand +import treversedeps +import truncommand import tsetupcommand -# import ttestcommand -# import ttwobinaryversions -# import tuninstall -# import ttaskdeps +import ttestcommand +import ttwobinaryversions +import tuninstall +import ttaskdeps # nonim tests are very slow and (often) break the CI. From 4933e0c8c2c753abb147c94f8e666b68685b5bf2 Mon Sep 17 00:00:00 2001 From: jmgomez Date: Tue, 20 Feb 2024 13:57:16 +0000 Subject: [PATCH 3/4] do not allow `paths` escape the package root dir --- src/nimble.nim | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/nimble.nim b/src/nimble.nim index e31d042e..54dcea78 100644 --- a/src/nimble.nim +++ b/src/nimble.nim @@ -356,10 +356,18 @@ proc allDependencies(pkgInfo: PackageInfo, options: Options): HashSet[PackageInf for requires in pkgInfo.taskRequires.values: result.incl pkgInfo.processFreeDependencies(requires, options) +proc isSubdirOf(subdir, baseDir: string): bool = + subDir.normalizedPath.startsWith(baseDir.normalizedPath) + proc expandPaths(pkgInfo: PackageInfo, options: Options): seq[string] = var pkgInfo = pkgInfo.toFullInfo(options) - return @[pkgInfo.getRealDir()] & pkgInfo.paths.mapIt(pkgInfo.getRealDir() & "/" & it) - + let baseDir = pkgInfo.getRealDir() + result = @[baseDir] + for relativePath in pkgInfo.paths: + let path = baseDir & "/" & relativePath + if path.isSubdirOf(baseDir): + result.add path + proc installFromDir(dir: string, requestedVer: VersionRange, options: Options, url: string, first: bool, fromLockFile: bool, vcsRevision = notSetSha1Hash, From 14334353d8d108ee5eb89cf22c9d103489740f67 Mon Sep 17 00:00:00 2001 From: jmgomez Date: Thu, 4 Apr 2024 10:20:19 +0100 Subject: [PATCH 4/4] improves `isSubdirOf` --- src/nimble.nim | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/nimble.nim b/src/nimble.nim index 54dcea78..6f2a564d 100644 --- a/src/nimble.nim +++ b/src/nimble.nim @@ -357,7 +357,14 @@ proc allDependencies(pkgInfo: PackageInfo, options: Options): HashSet[PackageInf result.incl pkgInfo.processFreeDependencies(requires, options) proc isSubdirOf(subdir, baseDir: string): bool = - subDir.normalizedPath.startsWith(baseDir.normalizedPath) + let + normalizedSubdir = subdir.normalizedPath + normalizedBaseDir = baseDir.normalizedPath & DirSep + + when defined(windows): + normalizedSubdir.toLower.startsWith(normalizedBaseDir.toLower) + else: + normalizedSubdir.startsWith(normalizedBaseDir) proc expandPaths(pkgInfo: PackageInfo, options: Options): seq[string] = var pkgInfo = pkgInfo.toFullInfo(options)