Skip to content

Commit b890189

Browse files
authored
Normalization (#1443)
* Normalizes requirements * normalize should also take alias into account * progress * Use original requirements for installing packages * Internally normalizes deps * [OK] should ignore features specified in `requires` when using the vmparser * adds urls to the packageToDependency table * removes comment * Stores the package version table in SATResult. Uses it to do a lookup fallback * temporary comments an "easy" to fix test * [OK] cannot remove package with develop reverse dependency * [OK] can uninstall * [OK] Forge alias is generated inside lockfile * Removes normalizedRequirements lookup table * Revert "Removes normalizedRequirements lookup table" * Reenables last test * Replaces direct comparisons with `cmpIgnoreCase`
1 parent eb6f725 commit b890189

File tree

7 files changed

+215
-98
lines changed

7 files changed

+215
-98
lines changed

src/nimble.nim

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2122,10 +2122,14 @@ proc lock(options: var Options) =
21222122
vcsRevision = getVcsRevision(pkgInfo.getRealDir())
21232123
except CatchableError:
21242124
discard
2125+
var lockUrl = pkgInfo.metaData.url
2126+
if lockUrl == "":
2127+
lockUrl = nimblesat.getUrlFromPkgName(solvedPkg.pkgName, options.satResult.pkgVersionTable, options)
2128+
21252129
lockDeps[noTask][pkgInfo.basicInfo.name] = LockFileDep(
21262130
version: solvedPkg.version,
21272131
vcsRevision: vcsRevision,
2128-
url: pkgInfo.metaData.url,
2132+
url: lockUrl,
21292133
downloadMethod: pkgInfo.metaData.downloadMethod,
21302134
dependencies: solvedPkg.requirements.mapIt(it.name),
21312135
checksums: Checksums(sha1: pkgInfo.basicInfo.checksum))
@@ -2662,6 +2666,15 @@ proc runVNext*(options: var Options) =
26622666
options.satResult = initSATResult(satNimSelection)
26632667
var rootPackage = downloadPkInfoForPv(pkg, options, doPrompt = true)
26642668
solvePkgs(rootPackage, options)
2669+
2670+
let rootSolvedPkg = SolvedPackage(
2671+
pkgName: rootPackage.basicInfo.name,
2672+
version: rootPackage.basicInfo.version,
2673+
requirements: rootPackage.requires,
2674+
deps: options.satResult.solvedPkgs.filterIt(it.pkgName.toLower != rootPackage.basicInfo.name.toLower)
2675+
)
2676+
options.satResult.solvedPkgs.add(rootSolvedPkg)
2677+
26652678
# echo "BEFORE INSTALL PKGS"
26662679
# options.debugSATResult()
26672680
options.satResult.installPkgs(options)

src/nimblepkg/declarativeparser.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,4 +469,5 @@ proc getPkgInfoFromDirWithDeclarativeParser*(dir: string, options: Options): Pac
469469
let nimbleFileInfo = extractRequiresInfo(nimbleFile)
470470
result = initPackageInfo()
471471
fillPkgBasicInfo(result, nimbleFileInfo)
472+
result.metadata = loadMetaData(result.getNimbleFileDir(), raiseIfNotFound = false, options)
472473
result = toRequiresInfo(result, options, some nimbleFileInfo)

src/nimblepkg/download.nim

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import parseutils, os, osproc, strutils, tables, uri, strformat,
77
from algorithm import SortOrder, sorted
88

99
import packageinfotypes, packageparser, version, tools, common, options, cli,
10-
sha1hashes, vcstools, displaymessages, packageinfo, config, declarativeparser
10+
sha1hashes, vcstools, displaymessages, packageinfo, config, declarativeparser, packagemetadatafile
1111

1212
type
1313
DownloadPkgResult* = tuple
@@ -523,6 +523,11 @@ proc downloadPkg*(url: string, verRange: VersionRange,
523523
(result.version, result.vcsRevision) = doDownload(
524524
modUrl, downloadDir, verRange, downMethod, options, vcsRevision)
525525

526+
var metaData = initPackageMetaData()
527+
metaData.url = modUrl
528+
metaData.vcsRevision = result.vcsRevision
529+
saveMetaData(metaData, result.dir)
530+
526531
var pkgInfo: PackageInfo
527532
if validateRange and verRange.kind notin {verSpecial, verAny} or not options.isLegacy:
528533
## Makes sure that the downloaded package's version satisfies the requested

src/nimblepkg/nimblesat.nim

Lines changed: 109 additions & 65 deletions
Large diffs are not rendered by default.

src/nimblepkg/packageinfotypes.nim

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,17 @@ type
116116
pkg*: Option[PackageInfo] #when none, we need to install it
117117
version*: Version
118118

119+
PackageMinimalInfo* = object
120+
name*: string
121+
version*: Version
122+
requires*: seq[PkgTuple]
123+
isRoot*: bool
124+
url*: string
125+
126+
PackageVersions* = object
127+
pkgName*: string
128+
versions*: seq[PackageMinimalInfo]
129+
119130
SATResult* = ref object
120131
rootPackage*: PackageInfo
121132
pkgsToInstall*: seq[(string, Version)] #Packages to install
@@ -129,6 +140,8 @@ type
129140
declarativeParseFailed*: bool
130141
declarativeParserErrorLines*: seq[string]
131142
nimResolved*: NimResolved
143+
normalizedRequirements*: Table[string, string] #normalized -> old. Some packages are not published as nimble packages, we keep the url for installation.
144+
pkgVersionTable*: Table[string, PackageVersions]
132145

133146
proc `==`*(a, b: SolvedPackage): bool =
134147
a.pkgName == b.pkgName and
@@ -157,4 +170,7 @@ proc getGloballyActiveFeatures*(): seq[string] =
157170
result.add(&"features.{pkgName}.{feature}")
158171

159172
proc initSATResult*(pass: SATPass): SATResult =
160-
SATResult(pkgsToInstall: @[], solvedPkgs: @[], output: "", pkgs: initHashSet[PackageInfo](), pass: pass, installedPkgs: @[], declarativeParseFailed: false, declarativeParserErrorLines: @[])
173+
SATResult(pkgsToInstall: @[], solvedPkgs: @[], output: "", pkgs: initHashSet[PackageInfo](),
174+
pass: pass, installedPkgs: @[], declarativeParseFailed: false, declarativeParserErrorLines: @[],
175+
normalizedRequirements: initTable[string, string]()
176+
)

src/nimblepkg/vnext.nim

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,46 +19,48 @@ import nimblesat, packageinfotypes, options, version, declarativeparser, package
1919

2020
proc debugSATResult*(options: Options) =
2121
# return
22+
let satResult = options.satResult
23+
let color = "\e[32m"
24+
let reset = "\e[0m"
2225
echo "=== DEBUG SAT RESULT ==="
2326
echo "Called from: ", getStackTrace()[^2]
24-
let satResult = options.satResult
2527
echo "--------------------------------"
26-
echo "Pass: ", satResult.pass
28+
echo color, "Pass: ", reset, satResult.pass
2729
if satResult.nimResolved.pkg.isSome:
28-
echo "Selected Nim: ", satResult.nimResolved.pkg.get.basicInfo.name, " ", satResult.nimResolved.version
30+
echo color, "Selected Nim: ", reset, satResult.nimResolved.pkg.get.basicInfo.name, " ", satResult.nimResolved.version
2931
else:
3032
echo "No Nim selected"
31-
echo "Declarative parser failed: ", satResult.declarativeParseFailed
33+
echo color, "Declarative parser failed: ", reset, satResult.declarativeParseFailed
3234
if satResult.declarativeParseFailed:
33-
echo "Declarative parser error lines: ", satResult.declarativeParserErrorLines
35+
echo color, "Declarative parser error lines: ", reset, satResult.declarativeParserErrorLines
3436

3537
if satResult.rootPackage.hasLockFile(options):
3638
echo "Root package has lock file: ", satResult.rootPackage.myPath.parentDir() / "nimble.lock"
3739
else:
3840
echo "Root package does not have lock file"
39-
echo "Root package: ", satResult.rootPackage.basicInfo.name, " ", satResult.rootPackage.basicInfo.version, " ", satResult.rootPackage.myPath
40-
echo "Root requires: ", satResult.rootPackage.requires.mapIt(it.name & " " & $it.ver)
41-
echo "Solved packages: ", satResult.solvedPkgs.mapIt(it.pkgName & " " & $it.version & " " & $it.deps.mapIt(it.pkgName))
42-
echo "Solution as Packages Info: ", satResult.pkgs.mapIt(it.basicInfo.name & " " & $it.basicInfo.version)
41+
echo color, "Root package: ", reset, satResult.rootPackage.basicInfo.name, " ", satResult.rootPackage.basicInfo.version, " ", satResult.rootPackage.myPath
42+
echo color, "Root requires: ", reset, satResult.rootPackage.requires.mapIt(it.name & " " & $it.ver)
43+
echo color, "Solved packages: ", reset, satResult.solvedPkgs.mapIt(it.pkgName & " " & $it.version & " " & $it.deps.mapIt(it.pkgName))
44+
echo color, "Solution as Packages Info: ", reset, satResult.pkgs.mapIt(it.basicInfo.name & " " & $it.basicInfo.version)
4345
if options.action.typ == actionUpgrade:
44-
echo "Upgrade versions: ", options.action.packages.mapIt(it.name & " " & $it.ver)
45-
echo "RESULT REVISIONS ", satResult.pkgs.mapIt(it.basicInfo.name & " " & $it.metaData.vcsRevision)
46-
echo "PKG LIST REVISIONS ", satResult.pkgList.mapIt(it.basicInfo.name & " " & $it.metaData.vcsRevision)
47-
echo "Packages to install: ", satResult.pkgsToInstall
48-
echo "Installed pkgs: ", satResult.pkgs.mapIt(it.basicInfo.name)
49-
echo "Build pkgs: ", satResult.buildPkgs.mapIt(it.basicInfo.name)
50-
echo "Packages url: ", satResult.pkgs.mapIt(it.metaData.url)
51-
echo "Package list: ", satResult.pkgList.mapIt(it.basicInfo.name)
52-
echo "PkgList path: ", satResult.pkgList.mapIt(it.myPath.parentDir)
53-
echo "Nimbledir: ", options.getNimbleDir()
54-
echo "Nimble Action: ", options.action.typ
46+
echo color, "Upgrade versions: ", reset, options.action.packages.mapIt(it.name & " " & $it.ver)
47+
echo color, "RESULT REVISIONS ", reset, satResult.pkgs.mapIt(it.basicInfo.name & " " & $it.metaData.vcsRevision)
48+
echo color, "PKG LIST REVISIONS ", reset, satResult.pkgList.mapIt(it.basicInfo.name & " " & $it.metaData.vcsRevision)
49+
echo color, "Packages to install: ", reset, satResult.pkgsToInstall
50+
echo color, "Installed pkgs: ", reset, satResult.pkgs.mapIt(it.basicInfo.name)
51+
echo color, "Build pkgs: ", reset, satResult.buildPkgs.mapIt(it.basicInfo.name)
52+
echo color, "Packages url: ", reset, satResult.pkgs.mapIt(it.metaData.url)
53+
echo color, "Package list: ", reset, satResult.pkgList.mapIt(it.basicInfo.name)
54+
echo color, "PkgList path: ", reset, satResult.pkgList.mapIt(it.myPath.parentDir)
55+
echo color, "Nimbledir: ", reset, options.getNimbleDir()
56+
echo color, "Nimble Action: ", reset, options.action.typ
5557
if options.action.typ == actionDevelop:
56-
echo "Path: ", options.action.packages.mapIt(it.name)
57-
echo "Dev actions: ", options.action.devActions.mapIt(it.actionType)
58-
echo "Dependencies: ", options.action.packages.mapIt(it.name)
58+
echo color, "Path: ", reset, options.action.packages.mapIt(it.name)
59+
echo color, "Dev actions: ", reset, options.action.devActions.mapIt(it.actionType)
60+
echo color, "Dependencies: ", reset, options.action.packages.mapIt(it.name)
5961
for devAction in options.action.devActions:
60-
echo "Dev action: ", devAction.actionType
61-
echo "Argument: ", devAction.argument
62+
echo color, "Dev action: ", reset, devAction.actionType
63+
echo color, "Argument: ", reset, devAction.argument
6264
echo "--------------------------------"
6365

6466
proc nameMatches(pkg: PackageInfo, pv: PkgTuple, options: Options): bool =
@@ -890,7 +892,23 @@ proc installPkgs*(satResult: var SATResult, options: Options) =
890892
installedPkgInfo = installFromDirDownloadInfo(satResult.rootPackage.getNimbleFileDir(), satResult.rootPackage.metaData.url, pv, options).toRequiresInfo(options)
891893
wasNewlyInstalled = oldPkg.isNone
892894
else:
893-
var dlInfo = getPackageDownloadInfo(pv, options, doPrompt = true)
895+
# echo "NORMALIZING REQUIREMENT: ", pv.name
896+
# echo "ROOT PACKAGE: ", satResult.rootPackage.basicInfo.name, " ", $satResult.rootPackage.basicInfo.version, " ", satResult.rootPackage.metaData.url
897+
# options.debugSATResult()
898+
if pv.name in options.satResult.normalizedRequirements:
899+
pv.name = options.satResult.normalizedRequirements[pv.name]
900+
901+
var dlInfo: PackageDownloadInfo
902+
try:
903+
dlInfo = getPackageDownloadInfo(pv, options, doPrompt = true)
904+
except CatchableError as e:
905+
#if we fail, we try to find the url for the req:
906+
let url = getUrlFromPkgName(pv.name, options.satResult.pkgVersionTable, options)
907+
if url != "":
908+
pv.name = url
909+
dlInfo = getPackageDownloadInfo(pv, options, doPrompt = true)
910+
else:
911+
raise e
894912
var downloadDir = dlInfo.downloadDir / dlInfo.subdir
895913
if not dirExists(dlInfo.downloadDir):
896914
#The reason for this is that the download cache may have a constrained version

tests/tsat.nim

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,33 @@ proc downloadAllPackages() {.used.} =
5252
let ignorePackages = ["rpgsheet",
5353
"arturo", "argument_parser", "murmur", "nimgame", "locale", "nim-locale",
5454
"nim-ao", "ao", "termbox", "linagl", "kwin", "yahooweather", "noaa",
55-
"nimwc",
55+
"nimwc", "pylib",
5656
"artemis"]
57-
let toDownload = importantPackages.filterIt(it notin ignorePackages)
58-
for pkg in toDownload:
57+
let startAt = 0#importantPackages.find("rbtree")
58+
let toDownload = importantPackages
59+
for i, pkg in toDownload:
60+
if i >= startAt or pkg in ignorePackages:
61+
continue
5962
echo "Downloading ", pkg
6063
downloadAndStorePackageVersionTableFor(pkg, options)
6164
echo "Done with ", pkg
6265

66+
proc fromJsonHook(pv: var PkgTuple, jsonNode: JsonNode, opt = Joptions()) =
67+
if jsonNode.kind == Jstring:
68+
pv = parseRequires(jsonNode.getStr())
69+
else:
70+
raise newException(ValueError, "Expected a string for PkgTuple found: " & $jsonNode.kind & " val: " & $jsonNode)
71+
72+
# proc fromJsonHook(pm: var PackageMinimalInfo, jsonNode: JsonNode, opt = Joptions()) =
73+
# pm.name = jsonNode["name"].getStr().toLower
74+
# pm.version = newVersion(jsonNode["version"].getStr())
75+
# for req in jsonNode["requires"]:
76+
# var pv: PkgTuple
77+
# fromJson(pv, req)
78+
# pm.requires.add((name: pv.name, ver: pv.ver))
79+
# pm.isRoot = jsonNode["isRoot"].getBool()
80+
81+
6382
suite "SAT solver":
6483
test "can solve simple SAT":
6584
let pkgVersionTable = {
@@ -181,7 +200,8 @@ suite "SAT solver":
181200
var pks = 0
182201
for jsonFile in walkPattern("packageMinimal/*.json"):
183202
inc pks
184-
var pkgVersionTable = parseJson(readFile(jsonFile)).to(Table[string, PackageVersions])
203+
var pkgVersionTable = parseJson(readFile(jsonFile)).jsonTo(Table[string, PackageVersions], Joptions(allowMissingKeys: true))
204+
pkgVersionTable.normalizeRequirements(initOptions())
185205
var graph = pkgVersionTable.toDepGraph()
186206
let form = toFormular(graph)
187207
var packages = initTable[string, Version]()

0 commit comments

Comments
 (0)