@@ -76,8 +76,8 @@ proc processFreeDependencies(pkgInfo: PackageInfo, options: Options):
7676 var pkgList {.global .}: seq [PackageInfo ] = @ []
7777 once: pkgList = initPkgList (pkgInfo, options)
7878
79- display (" Verifying" ,
80- " dependencies for $1@$2 " % [pkgInfo.basicInfo.name, $ pkgInfo.metaData.specialVersion ],
79+ display (" Verifying" , " dependencies for $1@$2 " %
80+ [pkgInfo.basicInfo.name, $ pkgInfo.basicInfo.version ],
8181 priority = HighPriority )
8282
8383 var reverseDependencies: seq [PackageBasicInfo ] = @ []
@@ -106,7 +106,15 @@ proc processFreeDependencies(pkgInfo: PackageInfo, options: Options):
106106 let (packages, installedPkg) = install (toInstall, options,
107107 doPrompt = false , first = false , fromLockFile = false )
108108
109- result .incl packages
109+ for pkg in packages:
110+ if result .contains pkg:
111+ # If the result already contains the newly tried to install package
112+ # we had to merge its special versions set into the set of the old
113+ # one.
114+ result [pkg].metaData.specialVersions.incl (
115+ pkg.metaData.specialVersions)
116+ else :
117+ result .incl pkg
110118
111119 pkg = installedPkg # For addRevDep
112120 fillMetaData (pkg, pkg.getRealDir (), false )
@@ -119,7 +127,7 @@ proc processFreeDependencies(pkgInfo: PackageInfo, options: Options):
119127 # Process the dependencies of this dependency.
120128 result .incl processFreeDependencies (pkg.toFullInfo (options), options)
121129 if not pkg.isLink:
122- reverseDependencies.add (( pkg.basicInfo.name, pkg.metaData.specialVersion, pkg.basicInfo.checksum) )
130+ reverseDependencies.add (pkg.basicInfo)
123131
124132 # Check if two packages of the same name (but different version) are listed
125133 # in the path.
@@ -260,27 +268,24 @@ proc removePackage(pkgInfo: PackageInfo, options: Options) =
260268 reinstallSymlinksForOlderVersion (pkgDestDir, options)
261269 options.nimbleData.removeRevDep (pkgInfo)
262270
263- proc packageExists (pkgInfo: PackageInfo , options: Options ): bool =
264- let pkgDestDir = pkgInfo.getPkgDest (options)
265- return fileExists (pkgDestDir / packageMetaDataFileName)
266-
267- proc promptOverwriteExistingPackage (pkgInfo: PackageInfo ,
268- options: Options ): bool =
269- let message = " $1@$2 already exists. Overwrite?" %
270- [pkgInfo.basicInfo.name, $ pkgInfo.metaData.specialVersion]
271- return options.prompt (message)
272-
273- proc removeOldPackage (pkgInfo: PackageInfo , options: Options ) =
271+ proc packageExists (pkgInfo: PackageInfo , options: Options ):
272+ Option [PackageInfo ] =
273+ # # Checks whether a package `pkgInfo` already exists in the Nimble cache. If a
274+ # # package already exists returns the `PackageInfo` of the package in the
275+ # # cache otherwise returns `none`. Raises a `NimbleError` in the case the
276+ # # package exists in the cache but it is not valid.
274277 let pkgDestDir = pkgInfo.getPkgDest (options)
275- let oldPkgInfo = getPkgInfo (pkgDestDir, options)
276- removePackage (oldPkgInfo, options)
277-
278- proc promptRemovePackageIfExists (pkgInfo: PackageInfo , options: Options ): bool =
279- if packageExists (pkgInfo, options):
280- if not promptOverwriteExistingPackage (pkgInfo, options):
281- return false
282- removeOldPackage (pkgInfo, options)
283- return true
278+ if not fileExists (pkgDestDir / packageMetaDataFileName):
279+ return none [PackageInfo ]()
280+ else :
281+ var oldPkgInfo = initPackageInfo ()
282+ try :
283+ oldPkgInfo = pkgDestDir.getPkgInfo (options)
284+ except CatchableError as error:
285+ raise nimbleError (& " The package inside \" { pkgDestDir} \" is invalid. " ,
286+ details = error)
287+ fillMetaData (oldPkgInfo, pkgDestDir, true )
288+ return some (oldPkgInfo)
284289
285290proc processLockedDependencies (pkgInfo: PackageInfo , options: Options ):
286291 HashSet [PackageInfo ]
@@ -329,9 +334,10 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options,
329334 var depsOptions = options
330335 depsOptions.depsOnly = false
331336
332- # Overwrite the version if the requested version is "#head" or similar.
333337 if requestedVer.kind == verSpecial:
334- pkgInfo.metaData.specialVersion = requestedVer.spe
338+ # Add a version alias to special versions set if requested version is a
339+ # special one.
340+ pkgInfo.metaData.specialVersions.incl requestedVer.spe
335341
336342 # Dependencies need to be processed before the creation of the pkg dir.
337343 if first and pkgInfo.lockedDeps.len > 0 :
@@ -343,10 +349,24 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options,
343349 result .pkg = pkgInfo
344350 return result
345351
346- display (" Installing" , " $1@$2" % [pkginfo.basicInfo.name, $ pkginfo.metaData.specialVersion],
347- priority = HighPriority )
352+ display (" Installing" , " $1@$2" %
353+ [pkginfo.basicInfo.name, $ pkginfo.basicInfo.version],
354+ priority = HighPriority )
348355
349- let isPackageAlreadyInCache = pkgInfo.packageExists (options)
356+ let oldPkg = pkgInfo.packageExists (options)
357+ if oldPkg.isSome:
358+ # In the case we already have the same package in the cache then only merge
359+ # the new package special versions to the old one.
360+ displayWarning (pkgAlreadyExistsInTheCacheMsg (pkgInfo))
361+ var oldPkg = oldPkg.get
362+ oldPkg.metaData.specialVersions.incl pkgInfo.metaData.specialVersions
363+ saveMetaData (oldPkg.metaData, oldPkg.getNimbleFileDir, changeRoots = false )
364+ if result .deps.contains oldPkg:
365+ result .deps[oldPkg].metaData.specialVersions.incl (
366+ oldPkg.metaData.specialVersions)
367+ result .deps.incl oldPkg
368+ result .pkg = oldPkg
369+ return
350370
351371 # Build before removing an existing package (if one exists). This way
352372 # if the build fails then the old package will still be installed.
@@ -361,8 +381,7 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options,
361381 try :
362382 buildFromDir (pkgInfo, paths, " -d:release" & flags, options)
363383 except CatchableError :
364- if not isPackageAlreadyInCache:
365- removeRevDep (options.nimbleData, pkgInfo)
384+ removeRevDep (options.nimbleData, pkgInfo)
366385 raise
367386
368387 let pkgDestDir = pkgInfo.getPkgDest (options)
@@ -374,9 +393,6 @@ proc installFromDir(dir: string, requestedVer: VersionRange, options: Options,
374393 # Don't copy artifacts if project local deps mode and "installing" the top
375394 # level package.
376395 if not (options.localdeps and options.isInstallingTopLevel (dir)):
377- if not promptRemovePackageIfExists (pkgInfo, options):
378- return
379-
380396 createDir (pkgDestDir)
381397 # Copy this package's files based on the preferences specified in PkgInfo.
382398 var filesInstalled: HashSet [string ]
@@ -797,18 +813,22 @@ proc list(options: Options) =
797813 echo (" " )
798814
799815proc listInstalled (options: Options ) =
800- var h: OrderedTable [string , seq [Version ]]
816+ type
817+ VersionChecksumTuple = tuple [version: Version , checksum: Sha1Hash ]
818+ var h: OrderedTable [string , seq [VersionChecksumTuple ]]
801819 let pkgs = getInstalledPkgsMin (options.getPkgsDir (), options)
802820 for pkg in pkgs:
803821 let
804822 pName = pkg.basicInfo.name
805- pVer = pkg.metaData.specialVersion
823+ pVersion = pkg.basicInfo.version
824+ pChecksum = pkg.basicInfo.checksum
806825 if not h.hasKey (pName): h[pName] = @ []
807826 var s = h[pName]
808- add (s, pVer )
827+ add (s, (pVersion, pChecksum) )
809828 h[pName] = s
810829
811- h.sort (proc (a, b: (string , seq [Version ])): int = cmpIgnoreCase (a[0 ], b[0 ]))
830+ h.sort (proc (a, b: (string , seq [VersionChecksumTuple ])): int =
831+ cmpIgnoreCase (a[0 ], b[0 ]))
812832 for k in keys (h):
813833 echo k & " [" & h [k].join (" , " ) & " ]"
814834
@@ -837,7 +857,7 @@ proc listPaths(options: Options) =
837857 # There may be several, list all available ones and sort by version.
838858 for pkg in pkgs:
839859 if name == pkg.basicInfo.name:
840- installed.add ((pkg.metaData.specialVersion , pkg.getRealDir))
860+ installed.add ((pkg.basicInfo.version , pkg.getRealDir))
841861
842862 if installed.len > 0 :
843863 sort (installed, cmp[VersionAndPath ], Descending )
@@ -1127,7 +1147,7 @@ proc uninstall(options: var Options) =
11271147 if len (revDeps - pkgsToDelete) > 0 :
11281148 let pkgs = revDeps.collectNames (true )
11291149 displayWarning (
1130- cannotUninstallPkgMsg (pkgTup.name, pkg.metaData.specialVersion , pkgs))
1150+ cannotUninstallPkgMsg (pkgTup.name, pkg.basicInfo.version , pkgs))
11311151 else :
11321152 pkgsToDelete.incl pkg.toRevDep
11331153
0 commit comments