From 75b2f60bf15a9d49859b262a47da30ec70614a5e Mon Sep 17 00:00:00 2001 From: kitsunyan Date: Sat, 17 Mar 2018 23:55:48 +0300 Subject: Check conflicting targets before building --- src/common.nim | 12 ------------ src/feature/localquery.nim | 8 ++++---- src/feature/syncinstall.nim | 34 ++++++++++++++++++++++++---------- src/package.nim | 18 ++++++++++++++++++ 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/src/common.nim b/src/common.nim index 0dc73f3..23ef7f3 100644 --- a/src/common.nim +++ b/src/common.nim @@ -25,18 +25,6 @@ type FullPackageTarget*[T] = object of SyncPackageTarget pkgInfo*: Option[T] -proc toPackageReference*(dependency: ptr AlpmDependency): PackageReference = - let op = case dependency.depmod: - of AlpmDepMod.eq: some(ConstraintOperation.eq) - of AlpmDepMod.ge: some(ConstraintOperation.ge) - of AlpmDepMod.le: some(ConstraintOperation.le) - of AlpmDepMod.gt: some(ConstraintOperation.gt) - of AlpmDepMod.lt: some(ConstraintOperation.lt) - else: none(ConstraintOperation) - - let description = if dependency.desc != nil: some($dependency.desc) else: none(string) - ($dependency.name, description, op.map(o => (o, $dependency.version))) - proc checkAndRefresh*(color: bool, args: seq[Argument]): tuple[code: int, args: seq[Argument]] = let refreshCount = args.count((some("y"), "refresh")) if refreshCount > 0: diff --git a/src/feature/localquery.nim b/src/feature/localquery.nim index b07ec98..9dfaa05 100644 --- a/src/feature/localquery.nim +++ b/src/feature/localquery.nim @@ -1,6 +1,6 @@ import algorithm, future, options, sequtils, sets, strutils, tables, - "../args", "../common", "../config", "../format", "../package", "../pacman", "../utils", + "../args", "../config", "../format", "../package", "../pacman", "../utils", "../wrapper/alpm" proc handleQueryOrphans*(args: seq[Argument], config: Config): int = @@ -22,11 +22,11 @@ proc handleQueryOrphans*(args: seq[Argument], config: Config): int = reference let depends = toSeq(pkg.depends.items) - .map(toPackageReference).toSet + .map(d => d.toPackageReference).toSet let optional = toSeq(pkg.optional.items) - .map(toPackageReference).toSet + .map(d => d.toPackageReference).toSet let provides = toSeq(pkg.provides.items) - .map(toPackageReference).map(fixProvides).toSet + .map(d => d.toPackageReference).map(fixProvides).toSet installed.add(($pkg.name, pkg.reason == AlpmReason.explicit), depends + optional) diff --git a/src/feature/syncinstall.nim b/src/feature/syncinstall.nim index 3d3abcc..23c8a37 100644 --- a/src/feature/syncinstall.nim +++ b/src/feature/syncinstall.nim @@ -80,8 +80,7 @@ proc findDependencies(config: Config, handle: ptr AlpmHandle, dbs: seq[ptr AlpmD for satref, res in satisfied.pairs: if res.buildPkgInfo.isSome: let pkgInfo = res.buildPkgInfo.unsafeGet - if satref == reference or reference.isProvidedBy((pkgInfo.name, none(string), - some((ConstraintOperation.eq, pkgInfo.version)))): + if satref == reference or reference.isProvidedBy(pkgInfo.toPackageReference): return some(pkgInfo) for provides in pkgInfo.provides: if reference.isProvidedBy(provides) and @@ -92,8 +91,7 @@ proc findDependencies(config: Config, handle: ptr AlpmHandle, dbs: seq[ptr AlpmD proc findInDatabaseWithGroups(db: ptr AlpmDatabase, reference: PackageReference, directName: bool): Option[tuple[name: string, groups: seq[string]]] = for pkg in db.packages: - if reference.isProvidedBy(($pkg.name, none(string), - some((ConstraintOperation.eq, $pkg.version)))): + if reference.isProvidedBy(pkg.toPackageReference): return some(($pkg.name, pkg.groupsSeq)) for provides in pkg.provides: if reference.isProvidedBy(provides.toPackageReference): @@ -610,8 +608,7 @@ proc handleInstall(args: seq[Argument], config: Config, upgradeCount: int, proc checkSatisfied(reference: PackageReference): bool = for pkg in handle.local.packages: - if reference.isProvidedBy(($pkg.name, none(string), - some((ConstraintOperation.eq, $pkg.version)))): + if reference.isProvidedBy(pkg.toPackageReference): return true for provides in pkg.provides: if reference.isProvidedBy(provides.toPackageReference): @@ -823,11 +820,28 @@ proc handleSyncInstall*(args: seq[Argument], config: Config): int = else: true)) - if acceptedPkgInfos.len > 0 and printFormat.isNone: + let nonConflicingPkgInfos = pkgInfos.foldl(block: + let conflictsWith = lc[p | (p <- a, p.name != b.name and + (lc[0 | (c <- b.conflicts, c.isProvidedBy(p.toPackageReference)), int].len > 0 or + lc[0 | (c <- p.conflicts, c.isProvidedBy(b.toPackageReference)), int].len > 0)), + PackageInfo] + if printFormat.isNone and conflictsWith.len > 0: + for conflict in conflictsWith: + printWarning(config.color, + tra("removing '%s' from target list because it conflicts with '%s'\n") % + [b.name, conflict.name]) + a + else: + a & b, + newSeq[PackageInfo]()) + + let finalPkgInfos = nonConflicingPkgInfos + + if finalPkgInfos.len > 0 and printFormat.isNone: echo(trp("resolving dependencies...\n")) let (satisfied, unsatisfied) = withAlpm(config.root, config.db, config.dbs, config.arch, handle, dbs, errors): - findDependencies(config, handle, dbs, acceptedPkgInfos, + findDependencies(config, handle, dbs, finalPkgInfos, printFormat.isSome, noaur) if unsatisfied.len > 0: @@ -848,8 +862,8 @@ proc handleSyncInstall*(args: seq[Argument], config: Config): int = elif pkgInfo.repo == "aur" and pkgInfo.maintainer.isNone: printWarning(config.color, tr"$# is orphaned" % [pkgInfo.name]) - let aurPrintSet = acceptedPkgInfos.map(i => i.name).toSet - let fullPkgInfos = acceptedPkgInfos & lc[i | (s <- satisfied.values, + let aurPrintSet = finalPkgInfos.map(i => i.name).toSet + let fullPkgInfos = finalPkgInfos & lc[i | (s <- satisfied.values, i <- s.buildPkgInfo, not (i.name in aurPrintSet)), PackageInfo].deduplicate let directPacmanTargets = pacmanTargets.map(t => t.formatArgument) diff --git a/src/package.nim b/src/package.nim index 483c058..5683d5f 100644 --- a/src/package.nim +++ b/src/package.nim @@ -162,6 +162,24 @@ proc isProvidedBy*(package: PackageReference, by: PackageReference): bool = else: false +proc toPackageReference*(dependency: ptr AlpmDependency): PackageReference = + let op = case dependency.depmod: + of AlpmDepMod.eq: some(ConstraintOperation.eq) + of AlpmDepMod.ge: some(ConstraintOperation.ge) + of AlpmDepMod.le: some(ConstraintOperation.le) + of AlpmDepMod.gt: some(ConstraintOperation.gt) + of AlpmDepMod.lt: some(ConstraintOperation.lt) + else: none(ConstraintOperation) + + let description = if dependency.desc != nil: some($dependency.desc) else: none(string) + ($dependency.name, description, op.map(o => (o, $dependency.version))) + +template toPackageReference*(pkg: ptr AlpmPackage): PackageReference = + ($pkg.name, none(string), some((ConstraintOperation.eq, $pkg.version))) + +template toPackageReference*(pkg: PackageInfo): PackageReference = + (pkg.name, none(string), some((ConstraintOperation.eq, pkg.version))) + proc parseSrcInfoKeys(srcInfo: string): tuple[baseSeq: ref seq[SrcInfoPair], table: OrderedTable[string, ref seq[SrcInfoPair]]] = var table = initOrderedTable[string, ref seq[SrcInfoPair]]() -- cgit v1.2.3-70-g09d2