swiftlang/swift-package-manager

Expected root cause […] to almost satisfy the current partial solution

Frizlab opened this issue · 2 comments

Is it reproducible with SwiftPM command-line tools: swift build, swift test, swift package etc?

  • Confirmed reproduction steps with SwiftPM CLI.

Description

I got the following internal error while running swift package resolve:

error: InternalError(description: "Internal error. Please file a bug at https://github.com/apple/swift-package-manager/issues with this info. Expected root cause {json-logger[everything] 0.2.0, ¬generic-json[everything] 3.0.0..<4.0.0} to almost satisfy the current partial solution:
 * [Decision 0: puremonolith[everything] 1.0.0]
 * [Derivation: urlrequestoperation[everything] 2.0.0-alpha.15..<3.0.0 ← {puremonolith[everything] 1.0.0, ¬urlrequestoperation[everything] 2.0.0-alpha.15..<3.0.0}]
 * [Derivation: swift-log[everything] 1.5.1..<2.0.0 ← {puremonolith[everything] 1.0.0, ¬swift-log[everything] 1.5.1..<2.0.0}]
 * [Derivation: routing-kit[everything] 4.8.2..<5.0.0 ← {puremonolith[everything] 1.0.0, ¬routing-kit[everything] 4.8.2..<5.0.0}]
 * [Derivation: unwraporthrow[everything] 1.0.0..<2.0.0 ← {puremonolith[everything] 1.0.0, ¬unwraporthrow[everything] 1.0.0..<2.0.0}]
 * [Derivation: safeglobal[everything] 0.1.0..<1.0.0 ← {puremonolith[everything] 1.0.0, ¬safeglobal[everything] 0.1.0..<1.0.0}]
 * [Derivation: swift-email[everything] 0.2.3..<1.0.0 ← {puremonolith[everything] 1.0.0, ¬swift-email[everything] 0.2.3..<1.0.0}]
 * [Derivation: httpcoders[everything] 0.1.2..<1.0.0 ← {puremonolith[everything] 1.0.0, ¬httpcoders[everything] 0.1.2..<1.0.0}]
 * [Derivation: generic-json[everything] 3.0.0..<4.0.0 ← {puremonolith[everything] 1.0.0, ¬generic-json[everything] 3.0.0..<4.0.0}]
 * [Derivation: swift-log[everything] 1.5.3..<2.0.0 ← {puremonolith[everything] 1.0.0, ¬swift-log[everything] 1.5.3..<2.0.0}]
 * [Derivation: json-logger[everything] 0.2.0..<1.0.0 ← {puremonolith[everything] 1.0.0, ¬json-logger[everything] 0.2.0..<1.0.0}]
 * [Derivation: clt-logger[everything] 0.7.1..<1.0.0 ← {puremonolith[everything] 1.0.0, ¬clt-logger[everything] 0.7.1..<1.0.0}]
 * [Derivation: stripe-kit[everything] 23.1.0..<24.0.0 ← {puremonolith[everything] 1.0.0, ¬stripe-kit[everything] 23.1.0..<24.0.0}]
 * [Derivation: vapor[everything] 4.67.0..<5.0.0 ← {puremonolith[everything] 1.0.0, ¬vapor[everything] 4.67.0..<5.0.0}]
 * [Derivation: redis[everything] 4.10.0..<5.0.0 ← {puremonolith[everything] 1.0.0, ¬redis[everything] 4.10.0..<5.0.0}]
 * [Derivation: queues-redis-driver[everything] 1.0.3..<2.0.0 ← {puremonolith[everything] 1.0.0, ¬queues-redis-driver[everything] 1.0.3..<2.0.0}]
 * [Derivation: queues[everything] 1.11.1..<2.0.0 ← {puremonolith[everything] 1.0.0, ¬queues[everything] 1.11.1..<2.0.0}]
 * [Derivation: jwt[everything] 4.2.1..<5.0.0 ← {puremonolith[everything] 1.0.0, ¬jwt[everything] 4.2.1..<5.0.0}]
 * [Derivation: fluent-postgres-driver[everything] 2.4.0..<3.0.0 ← {puremonolith[everything] 1.0.0, ¬fluent-postgres-driver[everything] 2.4.0..<3.0.0}]
 * [Derivation: fluent[everything] 4.5.0..<5.0.0 ← {puremonolith[everything] 1.0.0, ¬fluent[everything] 4.5.0..<5.0.0}]
 * [Derivation: apns[everything] 4.0.0..<5.0.0 ← {puremonolith[everything] 1.0.0, ¬apns[everything] 4.0.0..<5.0.0}]
 * [Derivation: swift-prometheus[everything] 2.0.0..<3.0.0 ← {puremonolith[everything] 1.0.0, ¬swift-prometheus[everything] 2.0.0..<3.0.0}]
 * [Derivation: legibleerror[everything] 1.0.6..<2.0.0 ← {puremonolith[everything] 1.0.0, ¬legibleerror[everything] 1.0.6..<2.0.0}]
 * [Derivation: unwraporthrow[everything] 1.0.1-rc.1..<2.0.0 ← {puremonolith[everything] 1.0.0, ¬unwraporthrow[everything] 1.0.1-rc.1..<2.0.0}]
 * [Derivation: safeglobal[everything] 0.2.0..<1.0.0 ← {puremonolith[everything] 1.0.0, ¬safeglobal[everything] 0.2.0..<1.0.0}]
 * [Derivation: swift-xdg[everything] 1.0.0-beta.1.0.1..<2.0.0 ← {puremonolith[everything] 1.0.0, ¬swift-xdg[everything] 1.0.0-beta.1.0.1..<2.0.0}]
 * [Derivation: swift-task-queue[everything] 1.1.0..<2.0.0 ← {puremonolith[everything] 1.0.0, ¬swift-task-queue[everything] 1.1.0..<2.0.0}]
 * [Derivation: generic-json[everything] 3.1.0-beta..<4.0.0 ← {puremonolith[everything] 1.0.0, ¬generic-json[everything] 3.1.0-beta..<4.0.0}]
 * [Derivation: collectionconcurrencykit[everything] 0.3.0..<1.0.0 ← {puremonolith[everything] 1.0.0, ¬collectionconcurrencykit[everything] 0.3.0..<1.0.0}]
 * [Derivation: tomldecoder[everything] 0.2.2..<1.0.0 ← {puremonolith[everything] 1.0.0, ¬tomldecoder[everything] 0.2.2..<1.0.0}]
 * [Derivation: swift-metrics[everything] 2.2.0..<3.0.0 ← {puremonolith[everything] 1.0.0, ¬swift-metrics[everything] 2.2.0..<3.0.0}]
 * [Derivation: ¬json-logger[everything] 0.2.1..<1.0.0 ← {json-logger[everything] 0.2.1..<1.0.0}]
")
My Package.swift
// swift-tools-version:5.8
import PackageDescription
import Foundation



/* To find a valid test for Xcode detection, we sneakily inserted the following code in the products definition, just before the return:
 *    for (key, val) in ProcessInfo.processInfo.environment {
 *       res.append(.executable(name: key, targets: [val]))
 *    }
 * This generated a bunch of errors about invalid targets for the executable products,
 *  w/ the name of the executable being the key of the environment value and the target name its value.
 * From this we devised a check which was likely to be true in Xcode and unlikely to be true anywhere else.
 *
 * When tested, the actual value of the environment key we chose was `com.apple.dt.Xcode`.
 * We did not test directly for this in the check as _maybe_ some versions of Xcode have a different bundle ID (I don’t think so but we never know…). */
let isXcode = ProcessInfo.processInfo.environment["__CFBundleIdentifier"]?.lowercased().contains("xcode") ?? false

/* If the Package.swift is resolved in Xcode we set a different name for the executable name.
 * We need to do this because Xcode is a little bit dumb and has some kind of weirdnesses or failures
 *  when the bundle has a different name than the executable name (including, but not limited to: the tests do not compile). */
let executableName = if isXcode {"PureMonolith"} else {"pure-monolith"}

let package = Package(
   name: "PureMonolith",
   platforms: [
      .macOS(.v13)
   ],
   products: {
      var res = [Product]()
      res.append(.executable(name: executableName, targets: ["PureMonolith"]))
      return res
   }(),
   dependencies: {
      var res = [Package.Dependency]()
      res.append(.package(url: "git@gitlab.com:togever/togever-api-model.git",            branch: "develop"))
      res.append(.package(url: "https://github.com/apple/swift-log.git",                  from: "1.4.4"))
      res.append(.package(url: "https://github.com/apple/swift-metrics.git",              from: "2.2.0"))
      res.append(.package(url: "https://github.com/dduan/TOMLDecoder.git",                from: "0.2.2"))
      res.append(.package(url: "https://github.com/Frizlab/CollectionConcurrencyKit.git", from: "0.3.0"))
      res.append(.package(url: "https://github.com/Frizlab/generic-json.git",             from: "3.1.0-beta"))
      res.append(.package(url: "https://github.com/Frizlab/swift-email.git",              from: "0.2.1"))
      res.append(.package(url: "https://github.com/Frizlab/swift-task-queue.git",         from: "1.1.0"))
      res.append(.package(url: "https://github.com/Frizlab/swift-xdg.git",                from: "1.0.0-beta.1.0.1"))
      res.append(.package(url: "https://github.com/Frizlab/SafeGlobal.git",               from: "0.2.0"))
      res.append(.package(url: "https://github.com/Frizlab/UnwrapOrThrow.git",            from: "1.0.1-rc.1"))
      res.append(.package(url: "https://github.com/mxcl/LegibleError.git",                from: "1.0.6"))
      res.append(.package(url: "https://github.com/swift-server/swift-prometheus.git",    from: "2.0.0"))
      res.append(.package(url: "https://github.com/vapor/apns.git",                       from: "4.0.0"))
      res.append(.package(url: "https://github.com/vapor/fluent.git",                     from: "4.5.0"))
      res.append(.package(url: "https://github.com/vapor/fluent-postgres-driver.git",     from: "2.4.0"))
      res.append(.package(url: "https://github.com/vapor/jwt.git",                        from: "4.2.1"))
      res.append(.package(url: "https://github.com/vapor/queues.git",                     from: "1.11.1"))
      res.append(.package(url: "https://github.com/vapor/queues-redis-driver.git",        from: "1.0.3"))
      res.append(.package(url: "https://github.com/vapor/redis.git",                      from: "4.10.0"))
      res.append(.package(url: "https://github.com/vapor/vapor.git",                      from: "4.67.0"))
      res.append(.package(url: "https://github.com/vapor-community/stripe-kit.git",       from: "23.1.0"))
      res.append(.package(url: "https://github.com/xcode-actions/clt-logger.git",         from: "0.7.1"))
      res.append(.package(url: "https://github.com/xcode-actions/json-logger.git",        from: "0.2.0"))
      res.append(.package(url: "https://github.com/xcode-actions/loki-logger.git",        branch: "main"))
      return res
   }(),
   targets: {
      var res = [Target]()
      res.append(.executableTarget(
         name: "PureMonolith",
         dependencies: {
            var res = [Target.Dependency]()
            res.append(.product(name: "CLTLogger",                package: "clt-logger"))
            res.append(.product(name: "CollectionConcurrencyKit", package: "CollectionConcurrencyKit"))
            res.append(.product(name: "Email",                    package: "swift-email"))
            res.append(.product(name: "Fluent",                   package: "fluent"))
            res.append(.product(name: "FluentPostgresDriver",     package: "fluent-postgres-driver"))
            res.append(.product(name: "JSONLogger",               package: "json-logger"))
            res.append(.product(name: "JWT",                      package: "jwt"))
            res.append(.product(name: "LegibleError",             package: "LegibleError"))
            res.append(.product(name: "Logging",                  package: "swift-log"))
            res.append(.product(name: "LokiLogger",               package: "loki-logger"))
            res.append(.product(name: "Metrics",                  package: "swift-metrics"))
            res.append(.product(name: "Prometheus",               package: "swift-prometheus"))
            res.append(.product(name: "PureModel",                package: "togever-api-model"))
            res.append(.product(name: "Queues",                   package: "queues"))
            res.append(.product(name: "QueuesRedisDriver",        package: "queues-redis-driver"))
            res.append(.product(name: "Redis",                    package: "redis"))
            res.append(.product(name: "SafeGlobal",               package: "SafeGlobal"))
            res.append(.product(name: "StripeKit",                package: "stripe-kit"))
            res.append(.product(name: "TaskQueue",                package: "swift-task-queue"))
            res.append(.product(name: "TOMLDecoder",              package: "TOMLDecoder"))
            res.append(.product(name: "UnwrapOrThrow",            package: "UnwrapOrThrow"))
            res.append(.product(name: "Vapor",                    package: "vapor"))
            res.append(.product(name: "VaporAPNS",                package: "apns"))
            res.append(.product(name: "XDG",                      package: "swift-xdg"))
            return res
         }(),
         swiftSettings: {
            var res = [SwiftSetting]()
            /* Enable better optimizations when building in Release configuration.
             * Despite the use of the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release builds.
             * See <https://github.com/swift-server/guides/blob/main/docs/building.md#building-for-production> for details. */
            res.append(.unsafeFlags(["-cross-module-optimization"], .when(configuration: .release)))
            /* Check for concurrency issues. */
            res.append(.enableExperimentalFeature("StrictConcurrency"))
            return res
         }()
      ))
      res.append(.testTarget(name: "PureMonolithTests", dependencies: {
         var res = [Target.Dependency]()
         res.append(.target(name: "PureMonolith")) /* <- Tested target. */
         res.append(.product(name: "CLTLogger",  package: "clt-logger"))
         res.append(.product(name: "Logging",    package: "swift-log"))
         res.append(.product(name: "SafeGlobal", package: "SafeGlobal"))
         res.append(.product(name: "XCTVapor",   package: "vapor"))
         return res
      }(), swiftSettings: [.enableExperimentalFeature("StrictConcurrency")]))
      return res
   }()
)

Expected behavior

The graph should resolve.

Actual behavior

We get an internal error.

Steps to reproduce

Create a project with the given Package.swift and try to resolve it..

Swift Package Manager version/commit hash

Swift Package Manager - Swift 5.10.0-dev

Swift & OS version (output of swift --version ; uname -a)

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0
Darwin Frizlabs-MacBook-Pro-Mojo.local 23.4.0 Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:37 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6031 arm64

Note: togever-api-model depends on generic-json from: "3.0.0".

I suspect this is the root cause of the issue: my package depends on a beta version of generic-json and on a package (togever-api-model) which depends on a non-beta version of generic-json.
It should work, but we get an internal error instead.

I did not try reducing the problem to this simpler use-case but I did get the issue when I updated the requirements for generic-json in my package.

Closing as I cannot reproduce anymore.