Skip to content

Commit 81a1b62

Browse files
committed
Treat global develop dependencies as a develop file
Nimble link files created by `nimble develop --global` now are treated as a global develop file used only when no local develop file is found. This allows Nimble to understand them and to work with them seamlessly as with an ordinary develop file. Related to #948
1 parent 2bbcc16 commit 81a1b62

File tree

5 files changed

+90
-44
lines changed

5 files changed

+90
-44
lines changed

readme.markdown

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,8 @@ packages for which the develop command is executed.
293293
manipulated. It is useful for creating a free develop file which is not
294294
associated with any project intended for inclusion in some other develop file.
295295
* `-g, --global` - Creates an old style link file in the special `links`
296-
directory. It is read by Nim to be able to use global develop mode packages but
297-
it is ignored by Nimble.
296+
directory. It is read by Nim to be able to use global develop mode packages.
297+
Nimble uses it as a global develop file if a local one does not exist.
298298

299299
The options for manipulation of the develop files could be given only when
300300
executing `develop` command from some package's directory unless

src/nimble.nim

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,8 +1141,8 @@ proc developAllDependencies(pkgInfo: PackageInfo, options: var Options)
11411141
proc saveLinkFile(pkgInfo: PackageInfo, options: Options) =
11421142
let
11431143
pkgName = pkgInfo.basicInfo.name
1144-
pkgLinkDir = options.getPkgsLinksDir / pkgName & "-#head"
1145-
pkgLinkFilePath = pkgLinkDir / pkgName & ".nimble-link"
1144+
pkgLinkDir = options.getPkgsLinksDir / pkgName.getLinkFileDir
1145+
pkgLinkFilePath = pkgLinkDir / pkgName.getLinkFileName
11461146
pkgLinkFileContent = pkgInfo.myPath & "\n" & pkgInfo.getNimbleFileDir
11471147

11481148
if pkgLinkDir.dirExists and not options.prompt(
@@ -1449,10 +1449,9 @@ proc check(options: Options) =
14491449
try:
14501450
let currentDir = getCurrentDir()
14511451
let pkgInfo = getPkgInfo(currentDir, options, true)
1452-
if currentDir.developFileExists:
1453-
validateDevelopFile(pkgInfo, options)
1454-
let dependencies = pkgInfo.processAllDependencies(options).toSeq
1455-
validateDevelopDependenciesVersionRanges(pkgInfo, dependencies, options)
1452+
validateDevelopFile(pkgInfo, options)
1453+
let dependencies = pkgInfo.processAllDependencies(options).toSeq
1454+
validateDevelopDependenciesVersionRanges(pkgInfo, dependencies, options)
14561455
displaySuccess(&"The package \"{pkgInfo.basicInfo.name}\" is valid.")
14571456
except CatchableError as error:
14581457
displayError(error)

src/nimblepkg/common.nim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,9 @@ template cdNewDir*(dir: string, body: untyped) =
7878
createNewDir dir
7979
cd dir:
8080
body
81+
82+
proc getLinkFileDir*(pkgName: string): string =
83+
pkgName & "-#head"
84+
85+
proc getLinkFileName*(pkgName: string): string =
86+
pkgName & ".nimble-link"

src/nimblepkg/developfile.nim

Lines changed: 74 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ proc mergeFollowedDevFileData(lhs: var DevelopFileData, rhs: DevelopFileData,
307307
errors.collidingNames)
308308
309309
proc load(path: Path, dependentPkg: PackageInfo, options: Options,
310-
silentIfFileNotExists, raiseOnValidationErrors: bool):
310+
silentIfFileNotExists, raiseOnValidationErrors, loadGlobalDeps: bool):
311311
DevelopFileData
312312
313313
template load(dependentPkg: PackageInfo, args: varargs[untyped]):
@@ -318,8 +318,37 @@ template load(dependentPkg: PackageInfo, args: varargs[untyped]):
318318
dependentPkg.assertIsLoaded
319319
load(dependentPkg.getPkgDevFilePath, dependentPkg, args)
320320
321+
proc loadGlobalDependencies(result: var DevelopFileData,
322+
collidingNames: var CollidingNames,
323+
options: Options) =
324+
## Loads data from the `links` subdirectory in the Nimble cache. The links
325+
## in the cache are treated as paths in a global develop file used when a
326+
## local one does not exist.
327+
328+
for (kind, path) in walkDir(options.getPkgsLinksDir):
329+
if kind != pcDir:
330+
continue
331+
let (pkgName, _, _) = getNameVersionChecksum(path)
332+
let linkFilePath = path / pkgName.getLinkFileName
333+
if not linkFilePath.fileExists:
334+
displayWarning(&"Not found link file in \"{path}\".")
335+
continue
336+
let lines = linkFilePath.readFile.split("\n")
337+
if lines.len != 2:
338+
displayWarning(&"Invalid link file \"{linkFilePath}\".")
339+
continue
340+
let pkgPath = lines[1]
341+
let (pkgInfo, error) = validatePackage(pkgPath, options)
342+
if error == nil:
343+
let path = path.Path
344+
result.addPackage(pkgInfo, path, [path].toHashSet, collidingNames)
345+
else:
346+
displayWarning(
347+
&"Package \"{pkgName}\" at path \"{pkgPath}\" is invalid. Skipping it.")
348+
displayDetails(error.msg)
349+
321350
proc load(path: Path, dependentPkg: PackageInfo, options: Options,
322-
silentIfFileNotExists, raiseOnValidationErrors: bool):
351+
silentIfFileNotExists, raiseOnValidationErrors, loadGlobalDeps: bool):
323352
DevelopFileData =
324353
## Loads data from a develop file at path `path`.
325354
##
@@ -328,6 +357,10 @@ proc load(path: Path, dependentPkg: PackageInfo, options: Options,
328357
##
329358
## If `raiseOnValidationErrors` raises a `NimbleError` in the case some of the
330359
## contents of the develop file are invalid.
360+
##
361+
## If `loadGlobalDeps` then load the packages pointed by the link files in the
362+
## `links` directory in the Nimble cache instead of the once pointed by the
363+
## local develop file.
331364
##
332365
## Raises if the develop file or some of the included develop files:
333366
## - cannot be read.
@@ -343,9 +376,6 @@ proc load(path: Path, dependentPkg: PackageInfo, options: Options,
343376
result.path = path
344377
result.dependentPkg = dependentPkg
345378

346-
if silentIfFileNotExists and not path.fileExists:
347-
return
348-
349379
var
350380
errors {.global.}: ErrorsCollection
351381
visitedFiles {.global.}: HashSet[Path]
@@ -355,31 +385,38 @@ proc load(path: Path, dependentPkg: PackageInfo, options: Options,
355385
if dependentPkg.isLoaded:
356386
visitedPkgs.incl dependentPkg.getNimbleFileDir
357387

358-
try:
359-
fromJson(result.jsonData, parseFile(path), Joptions(allowExtraKeys: true))
360-
except ValueError as error:
361-
raise nimbleError(notAValidDevFileJsonMsg($path), details = error)
362-
363-
for depPath in result.jsonData.dependencies:
364-
let depPath = if depPath.isAbsolute:
365-
depPath.normalizedPath else: (path.splitFile.dir / depPath).normalizedPath
366-
let (pkgInfo, error) = validatePackage(depPath, options)
367-
if error == nil:
368-
result.addPackage(pkgInfo, path, [path].toHashSet, errors.collidingNames)
369-
else:
370-
errors.invalidPackages[depPath] = error
388+
if loadGlobalDeps:
389+
loadGlobalDependencies(result, errors.collidingNames, options)
390+
else:
391+
if silentIfFileNotExists and not path.fileExists:
392+
return
371393

372-
for inclPath in result.jsonData.includes:
373-
let inclPath = inclPath.normalizedPath
374-
if visitedFiles.contains(inclPath):
375-
continue
376-
var inclDevFileData = initDevelopFileData()
377394
try:
378-
inclDevFileData = load(inclPath, initPackageInfo(), options, false, false)
379-
except CatchableError as error:
380-
errors.invalidIncludeFiles[path] = error
381-
continue
382-
result.mergeIncludedDevFileData(inclDevFileData, errors)
395+
fromJson(result.jsonData, parseFile(path), Joptions(allowExtraKeys: true))
396+
except ValueError as error:
397+
raise nimbleError(notAValidDevFileJsonMsg($path), details = error)
398+
399+
for depPath in result.jsonData.dependencies:
400+
let depPath = if depPath.isAbsolute:
401+
depPath.normalizedPath else: (path.splitFile.dir / depPath).normalizedPath
402+
let (pkgInfo, error) = validatePackage(depPath, options)
403+
if error == nil:
404+
result.addPackage(pkgInfo, path, [path].toHashSet, errors.collidingNames)
405+
else:
406+
errors.invalidPackages[depPath] = error
407+
408+
for inclPath in result.jsonData.includes:
409+
let inclPath = inclPath.normalizedPath
410+
if visitedFiles.contains(inclPath):
411+
continue
412+
var inclDevFileData = initDevelopFileData()
413+
try:
414+
inclDevFileData = load(
415+
inclPath, initPackageInfo(), options, false, false, false)
416+
except CatchableError as error:
417+
errors.invalidIncludeFiles[path] = error
418+
continue
419+
result.mergeIncludedDevFileData(inclDevFileData, errors)
383420

384421
if result.dependentPkg.isLoaded and path.splitPath.tail == developFileName:
385422
# If this is a package develop file, but not a free one, for each of the
@@ -390,7 +427,7 @@ proc load(path: Path, dependentPkg: PackageInfo, options: Options,
390427
continue
391428
var followedPkgDevFileData = initDevelopFileData()
392429
try:
393-
followedPkgDevFileData = load(pkg[], options, true, false)
430+
followedPkgDevFileData = load(pkg[], options, true, false, false)
394431
except:
395432
# The errors will be accumulated in `errors` global variable and
396433
# reported by the `load` call which initiated the recursive process.
@@ -580,7 +617,7 @@ proc includeDevelopFile(data: var DevelopFileData, path: Path,
580617
581618
var inclFileData = initDevelopFileData()
582619
try:
583-
inclFileData = load(path, initPackageInfo(), options, false, true)
620+
inclFileData = load(path, initPackageInfo(), options, false, true, false)
584621
except CatchableError as error:
585622
displayError(failedToLoadFileMsg($path))
586623
displayDetails(error)
@@ -660,7 +697,7 @@ proc updateDevelopFile*(dependentPkg: PackageInfo, options: Options): bool =
660697
var
661698
hasError = false
662699
hasSuccessfulRemoves = false
663-
data = load(developFile, dependentPkg, options, true, true)
700+
data = load(developFile, dependentPkg, options, true, true, false)
664701
665702
defer:
666703
let writeEmpty = hasSuccessfulRemoves or
@@ -691,7 +728,8 @@ proc processDevelopDependencies*(dependentPkg: PackageInfo, options: Options):
691728
## Returns a sequence with the develop mode dependencies of the `dependentPkg`
692729
## and recursively all of their develop mode dependencies.
693730
694-
let data = load(dependentPkg, options, true, true)
731+
let loadGlobalDeps = not dependentPkg.getPkgDevFilePath.fileExists
732+
let data = load(dependentPkg, options, true, true, loadGlobalDeps)
695733
result = newSeqOfCap[PackageInfo](data.nameToPkg.len)
696734
for _, pkg in data.nameToPkg:
697735
result.add pkg[]
@@ -702,7 +740,8 @@ proc getDevelopDependencies*(dependentPkg: PackageInfo, options: Options):
702740
## mode dependencies of package `dependentPkg` and recursively all of their
703741
## develop mode dependencies.
704742
705-
let data = load(dependentPkg, options, true, true)
743+
let loadGlobalDeps = not dependentPkg.getPkgDevFilePath.fileExists
744+
let data = load(dependentPkg, options, true, true, loadGlobalDeps)
706745
return data.nameToPkg
707746
708747
type
@@ -908,6 +947,7 @@ proc validateDevelopFile*(dependentPkg: PackageInfo, options: Options) =
908947
## The procedure is used in the Nimble's `check` command to transitively
909948
## validate the contents of the develop files.
910949
911-
discard load(dependentPkg, options, true, true)
950+
let loadGlobalDeps = not dependentPkg.getPkgDevFilePath.fileExists
951+
discard load(dependentPkg, options, true, true, loadGlobalDeps)
912952
if dependentPkg.areLockedDepsLoaded:
913953
validateDevelopFileAgainstLockFile(dependentPkg, options)

src/nimblepkg/options.nim

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,9 @@ Commands:
133133
specified and executed in package's directory.
134134
[-g, --global] Creates an old style link file in the special
135135
`links` directory. It is read by Nim to be
136-
able to use global develop mode packages but
137-
it is ignored by Nimble.
136+
able to use global develop mode packages.
137+
Nimble uses it as a global develop file if a
138+
local one does not exist.
138139
check Verifies the validity of a package in the
139140
current working directory.
140141
init [pkgname] Initializes a new Nimble project in the

0 commit comments

Comments
 (0)