mxcl / swift-sh

Easily script with third-party Swift dependencies.
The Unlicense
1.8k stars 59 forks source link

incompatible dependencies #69

Closed thecb4 closed 5 years ago

thecb4 commented 5 years ago

ArgumentsParser appears to be the culprit, but I have a repo that uses SPMUtility as a dependency for the Command Line Module.

I am importing the library portion, but since the CLI module depends on SPMUtility, shift sh still throws up from a dependency conflict. I tried upgrading to Swift-5.0-branch, but that did not resolve the problem. One solution is to break my library into a Kit and CLI repo. I'd rather not do that.

➜  Shelltr git:(feature/test-post-0.2-release) ✗ swift sh bin/workflow.swift                                   
Fetching https://gitlab.com/thecb4/Shelltr
Fetching https://gitlab.com/thecb4/changelogger
error: the package changelogger[https://gitlab.com/thecb4/changelogger] @ 0.1.2 contains incompatible dependencies:
    swift-package-manager[https://github.com/apple/swift-package-manager.git] @ swift-5.0-branch
mxcl commented 5 years ago

Not sure I understand the bug in swift-sh here. Please clarify.

Sent with GitHawk

thecb4 commented 5 years ago

I was using the Swift-Package-amanager library as a dependency in one of my imports at the top of my swift-ah file. When I attempted to execute the script and it went to fetch the library I would receive the “incompatible dependencies” error. I removed the dependency from my repo for now and everything executes fine with swift-sh. I was looking for a verbose feature to see if I could pinpoint the exact incompatibility.

Replicating the error should be as simple as including a repo In the swift-sh file that has Swift-Package-Manager as a dependency

mxcl commented 5 years ago

swift-sh writes out a Package.swift based on the imports you specify and then executes SwiftPM, if SwiftPM says you have “incompatible dependencies” then you have incompatible dependencies, not much swift-sh can do.

If you provided an example script or the imports that you are specifying that are causing the issue I would be able to help further.

thecb4 commented 5 years ago

See Package.swift for repo. Removing the swift-package-manager dependency allowed the script to work.

// swift-tools-version:4.2
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
  name: "ChangeLogger",
  products: [
    .executable(name: "changelogger", targets: ["ChangeLogger"]),
    .library(name: "ChangeLoggerCLI", targets: ["ChangeLoggerCLI"]),
    .library(name: "ChangeLoggerKit", targets: ["ChangeLoggerKit"])
  ],
  dependencies: [
    // Dependencies declare other packages that this package depends on.
    .package(url: "https://github.com/jpsim/Yams", .exact("1.0.1"))
    .package(url: "https://github.com/apple/swift-package-manager.git", .branch("swift-4.2-branch"))
  ],
  targets: [
    // Targets are the basic building blocks of a package. A target can define a module or a test suite.
    // Targets can depend on other targets in this package, and on products in packages which this package depends on.
    .target(
      name: "ChangeLogger",
      dependencies: ["ChangeLoggerCLI"]
    ),
    .target(
      name: "ChangeLoggerCLI",
      dependencies: ["ChangeLoggerKit", "Utility"]
    ),
    .target(
      name: "ChangeLoggerKit",
      dependencies: ["Yams"]
    ),
    .testTarget(
      name: "ChangeLoggerKitTests",
      dependencies: ["ChangeLoggerKit", "Yams"]
    ),
    .testTarget(
      name: "ChangeLoggerTests",
      dependencies: ["ChangeLogger", "ChangeLoggerKit"]
    )
  ]
)

See the swift-sh script

#!/usr/bin/swift sh

import Foundation
import Shelltr // https://gitlab.com/thecb4/Shelltr == 0.2.0
import ChangeLoggerKit // https://gitlab.com/thecb4/changelogger == 0.2.0

@available(macOS 10.13, *)
extension Shell {
  public static func _swifttest(shellType: ShellType = .bash, arguments: [String] = []) throws {
    let args = ["test"] + arguments
    try Shell(shellType).execute(.swift(args))
  }
}

if #available(macOS 10.13, *) {
  Shell.work {
    // tell me what you are changing
    try Shell.assertModified(file: "commit.yaml")

    // get rid of all the old data
    try Shell.rm(content: ".build", recursive: true, force: true)

    // Lint & Format
    try Shell.swiftformat()
    try Shell.swiftlint(quiet: false)

    // delete data and build for docs

    try Shell.swifttest()
    try Shell.sourcekitten(module: "Shelltr", destination: Shell.cwd + "/docs/source.json")
    try Shell.jazzy()

    // cleanup
    try Shell.rm(content: ".build", recursive: true, force: true)

    // add + commit
    try ChangeLog.revise()
    try Shell.gitAdd(.all)
    let message = try CommitEntry.current().summary
    try Shell.gitCommit(message: message)
  }
}
mxcl commented 5 years ago

Please provide an example that fails.

mxcl commented 5 years ago

Like, I used the script you provided and it worked.

thecb4 commented 5 years ago

Downgrading back to version 0.1.2 of ChangeLogger should provide the error

#!/usr/bin/swift sh

import Foundation
import Shelltr // https://gitlab.com/thecb4/Shelltr == 0.2.0
import ChangeLoggerKit // https://gitlab.com/thecb4/changelogger == 0.1.2

@available(macOS 10.13, *)
extension Shell {
  public static func _swifttest(shellType: ShellType = .bash, arguments: [String] = []) throws {
    let args = ["test"] + arguments
    try Shell(shellType).execute(.swift(args))
  }
}

if #available(macOS 10.13, *) {
  Shell.work {
    // tell me what you are changing
    try Shell.assertModified(file: "commit.yaml")

    // get rid of all the old data
    try Shell.rm(content: ".build", recursive: true, force: true)

    // Lint & Format
    try Shell.swiftformat()
    try Shell.swiftlint(quiet: false)

    // delete data and build for docs

    try Shell.swifttest()
    try Shell.sourcekitten(module: "Shelltr", destination: Shell.cwd + "/docs/source.json")
    try Shell.jazzy()

    // cleanup
    try Shell.rm(content: ".build", recursive: true, force: true)

    // add + commit
    try ChangeLog.revise()
    try Shell.gitAdd(.all)
    let message = try CommitEntry.current().summary
    try Shell.gitCommit(message: message)
  }
}
mxcl commented 5 years ago

Yeah, this is not a swift-sh issue, SwiftPM errors with this Package.swift, which comes from your dependency specification:

// swift-tools-version:5.0
import PackageDescription

let pkg = Package(name: "fub")

pkg.products = [
    .executable(name: "fub", targets: ["fub"])
]
pkg.dependencies = [
    .package(url: "https://gitlab.com/thecb4/Shelltr", .exact(Version(0,2,0))),
    .package(url: "https://gitlab.com/thecb4/changelogger", .exact(Version(0,1,2)))
]
pkg.targets = [
    .target(name: "fub", dependencies: ["Shelltr", "ChangeLoggerKit"], path: ".", sources: ["main.swift"])
]

Like, there's nothing swift-sh can do about this. If you believe this is a bug, please report it to Apple. I imagine however it is like SwiftPM says, ie. the dependency graph cannot be resolved for some reason.

mxcl commented 5 years ago

Like, reading the error, sounds like two things in the graph require different versions of libSwiftPM, which naturally is impossible to resolve.

thecb4 commented 5 years ago

When I was using the 4.2 branch of SwiftPM it was giving the same error. If I would get some additional info from swift pm about what was causing the clash, that would be helpful. Is it possible that since swift-sh is using swift-tools:5.0 that could be causing some of the problem?

I have a completely different library where I specify the same swift-pm dependency and everything works fine.

mxcl commented 5 years ago

swift-sh uses whatever tools are active. If you want to use 4.2, use xcode-select.

I have a completely different library where I specify the same swift-pm dependency and everything works fine.

This is not a swift-sh problem, you can go to ~/Library/Developer/swift-sh.cache, step into the directory swift-sh creates and type swift build you'll get the same error.

Somewhere in the graph being created there is a conflict that cannot be resolved by SwiftPM, I cannot really help further.

thecb4 commented 5 years ago

ok thanks.

mxcl commented 5 years ago

One of your dependencies requires a certain branch of swift-pm and another requires a different branch of swift-pm, both cannot be satisfied. This is unfortunately just how it is.

thecb4 commented 5 years ago

That's the part that is confusing. I only have 1 reference to Swift Package Manager in my libraries. I've gone back to the other dependencies to confirm there aren't others. Building the package and running the tests themselves work. I would expect the error to occur there also.

mxcl commented 5 years ago

FWIW if you use Xcode 10.1 it has a different error:

$ DEVELOPER_DIR=/Applications/Xcode.app swift build
Updating https://gitlab.com/thecb4/changelogger
Updating https://gitlab.com/thecb4/Shelltr
error: the package changelogger[https://gitlab.com/thecb4/changelogger] @ 0.1.2 contains incompatible dependencies:
    swift-package-manager[https://github.com/apple/swift-package-manager.git] @ swift-5.0-branch
'fub' /Users/mxcl/Library/Developer/swift-sh.cache/fub: error: product dependency 'Shelltr' not found
'fub' /Users/mxcl/Library/Developer/swift-sh.cache/fub: error: product dependency 'ChangeLoggerKit' not found

Edit, well it's the same error to start.

For this generated Package.swift:

// swift-tools-version:4.2
import PackageDescription

let pkg = Package(name: "fub")

pkg.products = [
    .executable(name: "fub", targets: ["fub"])
]
pkg.dependencies = [
    .package(url: "https://gitlab.com/thecb4/Shelltr", .exact(Version(0,2,0))),
    .package(url: "https://gitlab.com/thecb4/changelogger", .exact(Version(0,1,2)))
]
pkg.targets = [
    .target(name: "fub", dependencies: ["Shelltr", "ChangeLoggerKit"], path: ".", sources: ["main.swift"])
]

Whatever is happening here there is definitely some bug in SwiftPM, even if it is just a bad diagnostic message that is hiding the real problem.

Potentially the issue is that the other dependencies don't specify that they support Swift 5, and the SwiftPM branch you specify only supports Swift 5. SwiftPM is (possibly) just giving a rubbish error message.

Edit: well that doesn't make sense since deps can each be built with a different language version.

mxcl commented 5 years ago

“incompatible dependencies” is pretty vague. Possibly a Swift 4.2 package cannot depend on a Swift 5 package? I’m not sure frankly.

If so you have that situation here.

thecb4 commented 5 years ago

I am running 10.143, Swift 4.2.1

import Foundation
import Shelltr // https://gitlab.com/thecb4/Shelltr == 0.3.0
import ChangeLogKit // https://gitlab.com/thecb4/changelogger == 0.1.3

I created a 0.1.3 of changelogger so that everything was referencing 4.2 tools and uses a swift-4.2-branch. Same error.

➜  NowThis git:(feature/fix-rating) ✗ swift sh bin/nowthis_workflow.swift
Fetching https://gitlab.com/thecb4/Shelltr
Fetching https://gitlab.com/thecb4/changelogger
error: the package changelogger[https://gitlab.com/thecb4/changelogger] @ 0.1.3 contains incompatible dependencies:
    swift-package-manager[https://github.com/apple/swift-package-manager] @ swift-4.2-branch
'nowthis_workflow' /Users/cavellebenjamin/Library/Developer/swift-sh.cache/nowthis_workflow: error: product dependency 'Shelltr' not found
'nowthis_workflow' /Users/cavellebenjamin/Library/Developer/swift-sh.cache/nowthis_workflow: error: product dependency 'ChangeLogKit' not found
error: 1 <(/usr/bin/swift build -Xswiftc -suppress-warnings)
mxcl commented 5 years ago

Well, Swift 4.2.1 cannot compile the swift-5.0-branch of SwiftPM, because it cannot compile Swift 5 code. So there's your “incompatible dependency”.

You should report the bug to Apple, SwiftPM’s error diagnostic is rubbish. It should say why the dependency is incompatible.

Edit: oh ok, you changed it to swift-4.2-branch.

Well I’m stumped, I cannot help further. Either way this isn’t a swift-sh issue.

thecb4 commented 5 years ago

Appreciate the help thinking through the problem. I've tried it a couple of different ways. I have started to look at the SwiftPM GitHub repo to see if I can trace the problem back. The message is completely useless.