Skip to content

Commit ae8c091

Browse files
committed
decouples download from collecting packages. re-enables local fix to "issue nim-lang#1162"
1 parent 17e3f64 commit ae8c091

File tree

6 files changed

+94
-49
lines changed

6 files changed

+94
-49
lines changed

src/nimble.nim

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ proc checkSatisfied(options: Options, dependencies: seq[PackageInfo]) =
8181
[pkgInfo.basicInfo.name, $currentVer, $pkgsInPath[pkgInfo.basicInfo.name]])
8282
pkgsInPath[pkgInfo.basicInfo.name] = currentVer
8383

84+
import nimblepkg/nimblesat
85+
8486
proc processFreeDependencies(pkgInfo: PackageInfo,
8587
requirements: seq[PkgTuple],
8688
options: Options,
@@ -98,6 +100,31 @@ proc processFreeDependencies(pkgInfo: PackageInfo,
98100
pkgList = initPkgList(pkgInfo, options)
99101
#At this point we have all the installed packages
100102
#If we can solve them all here, we just do it and call it a day.
103+
#TODO refactor extract function
104+
var root = pkgInfo.getMinimalInfo()
105+
root.isRoot = true
106+
var pkgVersionTable = initTable[string, PackageVersions]()
107+
pkgVersionTable[root.name] = PackageVersions(pkgName: root.name, versions: @[root])
108+
109+
proc getPackageFromList(pv: PkgTuple, options: Options): Option[PackageMinimalInfo] =
110+
for pkg in pkgList:
111+
if pkg.basicInfo.name == pv.name and pkg.basicInfo.version.withinRange(pv.ver):
112+
return some pkg.getMinimalInfo()
113+
114+
collectAllVersions(pkgVersionTable, root, options, getPackageFromList)
115+
116+
var graph = pkgVersionTable.toDepGraph()
117+
let form = graph.toFormular()
118+
var packages = initTable[string, Version]()
119+
solve(graph, form, packages, listVersions= true)
120+
for pkg, ver in packages:
121+
for pkgInfo in pkgList:
122+
if pkgInfo.basicInfo.name == pkg and pkgInfo.basicInfo.version == ver:
123+
result.incl pkgInfo
124+
if result.len > 0: return result
125+
126+
127+
101128
#TODO REDO with the GraphDep (need to fill the minimal info from the installed packages first)
102129
# let allPackages = pkgList.mapIt(it.basicInfo)
103130
# if requirements.areRequirementsWithinPackages(allPackages):

src/nimblepkg/nimblesat.nim

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import sat/[sat, satvars]
22
import version, packageinfotypes, download, packageinfo, packageparser, options, sha1hashes
33

4-
import std/[tables, sequtils, algorithm, json, jsonutils, strutils]
4+
import std/[tables, sequtils, algorithm, json, jsonutils, strutils, options]
55

66

77
type
@@ -50,6 +50,7 @@ type
5050
reqs*: seq[Requirements]
5151
packageToDependency*: Table[string, int] #package.name -> index into nodes
5252
# reqsByDeps: Table[Requirements, int]
53+
GetPackageMinimal* = proc (pv: PkgTuple, options: Options): Option[PackageMinimalInfo]
5354

5455
proc getMinimalInfo*(pkg: PackageInfo): PackageMinimalInfo =
5556
result.name = pkg.basicInfo.name
@@ -80,7 +81,6 @@ proc getNimVersion*(pvs: seq[PkgTuple]): Version =
8081
else:
8182
#TODO range
8283
discard
83-
8484

8585
proc findDependencyForDep(g: DepGraph; dep: string): int {.inline.} =
8686
assert g.packageToDependency.hasKey(dep), dep & " not found"
@@ -237,4 +237,47 @@ proc solve*(g: var DepGraph; f: Form, packages: var Table[string, Version], list
237237
if listVersions:
238238
echo item.pkg, "[ ] " & toString item
239239
else:
240-
debugFormular(g, f, s)
240+
debugFormular(g, f, s)
241+
242+
243+
#TODO REVIEW this
244+
proc getDownloadInfo(pv: PkgTuple, options: Options,
245+
doPrompt: bool, ignorePackageCache = false): (DownloadMethod, string,
246+
Table[string, string]) =
247+
if pv.name.isURL:
248+
let (url, metadata) = getUrlData(pv.name)
249+
return (checkUrlType(url), url, metadata)
250+
else:
251+
var pkg = initPackage()
252+
if getPackage(pv.name, options, pkg, ignorePackageCache):
253+
let (url, metadata) = getUrlData(pkg.url)
254+
return (pkg.downloadMethod, url, metadata)
255+
256+
proc downloadPkInfoForPv*(pv: PkgTuple, options: Options): PackageInfo =
257+
let (meth, url, metadata) =
258+
getDownloadInfo(pv, options, doPrompt = true)
259+
let subdir = metadata.getOrDefault("subdir")
260+
let res =
261+
downloadPkg(url, pv.ver, meth, subdir, options,
262+
downloadPath = "", vcsRevision = notSetSha1Hash)
263+
return getPkgInfo(res.dir, options)
264+
265+
proc downloadMinimalPackage*(pv: PkgTuple, options: Options): Option[PackageMinimalInfo] =
266+
let pkgInfo = downloadPkInfoForPv(pv, options)
267+
some pkgInfo.getMinimalInfo()
268+
269+
proc collectAllVersions*(versions: var Table[string, PackageVersions], package: PackageMinimalInfo, options: Options, getMinimalPackage: GetPackageMinimal) =
270+
### Collects all the versions of a package and its dependencies and stores them in the versions table
271+
### A getMinimalPackage function is passed to get the package
272+
for pv in package.requires:
273+
# echo "Collecting versions for ", pv.name, " and Version: ", $pv.ver, " via ", package.name
274+
var pv = pv
275+
if not hasVersion(versions, pv): # Not found, meaning this package-version needs to be explored
276+
var pkgMin = getMinimalPackage(pv, options).get() #TODO elegantly fail here
277+
if pv.ver.kind == verSpecial:
278+
pkgMin.version = newVersion $pv.ver
279+
if not versions.hasKey(pv.name):
280+
versions[pv.name] = PackageVersions(pkgName: pv.name, versions: @[pkgMin])
281+
else:
282+
versions[pv.name].versions.addUnique pkgMin
283+
collectAllVersions(versions, pkgMin, options, getMinimalPackage)

tests/conflictingdepres/nimbledeps/pkgs2/b-0.1.4-16deae68214d584169ab5461ee97aee557e047fb/b.nimble

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
version = "0.1.4"
22
description = "c"
33
license = "MIT"
4+
author = "Juan M Gomez"
45

56
# Dependencies
67

tests/conflictingdepres/nimbledeps/pkgs2/c-0.1.0-16deae68214d584169ab5461ee97aee557e047fb/c.nimble

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
version = "0.1.0"
22
description = "c"
33
license = "MIT"
4+
author = "Juan M Gomez"
45

56
# Dependencies
67

tests/conflictingdepres/nimbledeps/pkgs2/c-0.2.1-16deae68214d584169ab5461ee97aee557e047fb/c.nimble

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
version = "0.2.1"
22
description = "c"
33
license = "MIT"
4+
author = "Juan M Gomez"
45

56
# Dependencies
67

tests/tsat.nim

Lines changed: 18 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,9 @@ import std/[tables, sequtils, algorithm, json, jsonutils, strutils]
66
import nimblepkg/[version, sha1hashes, packageinfotypes, nimblesat, options,
77
download, packageinfo, packageparser, config]
88
import nimble
9+
import times
910

1011

11-
proc downloadPkInfoForPv(pv: PkgTuple, options: Options): PackageInfo =
12-
let (meth, url, metadata) =
13-
getDownloadInfo(pv, options, doPrompt = true)
14-
let subdir = metadata.getOrDefault("subdir")
15-
let res =
16-
downloadPkg(url, pv.ver, meth, subdir, options,
17-
downloadPath = "", vcsRevision = notSetSha1Hash)
18-
return getPkgInfo(res.dir, options)
19-
2012
proc initFromJson*(dst: var PkgTuple, jsonNode: JsonNode, jsonPath: var string) =
2113
dst = parseRequires(jsonNode.str)
2214

@@ -29,21 +21,6 @@ proc toJsonHook*(src: PkgTuple): JsonNode =
2921
else:
3022
newJString(src.name & " " & ver)
3123

32-
proc collectAllVersions(versions: var Table[string, PackageVersions], package: PackageInfo, options: Options) =
33-
for pv in package.requires:
34-
# echo "Collecting versions for ", pv.name, " and Version: ", $pv.ver, " via ", package.name
35-
var pv = pv
36-
if not hasVersion(versions, pv): # Not found, meaning this package-version needs to be explored
37-
let pkgInfo = downloadPkInfoForPv(pv, options)
38-
var minimalInfo = pkgInfo.getMinimalInfo()
39-
if pv.ver.kind == verSpecial:
40-
echo "Special version ", pv, " but it was ", minimalInfo.version
41-
minimalInfo.version = newVersion $pv.ver
42-
if not versions.hasKey(pv.name):
43-
versions[pv.name] = PackageVersions(pkgName: pv.name, versions: @[minimalInfo])
44-
else:
45-
versions[pv.name].versions.addUnique minimalInfo
46-
collectAllVersions(versions, pkgInfo, options)
4724

4825

4926
#Test utils:
@@ -62,7 +39,7 @@ proc downloadAndStorePackageVersionTableFor(pkgName: string, options: Options) =
6239
var root = pkgInfo.getMinimalInfo()
6340
root.isRoot = true
6441
var pkgVersionTable = initTable[string, PackageVersions]()
65-
collectAllVersions(pkgVersionTable, pkgInfo, options)
42+
collectAllVersions(pkgVersionTable, root, options, downloadMinimalPackage)
6643
pkgVersionTable[pkgName] = PackageVersions(pkgName: pkgName, versions: @[root])
6744
let json = pkgVersionTable.toJson()
6845
writeFile(path, json.pretty())
@@ -166,22 +143,12 @@ suite "SAT solver":
166143
echo packages
167144
check packages.len == 0
168145
169-
# test "issue #1162":
170-
# cd "conflictingdepres":
171-
# #integration version of the test above
172-
# #TODO document folder structure setup so others know how to run similar tests
173-
# let (_, exitCode) = execNimble("install", "-l")
174-
# check exitCode == QuitSuccess
175-
176-
#[
177-
Next download all packages store it in a json and solve the dependencies one by one.
178-
179-
TODO
180-
- Create the table from already downloaded packages.
181-
- See if downloads can be cached and reused.
182-
- Review if when downloading a package we could just navigate it to get all versions without triggering another download
183-
184-
]#
146+
test "issue #1162":
147+
cd "conflictingdepres":
148+
#integration version of the test above
149+
#TODO document folder structure setup so others know how to run similar tests
150+
let (_, exitCode) = execNimble("install", "-l")
151+
check exitCode == QuitSuccess
185152
186153
# test "should be able to download a package and select its deps":
187154
@@ -198,7 +165,7 @@ suite "SAT solver":
198165
# var root = pkgInfo.getMinimalInfo()
199166
# root.isRoot = true
200167
# var pkgVersionTable = initTable[string, PackageVersions]()
201-
# collectAllVersions(pkgVersionTable, pkgInfo, options)
168+
# collectAllVersions(pkgVersionTable, root, options, downloadMinimalPackage)
202169
# pkgVersionTable[pkgName] = PackageVersions(pkgName: pkgName, versions: @[root])
203170

204171
# var graph = pkgVersionTable.toDepGraph()
@@ -209,14 +176,19 @@ suite "SAT solver":
209176

210177

211178
test "should be solve all nimble packages":
212-
downloadAllPackages() #uncomment this to download all packages. It's better to just keep them cached as it takes a while.
213-
179+
# downloadAllPackages() #uncomment this to download all packages. It's better to just keep them cached as it takes a while.
180+
let now = now()
181+
var pks = 0
214182
for jsonFile in walkPattern("packageMinimal/*.json"):
183+
inc pks
215184
var pkgVersionTable = parseJson(readFile(jsonFile)).to(Table[string, PackageVersions])
216185
var graph = pkgVersionTable.toDepGraph()
217186
let form = toFormular(graph)
218187
var packages = initTable[string, Version]()
219188
solve(graph, form, packages, listVersions= false)
220-
echo "Solved ", jsonFile.extractFilename, " with ", packages.len, " packages"
189+
# echo "Solved ", jsonFile.extractFilename, " with ", packages.len, " packages"
221190
222-
check packages.len > 0
191+
check packages.len > 0
192+
193+
let ends = now()
194+
echo "Solved ", pks, " packages in ", ends - now, " seconds"

0 commit comments

Comments
 (0)