aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common.nim20
-rw-r--r--src/feature/syncinstall.nim630
2 files changed, 333 insertions, 317 deletions
diff --git a/src/common.nim b/src/common.nim
index f2fb155..ead9b4b 100644
--- a/src/common.nim
+++ b/src/common.nim
@@ -39,20 +39,32 @@ type
repo: string
]
-proc checkAndRefresh*(color: bool, args: seq[Argument]): tuple[code: int, args: seq[Argument]] =
+proc checkAndRefreshUpgradeInternal(color: bool, upgrade: bool, args: seq[Argument]):
+ tuple[code: int, args: seq[Argument]] =
let refreshCount = args.count(%%%"refresh")
- if refreshCount > 0:
+ let upgradeCount = if upgrade: args.count(%%%"sysupgrade") else: 0
+ if refreshCount > 0 or upgradeCount > 0:
let code = pacmanRun(true, color, args
.keepOnlyOptions(commonOptions, transactionOptions, upgradeOptions) &
("S", none(string), ArgumentType.short) &
- ("y", none(string), ArgumentType.short).repeat(refreshCount))
+ ("y", none(string), ArgumentType.short).repeat(refreshCount) &
+ ("u", none(string), ArgumentType.short).repeat(upgradeCount))
let callArgs = args
- .filter(arg => not arg.matchOption(%%%"refresh"))
+ .filter(arg => not arg.matchOption(%%%"refresh") and
+ (upgradeCount == 0 or not arg.matchOption(%%%"sysupgrade")))
(code, callArgs)
else:
(0, args)
+template checkAndRefreshUpgrade*(color: bool, args: seq[Argument]):
+ tuple[code: int, args: seq[Argument]] =
+ checkAndRefreshUpgradeInternal(color, true, args)
+
+template checkAndRefresh*(color: bool, args: seq[Argument]):
+ tuple[code: int, args: seq[Argument]] =
+ checkAndRefreshUpgradeInternal(color, false, args)
+
proc noconfirm*(args: seq[Argument]): bool =
args
.filter(arg => arg.matchOption(%%%"confirm") or
diff --git a/src/feature/syncinstall.nim b/src/feature/syncinstall.nim
index 2471172..cd9240c 100644
--- a/src/feature/syncinstall.nim
+++ b/src/feature/syncinstall.nim
@@ -10,8 +10,7 @@ type
version: string,
groups: seq[string],
explicit: bool,
- foreign: bool,
- foreignUpgrade: bool
+ foreign: bool
]
SatisfyResult = tuple[
@@ -677,13 +676,11 @@ proc deduplicatePkgInfos(pkgInfos: seq[PackageInfo],
newSeq[PackageInfo]())
proc resolveDependencies(config: Config, pkgInfos: seq[PackageInfo],
- additionalPkgInfos: seq[PackageInfo], printMode: bool, directSome: bool,
+ additionalPkgInfos: seq[PackageInfo], printMode: bool,
nodepsCount: int, assumeInstalled: seq[PackageReference], noaur: bool):
(bool, Table[PackageReference, SatisfyResult],
seq[string], seq[seq[seq[PackageInfo]]], seq[string]) =
if pkgInfos.len > 0 and not printMode:
- if directSome:
- printColon(config.color, tr"Resolving build targets...")
echo(trp("resolving dependencies...\n"))
let (satisfied, unsatisfied, paths) = withAlpmConfig(config, true, handle, dbs, errors):
findDependencies(config, handle, dbs, pkgInfos, additionalPkgInfos,
@@ -834,191 +831,6 @@ proc removeBuildDependencies(config: Config, commonArgs: seq[Argument],
else:
0
-proc assumeInstalled(args: seq[Argument]): seq[PackageReference] =
- args
- .filter(a => a.matchOption(%%%"assume-installed"))
- .map(a => a.value.get.parsePackageReference(false))
- .filter(r => r.constraint.isNone or
- r.constraint.unsafeGet.operation == ConstraintOperation.eq)
-
-proc handleInstall(args: seq[Argument], config: Config, upgradeCount: int, nodepsCount: int,
- noconfirm: bool, explicits: HashSet[string], installed: seq[Installed],
- pacmanTargets: seq[FullPackageTarget[PackageInfo]], pkgInfos: seq[PackageInfo],
- additionalPkgInfos: seq[PackageInfo], keepNames: HashSet[string],
- initialPaths: seq[string], build: bool, noaur: bool): int =
- let workDirectPacmanTargets = if build: @[] else: pacmanTargets.map(`$`)
-
- let (directCode, directSome) = if workDirectPacmanTargets.len > 0 or upgradeCount > 0:
- (pacmanRun(true, config.color, args.filter(arg => not arg.isTarget) &
- workDirectPacmanTargets.map(t => (t, none(string), ArgumentType.target))), true)
- else:
- (0, false)
-
- if directCode != 0:
- clearPaths(initialPaths)
- directCode
- else:
- let commonArgs = args
- .keepOnlyOptions(commonOptions, transactionOptions, upgradeOptions)
- .filter(true, false, %%%"asdeps", %%%"asexplicit", %%%"needed")
-
- let assumeInstalled = args.assumeInstalled
- let skipDeps = assumeInstalled.len > 0 or nodepsCount > 0
-
- let removedNames = withAlpmConfig(config, true, handle, dbs, errors):
- for e in errors: printError(config.color, e)
- let newInstalledNames = lc[$p.name | (p <- handle.local.packages), string].toSet
- installed.map(i => i.name).filter(n => not (n in newInstalledNames)).toSet
-
- let (finalPkgInfos, finalAdditionalPkgInfos) = pkgInfos.foldl(block:
- let (pkgInfos, additionalPkgInfos) = a
- if b.name in removedNames:
- (pkgInfos, additionalPkgInfos & b)
- else:
- (pkgInfos & b, additionalPkgInfos),
- (newSeq[PackageInfo](), additionalPkgInfos))
-
- let (resolveSuccess, satisfied, additionalPacmanTargets, basePackages, dependencyPaths) =
- resolveDependencies(config, finalPkgInfos, finalAdditionalPkgInfos, false, directSome,
- nodepsCount, assumeInstalled, noaur)
- let paths = initialPaths & dependencyPaths
-
- let confirmAndResolveCode = if resolveSuccess:
- confirmViewAndImportKeys(config, basePackages, installed, noconfirm)
- else:
- 1
-
- if confirmAndResolveCode != 0:
- clearPaths(paths)
- confirmAndResolveCode
- else:
- let (_, initialUnrequired, initialUnrequiredWithoutOptional, _) =
- withAlpmConfig(config, false, handle, dbs, errors):
- queryUnrequired(handle, true, true, keepNames)
-
- let (additionalCode, additionalSome) = if additionalPacmanTargets.len > 0: (block:
- printColon(config.color, tr"Installing build dependencies...")
-
- (pacmanRun(true, config.color, commonArgs &
- ("S", none(string), ArgumentType.short) &
- ("needed", none(string), ArgumentType.long) &
- ("asdeps", none(string), ArgumentType.long) &
- additionalPacmanTargets.map(t => (t, none(string), ArgumentType.target))), true))
- else:
- (0, false)
-
- if additionalCode != 0:
- clearPaths(paths)
- additionalCode
- else:
- if basePackages.len > 0:
- # check all pacman dependencies were installed
- let unsatisfied = if nodepsCount <= 1:
- withAlpmConfig(config, true, handle, dbs, errors):
- for e in errors: printError(config.color, e)
-
- proc checkSatisfied(reference: PackageReference): bool =
- for pkg in handle.local.packages:
- if reference.isProvidedBy(pkg.toPackageReference, nodepsCount == 0):
- return true
- for provides in pkg.provides:
- if reference.isProvidedBy(provides.toPackageReference, nodepsCount == 0):
- return true
- return false
-
- lc[x.key | (x <- satisfied.namedPairs, not x.value.installed and
- x.value.buildPkgInfo.isNone and not x.key.checkSatisfied), PackageReference]
- else:
- @[]
-
- if unsatisfied.len > 0:
- clearPaths(paths)
- printUnsatisfied(config, satisfied, unsatisfied)
- 1
- else:
- proc installNext(index: int, installedAs: List[(string, string)],
- lastCode: int): (Table[string, string], int, int) =
- if index < basePackages.len and lastCode == 0:
- let (addInstalledAs, code) = installGroupFromSources(config, commonArgs,
- basePackages[index], explicits, skipDeps, noconfirm)
- installNext(index + 1, addInstalledAs ^& installedAs, code)
- else:
- (toSeq(installedAs.items).toTable, lastCode, index - 1)
-
- let (installedAs, code, index) = installNext(0, nil, 0)
- if code != 0 and index < basePackages.len - 1:
- printWarning(config.color, tr"installation aborted")
- clearPaths(paths)
-
- let newKeepNames = keepNames.map(n => installedAs.opt(n).get(n))
- let (_, finalUnrequired, finalUnrequiredWithoutOptional, _) =
- withAlpmConfig(config, false, handle, dbs, errors):
- queryUnrequired(handle, true, true, newKeepNames)
-
- let unrequired = finalUnrequired - initialUnrequired
- let unrequiredOptional = finalUnrequiredWithoutOptional -
- initialUnrequiredWithoutOptional - unrequired
-
- let removeCode = removeBuildDependencies(config,
- commonArgs, unrequired, unrequiredOptional)
- if removeCode != 0:
- removeCode
- else:
- code
- else:
- if not directSome and not additionalSome:
- echo(trp(" there is nothing to do\n"))
- clearPaths(paths)
- 0
-
-proc handlePrint(args: seq[Argument], config: Config, printFormat: string,
- upgradeCount: int, nodepsCount: int, pacmanTargets: seq[FullPackageTarget],
- pkgInfos: seq[PackageInfo], additionalPkgInfos: seq[PackageInfo], noaur: bool): int =
- let directPacmanTargets = pacmanTargets.map(`$`)
-
- let (resolveSuccess, _, additionalPacmanTargets, basePackages, _) =
- resolveDependencies(config, pkgInfos, additionalPkgInfos, true, false,
- nodepsCount, args.assumeInstalled, noaur)
-
- let code = if directPacmanTargets.len > 0 or
- additionalPacmanTargets.len > 0 or upgradeCount > 0: (block:
- let callPacmanTargets = if resolveSuccess:
- directPacmanTargets & additionalPacmanTargets
- else:
- directPacmanTargets
-
- # workaround for a strange nim bug, callPacmanTargets.map(...) breaks main.nim
- var callArguments = newSeq[Argument]()
- for t in callPacmanTargets:
- callArguments &= (t, none(string), ArgumentType.target)
-
- let code = pacmanRun(false, config.color,
- args.filter(arg => not arg.isTarget) & callArguments)
-
- if resolveSuccess:
- code
- else:
- 1)
- else:
- 0
-
- if code == 0:
- proc printWithFormat(pkgInfo: PackageInfo) =
- echo(printFormat
- .replace("%n", pkgInfo.name)
- .replace("%v", pkgInfo.version)
- .replace("%r", config.aurRepo)
- .replace("%s", "0")
- .replace("%l", pkgInfo.gitUrl))
-
- for installGroup in basePackages:
- for pkgInfos in installGroup:
- for pkgInfo in pkgInfos:
- printWithFormat(pkgInfo)
- 0
- else:
- code
-
proc printAllWarnings(config: Config, installed: seq[Installed], rpcInfos: seq[RpcPackageInfo],
pkgInfos: seq[PackageInfo], acceptedPkgInfos: seq[PackageInfo], upToDateNeeded: seq[Installed],
buildUpToDateNeeded: seq[(string, string)], localIsNewerSeq: seq[LocalIsNewer],
@@ -1028,7 +840,7 @@ proc printAllWarnings(config: Config, installed: seq[Installed], rpcInfos: seq[R
if upgradeCount > 0 and not noaur and config.printAurNotFound:
let rpcInfoTable = rpcInfos.map(i => (i.name, i)).toTable
for inst in installed:
- if inst.foreignUpgrade and not config.ignored(inst.name, inst.groups) and
+ if inst.foreign and not config.ignored(inst.name, inst.groups) and
not rpcInfoTable.hasKey(inst.name):
printWarning(config.color, tr"$# was not found in AUR" % [inst.name])
@@ -1221,170 +1033,362 @@ proc obtainPacmanBuildTargets(config: Config, pacmanTargets: seq[FullPackageTarg
(checkPacmanBuildPkgInfos, buildPkgInfos, buildUpToDateNeeded, buildPaths, obtainErrorMessages)
-proc findSyncTargetsWithInstalled(config: Config, targets: seq[PackageTarget], upgradeCount: int,
- noaur: bool, build: bool): (seq[SyncPackageTarget], seq[string], seq[Installed]) =
+proc obtainInstalledWithAur(config: Config,
+ rpcAurTargets: seq[FullPackageTarget[RpcPackageInfo]]): (seq[Installed], seq[string]) =
withAlpmConfig(config, true, handle, dbs, errors):
for e in errors: printError(config.color, e)
- let (syncTargets, checkAurNames) = findSyncTargets(handle, dbs, targets, config.aurRepo,
- not build, not build)
-
- proc checkReplaceable(name: string): bool =
- for db in dbs:
- for pkg in db.packages:
- for replaces in pkg.replaces:
- if replaces.name == name:
- return true
- return false
-
proc createInstalled(package: ptr AlpmPackage): Installed =
let foreign = dbs.filter(d => d[package.name] != nil).len == 0
- let foreignUpgrade = foreign and (upgradeCount == 0 or not checkReplaceable($package.name))
-
($package.name, $package.version, package.groupsSeq,
- package.reason == AlpmReason.explicit, foreign, foreignUpgrade)
+ package.reason == AlpmReason.explicit, foreign)
let installed = lc[createInstalled(p) | (p <- handle.local.packages), Installed]
+ let checkAurUpgradeNames = installed
+ .filter(i => i.foreign and (config.checkIgnored or not config.ignored(i.name, i.groups)))
+ .map(i => i.name)
- let checkAurNamesFull = if noaur:
- @[]
- elif upgradeCount > 0: (block:
- let foreignUpgrade = installed
- .filter(i => i.foreignUpgrade)
- .map(i => i.name)
- .toSet
-
- installed
- .filter(i => i.name in foreignUpgrade and
- (config.checkIgnored or not config.ignored(i.name, i.groups)))
- .map(i => i.name) & checkAurNames)
- else:
- checkAurNames
-
- (syncTargets, checkAurNamesFull, installed)
+ (installed, checkAurUpgradeNames)
-proc resolveBuildTargets(config: Config, targets: seq[PackageTarget],
+proc resolveBuildTargets(config: Config, syncTargets: seq[SyncPackageTarget],
+ rpcFullTargets: seq[FullPackageTarget[RpcPackageInfo]], printHeader: bool,
printMode: bool, upgradeCount: int, noconfirm: bool, needed: bool, noaur: bool, build: bool):
- (int, seq[Installed], HashSet[string], seq[FullPackageTarget[PackageInfo]],
- seq[PackageInfo], seq[PackageInfo], seq[string]) =
- template errorResult: untyped = (1, newSeq[Installed](),
- initSet[string](), newSeq[FullPackageTarget[PackageInfo]](),
+ (int, seq[Installed], HashSet[string], seq[PackageInfo], seq[PackageInfo], seq[string]) =
+ template errorResult: untyped = (1, newSeq[Installed](), initSet[string](),
newSeq[PackageInfo](), newSeq[PackageInfo](), newSeq[string]())
- let (syncTargets, checkAurNames, installed) =
- findSyncTargetsWithInstalled(config, targets, upgradeCount, noaur, build)
+ let (installed, checkAurUpgradeNames) = obtainInstalledWithAur(config, rpcFullTargets)
+ let checkAur = not noaur and checkAurUpgradeNames.len > 0 and upgradeCount > 0
- if not printMode and (checkAurNames.len > 0 or build):
+ if not printMode and (checkAur or build) and printHeader:
printColon(config.color, tr"Resolving build targets...")
- if checkAurNames.len > 0:
- echo(tr"checking AUR database...")
- let (rpcInfos, rerrors) = getRpcPackageInfos(checkAurNames,
- config.aurRepo, config.downloadTimeout)
- for e in rerrors: printError(config.color, e)
+ let upgradeRpcInfos = if checkAur: (block:
+ if not printMode:
+ echo(tr"checking AUR database for upgrades...")
+ let (upgradeRpcInfos, rerrors) = getRpcPackageInfos(checkAurUpgradeNames,
+ config.aurRepo, config.downloadTimeout)
+ for e in rerrors: printError(config.color, e)
+ upgradeRpcInfos)
+ else:
+ @[]
+
+ let installedTable = installed.map(i => (i.name, i)).toTable
+ let rpcAurTargets = rpcFullTargets.filter(t => t.isAurTargetFull(config.aurRepo))
- let rpcNotFoundTargets = filterNotFoundSyncTargets(syncTargets,
- rpcInfos, initTable[string, PackageReference](), config.aurRepo)
+ let targetRpcInfos = lc[x | (t <- rpcAurTargets, x <- t.pkgInfo), RpcPackageInfo]
+ let targetRpcInfoNames = targetRpcInfos.map(i => i.name).toSet
+ let rpcInfos = targetRpcInfos & upgradeRpcInfos.filter(i => not (i.name in targetRpcInfoNames))
- if rpcNotFoundTargets.len > 0:
- printSyncNotFound(config, rpcNotFoundTargets)
+ let (aurPkgInfos, additionalPkgInfos, aurPaths, upToDateNeeded, localIsNewerSeq, aperrors) =
+ obtainAurPackageInfos(config, rpcInfos, rpcAurTargets, installedTable,
+ printMode, needed, upgradeCount)
+ for e in aperrors: printError(config.color, e)
+
+ let upToDateNeededTable: Table[string, PackageReference] = upToDateNeeded.map(i => (i.name,
+ (i.name, none(string), some((ConstraintOperation.eq, i.version, false))))).toTable
+ let notFoundTargets = filterNotFoundSyncTargets(syncTargets,
+ aurPkgInfos, upToDateNeededTable, config.aurRepo)
+
+ if notFoundTargets.len > 0:
+ clearPaths(aurPaths)
+ printSyncNotFound(config, notFoundTargets)
errorResult
else:
- let installedTable = installed.map(i => (i.name, i)).toTable
- let rpcAurTargets = mapAurTargets(syncTargets, rpcInfos, config.aurRepo)
- .filter(t => t.isAurTargetFull(config.aurRepo))
+ let fullTargets = mapAurTargets(syncTargets
+ .filter(t => not (upToDateNeededTable.opt(t.reference.name)
+ .map(r => t.reference.isProvidedBy(r, true)).get(false))), aurPkgInfos, config.aurRepo)
+ let pacmanTargets = fullTargets.filter(t => not isAurTargetFull(t, config.aurRepo))
+ let aurTargets = fullTargets.filter(t => isAurTargetFull(t, config.aurRepo))
+
+ let (checkPacmanBuildPkgInfos, buildPkgInfos, buildUpToDateNeeded, buildPaths,
+ obtainBuildErrorMessages) = obtainPacmanBuildTargets(config, pacmanTargets, installedTable,
+ printMode, needed, build)
+
+ if checkPacmanBuildPkgInfos and buildPkgInfos.len < pacmanTargets.len:
+ clearPaths(buildPaths)
+ clearPaths(aurPaths)
+ for e in obtainBuildErrorMessages: printError(config.color, e)
+ errorResult
+ else:
+ let pkgInfos = (buildPkgInfos & aurPkgInfos)
+ .deduplicatePkgInfos(config, not printMode)
+ let targetNamesSet = (pacmanTargets & aurTargets).map(t => t.reference.name).toSet
+ let (finalPkgInfos, acceptedPkgInfos) = filterIgnoresAndConflicts(config, pkgInfos,
+ targetNamesSet, installedTable, printMode, noconfirm)
- let (aurPkgInfos, additionalPkgInfos, aurPaths, upToDateNeeded, localIsNewerSeq, aperrors) =
- obtainAurPackageInfos(config, rpcInfos, rpcAurTargets, installedTable,
- printMode, needed, upgradeCount)
- for e in aperrors: printError(config.color, e)
+ if not printMode:
+ printAllWarnings(config, installed, rpcInfos,
+ pkgInfos, acceptedPkgInfos, upToDateNeeded, buildUpToDateNeeded,
+ localIsNewerSeq, targetNamesSet, upgradeCount, noaur)
- let upToDateNeededTable: Table[string, PackageReference] = upToDateNeeded.map(i => (i.name,
- (i.name, none(string), some((ConstraintOperation.eq, i.version, false))))).toTable
- let notFoundTargets = filterNotFoundSyncTargets(syncTargets,
- aurPkgInfos, upToDateNeededTable, config.aurRepo)
+ (0, installed, targetNamesSet, finalPkgInfos, additionalPkgInfos, buildPaths & aurPaths)
- if notFoundTargets.len > 0:
- clearPaths(aurPaths)
- printSyncNotFound(config, notFoundTargets)
- errorResult
+proc assumeInstalled(args: seq[Argument]): seq[PackageReference] =
+ args
+ .filter(a => a.matchOption(%%%"assume-installed"))
+ .map(a => a.value.get.parsePackageReference(false))
+ .filter(r => r.constraint.isNone or
+ r.constraint.unsafeGet.operation == ConstraintOperation.eq)
+
+proc handleInstall(args: seq[Argument], config: Config, syncTargets: seq[SyncPackageTarget],
+ rpcFullTargets: seq[FullPackageTarget[RpcPackageInfo]], upgradeCount: int, nodepsCount: int,
+ wrapUpgrade: bool, noconfirm: bool, needed: bool, build: bool, noaur: bool): int =
+ let pacmanTargets = rpcFullTargets.filter(t => not isAurTargetFull(t, config.aurRepo))
+
+ let workDirectPacmanTargets = if build: @[] else: pacmanTargets.map(`$`)
+
+ # check for sysupgrade instead of upgradeCount since upgrade could be done before
+ # and then removed from the list of arguments
+ let (directCode, directSome) = if workDirectPacmanTargets.len > 0 or args.check(%%%"sysupgrade"):
+ (pacmanRun(true, config.color, args.filter(arg => not arg.isTarget) &
+ workDirectPacmanTargets.map(t => (t, none(string), ArgumentType.target))), true)
+ else:
+ (0, false)
+
+ if directCode != 0:
+ directCode
+ else:
+ let (resolveTargetsCode, installed, targetNamesSet, pkgInfos, additionalPkgInfos,
+ initialPaths) = resolveBuildTargets(config, syncTargets, rpcFullTargets,
+ directSome or wrapUpgrade, false, upgradeCount, noconfirm, needed, noaur, build)
+
+ if resolveTargetsCode != 0:
+ resolveTargetsCode
else:
- let fullTargets = mapAurTargets(syncTargets
- .filter(t => not (upToDateNeededTable.opt(t.reference.name)
- .map(r => t.reference.isProvidedBy(r, true)).get(false))), aurPkgInfos, config.aurRepo)
- let pacmanTargets = fullTargets.filter(t => not isAurTargetFull(t, config.aurRepo))
- let aurTargets = fullTargets.filter(t => isAurTargetFull(t, config.aurRepo))
-
- let (checkPacmanBuildPkgInfos, buildPkgInfos, buildUpToDateNeeded, buildPaths,
- obtainBuildErrorMessages) = obtainPacmanBuildTargets(config, pacmanTargets, installedTable,
- printMode, needed, build)
-
- if checkPacmanBuildPkgInfos and buildPkgInfos.len < pacmanTargets.len:
- # "--build" conflicts with "--sysupgrade", so it's ok to fail here
- clearPaths(buildPaths)
- clearPaths(aurPaths)
- for e in obtainBuildErrorMessages: printError(config.color, e)
- errorResult
+ let assumeInstalled = args.assumeInstalled
+ let skipDeps = assumeInstalled.len > 0 or nodepsCount > 0
+
+ let (resolveSuccess, satisfied, additionalPacmanTargets, basePackages, dependencyPaths) =
+ resolveDependencies(config, pkgInfos, additionalPkgInfos, false,
+ nodepsCount, assumeInstalled, noaur)
+
+ let confirmAndResolveCode = if resolveSuccess:
+ confirmViewAndImportKeys(config, basePackages, installed, noconfirm)
+ else:
+ 1
+
+ let paths = initialPaths & dependencyPaths
+ if confirmAndResolveCode != 0:
+ clearPaths(paths)
+ confirmAndResolveCode
else:
- let pkgInfos = (buildPkgInfos & aurPkgInfos)
- .deduplicatePkgInfos(config, not printMode)
- let targetNamesSet = (pacmanTargets & aurTargets).map(t => t.reference.name).toSet
- let (finalPkgInfos, acceptedPkgInfos) = filterIgnoresAndConflicts(config, pkgInfos,
- targetNamesSet, installedTable, printMode, noconfirm)
+ let explicitsNamesSet = installed.filter(i => i.explicit).map(i => i.name).toSet
+ let depsNamesSet = installed.filter(i => not i.explicit).map(i => i.name).toSet
+ let keepNames = explicitsNamesSet + depsNamesSet + targetNamesSet
- if not printMode:
- printAllWarnings(config, installed, rpcInfos,
- pkgInfos, acceptedPkgInfos, upToDateNeeded, buildUpToDateNeeded,
- localIsNewerSeq, targetNamesSet, upgradeCount, noaur)
+ let explicits = if args.check(%%%"asexplicit"):
+ targetNamesSet + explicitsNamesSet + depsNamesSet
+ elif args.check(%%%"asdeps"):
+ initSet[string]()
+ else:
+ explicitsNamesSet + (targetNamesSet - depsNamesSet)
+
+ let commonArgs = args
+ .keepOnlyOptions(commonOptions, transactionOptions, upgradeOptions)
+ .filter(true, false, %%%"asdeps", %%%"asexplicit", %%%"needed")
+
+ let (_, initialUnrequired, initialUnrequiredWithoutOptional, _) =
+ withAlpmConfig(config, false, handle, dbs, errors):
+ queryUnrequired(handle, true, true, keepNames)
+
+ let additionalCode = if additionalPacmanTargets.len > 0: (block:
+ printColon(config.color, tr"Installing build dependencies...")
+
+ pacmanRun(true, config.color, commonArgs &
+ ("S", none(string), ArgumentType.short) &
+ ("needed", none(string), ArgumentType.long) &
+ ("asdeps", none(string), ArgumentType.long) &
+ additionalPacmanTargets.map(t => (t, none(string), ArgumentType.target))))
+ else:
+ 0
+
+ if additionalCode != 0:
+ clearPaths(paths)
+ additionalCode
+ else:
+ if basePackages.len > 0:
+ # check all pacman dependencies were installed
+ let unsatisfied = if nodepsCount <= 1:
+ withAlpmConfig(config, true, handle, dbs, errors):
+ for e in errors: printError(config.color, e)
+
+ proc checkSatisfied(reference: PackageReference): bool =
+ for pkg in handle.local.packages:
+ if reference.isProvidedBy(pkg.toPackageReference, nodepsCount == 0):
+ return true
+ for provides in pkg.provides:
+ if reference.isProvidedBy(provides.toPackageReference, nodepsCount == 0):
+ return true
+ return false
+
+ lc[x.key | (x <- satisfied.namedPairs, not x.value.installed and
+ x.value.buildPkgInfo.isNone and not x.key.checkSatisfied), PackageReference]
+ else:
+ @[]
+
+ if unsatisfied.len > 0:
+ clearPaths(paths)
+ printUnsatisfied(config, satisfied, unsatisfied)
+ 1
+ else:
+ proc installNext(index: int, installedAs: List[(string, string)],
+ lastCode: int): (Table[string, string], int, int) =
+ if index < basePackages.len and lastCode == 0:
+ let (addInstalledAs, code) = installGroupFromSources(config, commonArgs,
+ basePackages[index], explicits, skipDeps, noconfirm)
+ installNext(index + 1, addInstalledAs ^& installedAs, code)
+ else:
+ (toSeq(installedAs.items).toTable, lastCode, index - 1)
+
+ let (installedAs, code, index) = installNext(0, nil, 0)
+ if code != 0 and index < basePackages.len - 1:
+ printWarning(config.color, tr"installation aborted")
+ clearPaths(paths)
+
+ let newKeepNames = keepNames.map(n => installedAs.opt(n).get(n))
+ let (_, finalUnrequired, finalUnrequiredWithoutOptional, _) =
+ withAlpmConfig(config, false, handle, dbs, errors):
+ queryUnrequired(handle, true, true, newKeepNames)
+
+ let unrequired = finalUnrequired - initialUnrequired
+ let unrequiredOptional = finalUnrequiredWithoutOptional -
+ initialUnrequiredWithoutOptional - unrequired
+
+ let removeCode = removeBuildDependencies(config,
+ commonArgs, unrequired, unrequiredOptional)
+ if removeCode != 0:
+ removeCode
+ else:
+ code
+ else:
+ let aurTargets = rpcFullTargets.filter(t => isAurTargetFull(t, config.aurRepo))
+ if (not noaur and (aurTargets.len > 0 or upgradeCount > 0)) or build:
+ echo(trp(" there is nothing to do\n"))
+ clearPaths(paths)
+ 0
+
+proc handlePrint(args: seq[Argument], config: Config, syncTargets: seq[SyncPackageTarget],
+ rpcFullTargets: seq[FullPackageTarget[RpcPackageInfo]], upgradeCount: int, nodepsCount: int,
+ needed: bool, build: bool, noaur: bool, printFormat: string): int =
+ let pacmanTargets = rpcFullTargets.filter(t => not isAurTargetFull(t, config.aurRepo))
+ let directPacmanTargets = pacmanTargets.map(`$`)
+
+ let (resolveTargetsCode, _, _, pkgInfos, additionalPkgInfos, _) = resolveBuildTargets(config,
+ syncTargets, rpcFullTargets, false, true, upgradeCount, true, needed, noaur, build)
+
+ if resolveTargetsCode != 0:
+ resolveTargetsCode
+ else:
+ let (resolveSuccess, _, additionalPacmanTargets, basePackages, _) =
+ resolveDependencies(config, pkgInfos, additionalPkgInfos, true,
+ nodepsCount, args.assumeInstalled, noaur)
+
+ let code = if directPacmanTargets.len > 0 or
+ additionalPacmanTargets.len > 0 or upgradeCount > 0: (block:
+ let callPacmanTargets = if resolveSuccess:
+ directPacmanTargets & additionalPacmanTargets
+ else:
+ directPacmanTargets
+
+ # workaround for a strange nim bug, callPacmanTargets.map(...) breaks main.nim
+ var callArguments = newSeq[Argument]()
+ for t in callPacmanTargets:
+ callArguments &= (t, none(string), ArgumentType.target)
+
+ let code = pacmanRun(false, config.color,
+ args.filter(arg => not arg.isTarget) & callArguments)
+
+ if resolveSuccess:
+ code
+ else:
+ 1)
+ else:
+ 0
+
+ if code == 0:
+ proc printWithFormat(pkgInfo: PackageInfo) =
+ echo(printFormat
+ .replace("%n", pkgInfo.name)
+ .replace("%v", pkgInfo.version)
+ .replace("%r", config.aurRepo)
+ .replace("%s", "0")
+ .replace("%l", pkgInfo.gitUrl))
+
+ for installGroup in basePackages:
+ for pkgInfos in installGroup:
+ for pkgInfo in pkgInfos:
+ printWithFormat(pkgInfo)
+ 0
+ else:
+ code
- (0, installed, targetNamesSet, pacmanTargets,
- finalPkgInfos, additionalPkgInfos, buildPaths & aurPaths)
+proc resolveAurTargets(config: Config, targets: seq[PackageTarget], printMode: bool, noaur: bool,
+ build: bool): (int, seq[SyncPackageTarget], seq[FullPackageTarget[RpcPackageInfo]]) =
+ let (syncTargets, checkAurTargetNames) = withAlpmConfig(config, true, handle, dbs, errors):
+ for e in errors: printError(config.color, e)
+ findSyncTargets(handle, dbs, targets, config.aurRepo, not build, not build)
+
+ let rpcInfos = if not noaur and checkAurTargetNames.len > 0: (block:
+ if not printMode:
+ printColon(config.color, tr"Resolving build targets...")
+ echo(tr"checking AUR database for targets...")
+
+ let (rpcInfos, rerrors) = getRpcPackageInfos(checkAurTargetNames,
+ config.aurRepo, config.downloadTimeout)
+ for e in rerrors: printError(config.color, e)
+ rpcInfos)
+ else:
+ @[]
+
+ let rpcNotFoundTargets = filterNotFoundSyncTargets(syncTargets,
+ rpcInfos, initTable[string, PackageReference](), config.aurRepo)
+
+ if rpcNotFoundTargets.len > 0:
+ printSyncNotFound(config, rpcNotFoundTargets)
+ (1, syncTargets, newSeq[FullPackageTarget[RpcPackageInfo]]())
+ else:
+ let rpcFullTargets = mapAurTargets(syncTargets, rpcInfos, config.aurRepo)
+ (0, syncTargets, rpcFullTargets)
proc handleSyncInstall*(args: seq[Argument], config: Config): int =
- let (refreshCode, callArgs) = checkAndRefresh(config.color, args)
- if refreshCode != 0:
- refreshCode
+ let printModeArg = args.check(%%%"print")
+ let printModeFormat = args.filter(arg => arg.matchOption(%%%"print-format")).optLast
+ let printFormat = if printModeArg or printModeFormat.isSome:
+ some(printModeFormat.map(arg => arg.value.get).get("%l"))
+ else:
+ none(string)
+
+ let targets = args.packageTargets(false)
+ let wrapUpgrade = targets.len == 0
+
+ let (refreshUpgradeCode, callArgs) = if wrapUpgrade and printFormat.isNone:
+ checkAndRefreshUpgrade(config.color, args)
+ else:
+ checkAndRefresh(config.color, args)
+
+ if refreshUpgradeCode != 0:
+ refreshUpgradeCode
else:
let upgradeCount = args.count(%%%"sysupgrade")
let nodepsCount = args.count(%%%"nodeps")
let needed = args.check(%%%"needed")
let noaur = args.check(%%%"noaur")
let build = args.check(%%%"build")
-
- let printModeArg = args.check(%%%"print")
- let printModeFormat = args.filter(arg => arg.matchOption(%%%"print-format")).optLast
- let printFormat = if printModeArg or printModeFormat.isSome:
- some(printModeFormat.map(arg => arg.value.get).get("%l"))
- else:
- none(string)
-
let noconfirm = args.noconfirm
- let targets = args.packageTargets(false)
withAur():
- let (code, installed, targetNamesSet, pacmanTargets,
- pkgInfos, additionalPkgInfos, paths) = resolveBuildTargets(config, targets,
- printFormat.isSome, upgradeCount, noconfirm, needed, noaur, build)
+ let (code, syncTargets, rpcFullTargets) = resolveAurTargets(config, targets,
+ printFormat.isSome, noaur, build)
let pacmanArgs = callArgs.filterExtensions(true, true,
commonOptions, transactionOptions, upgradeOptions, syncOptions)
+
if code != 0:
code
elif printFormat.isSome:
- handlePrint(pacmanArgs, config, printFormat.unsafeGet, upgradeCount, nodepsCount,
- pacmanTargets, pkgInfos, additionalPkgInfos, noaur)
+ handlePrint(pacmanArgs, config, syncTargets, rpcFullTargets,
+ upgradeCount, nodepsCount, needed, build, noaur, printFormat.unsafeGet)
else:
- let explicitsNamesSet = installed.filter(i => i.explicit).map(i => i.name).toSet
- let depsNamesSet = installed.filter(i => not i.explicit).map(i => i.name).toSet
- let keepNames = explicitsNamesSet + depsNamesSet + targetNamesSet
-
- let explicits = if args.check(%%%"asexplicit"):
- targetNamesSet + explicitsNamesSet + depsNamesSet
- elif args.check(%%%"asdeps"):
- initSet[string]()
- else:
- explicitsNamesSet + (targetNamesSet - depsNamesSet)
-
- handleInstall(pacmanArgs, config, upgradeCount, nodepsCount, noconfirm,
- explicits, installed, pacmanTargets, pkgInfos, additionalPkgInfos, keepNames,
- paths, build, noaur)
+ handleInstall(pacmanArgs, config, syncTargets, rpcFullTargets,
+ upgradeCount, nodepsCount, wrapUpgrade, noconfirm, needed, build, noaur)