Some package import do not work with Swift 5.2
Frizlab opened this issue · comments
This is new in Swift 5.2, I think the Package.swift
needs to be generated differently.
With this script,
#!/usr/bin/swift sh
import Crypto // apple/swift-crypto ~> 1.0.1
we get the following error
error: manifest parse error: unknown package 'Crypto' in dependencies of target 'my_awesome_script'; if the package is named differently from the product, either use '.product(name: "Crypto", package: <package-name>)' to specify the package name or give the package the 'Crypto' name using '.package(name: "Crypto", ...)'
Can you provide the generated Package.swift, it'll be in ~/Library/Develop/swift-sh.cache
.
Sure! There it is
// swift-tools-version:5.2
import PackageDescription
let pkg = Package(name: "hash_htpasswd_user_pass")
pkg.products = [
.executable(name: "hash_htpasswd_user_pass", targets: ["hash_htpasswd_user_pass"])
]
pkg.dependencies = [
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMajor(from: "1.0.1")),
.package(url: "https://github.com/kareman/SwiftShell.git", .upToNextMajor(from: "5.0.1"))
]
pkg.targets = [
.target(name: "hash_htpasswd_user_pass", dependencies: ["Crypto", "SwiftShell"], path: ".", sources: ["main.swift"])
]
#if swift(>=5) && os(macOS)
pkg.platforms = [
.macOS(.v10_15)
]
#endif
I've manually changed the swift-tools-version back to 5.1 for now. That appears to fix things.
I too have a script failing since upgrading Xcode to 11.4.x, it does import ArgumentParser // apple/swift-argument-parser
. I dove a little deeper into SPM to see what was up.
My script fails like (linefeeds added to error message for clarity):
Fetching https://github.com/apple/swift-argument-parser.git
Cloning https://github.com/apple/swift-argument-parser.git
Resolving https://github.com/apple/swift-argument-parser.git at 0.0.5
'rename' /Users/myself/Library/Developer/swift-sh.cache/e44e2e32219f152e07016f3bdb92d57f:
error: dependency 'ArgumentParser' in target 'rename' requires explicit declaration;
reference the package in the target dependency with
'.product(name: "ArgumentParser", package: "swift-argument-parser")'
The generated Package.swift
:
// swift-tools-version:5.2
import PackageDescription
let pkg = Package(name: "rename")
pkg.products = [
.executable(name: "rename", targets: ["rename"])
]
pkg.dependencies = [
.package(url: "https://github.com/apple/swift-argument-parser.git", Version(0,0,0)...Version(1_000_000,0,0)),
]
pkg.targets = [
.target(name: "rename", dependencies: ["ArgumentParser"], path: ".", sources: ["main.swift"])
]
#if swift(>=5) && os(macOS)
pkg.platforms = [
.macOS(.v10_15)
]
#endif
I tried changing Package.swift
manually and running again (which I'm happy was possible), changing the .package
call to what the error message described, but this didn't work.
/Users/myself/Library/Developer/swift-sh.cache/e44e2e32219f152e07016f3bdb92d57f: error: manifest parse error(s):
/Users/myself/Library/Developer/swift-sh.cache/e44e2e32219f152e07016f3bdb92d57f/Package.swift:11:6: error: type 'Array<Package.Dependency>.ArrayLiteralElement' (aka 'Package.Dependency') has no member 'product'
.product(name: "ArgumentParser", url: "https://github.com/apple/swift-argument-parser.git", Version(0,0,0)...Version(1_000_000,0,0)),
~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: 1 <(/usr/bin/swift build -Xswiftc -suppress-warnings)
I found SR-12075 which seems to be all about the change to the error message, which mentions ”SwiftPM should tell me that I need to specify name: "SwiftSyntax" in the declaration of the dependency”, however looking at the Package.Dependency
documentation and exported swift interface, I cannot find a variants of static func product(...)
with a name
parameter.
In fact, in the swift interface all those static functions are preceded by @available(_PackageDescription, obsoleted: 5.2)
, which looks fishy:
@available(_PackageDescription, obsoleted: 5.2)
public static func package(url: String, from version: PackageDescription.Version) -> PackageDescription.Package.Dependency
@available(_PackageDescription, obsoleted: 5.2)
public static func package(url: String, _ requirement: PackageDescription.Package.Dependency.Requirement) -> PackageDescription.Package.Dependency
@available(_PackageDescription, obsoleted: 5.2)
public static func package(url: String, _ range: Range<PackageDescription.Version>) -> PackageDescription.Package.Dependency
@available(_PackageDescription, obsoleted: 5.2)
public static func package(url: String, _ range: ClosedRange<PackageDescription.Version>) -> PackageDescription.Package.Dependency
@available(_PackageDescription, obsoleted: 5.2)
public static func package(path: String) -> PackageDescription.Package.Dependency
Is .package(..)
now canonically defined elsewhere for 5.2 with different signatures adding a name:
parameter, the above static functions remaining as-is for backwards compatibility? I cannot find such new declarations. Or is this just broken in Swift 5.2 Package Manager, with the new error message thanks to SR-12075 merely aspirational?
AFAICT, you changed the wrong thing. You should change dependencies: ["ArgumentParser"]
(in the .target
of the pkg.targets
assignment) to dependencies: [.product(name: "ArgumentParser", package: "swift-argument-parser")]
and it should work.
D'oh! Indeed that works, thanks.
I'm having the same issue with SwiftProtobuf.
#!/usr/bin/swift sh
import Foundation
import SwiftProtobuf // apple/swift-protobuf ~> 1.8.0
Getting error
error: dependency 'SwiftProtobuf' in target 'main' requires explicit declaration; provide the name of the package dependency with '.package(name: "SwiftProtobuf", url: "https://github.com/apple/swift-protobuf.git", from: "1.8.0")'
There's no option to add such .package
to dependencies.
It is interesting that if I do swift sh eject
and then swift build
in the newly created folder, it works. Same Package.swift
that swift-sh generated in ~/Library/Developer/swift-sh-cache
There's a difference actually, swift sh eject
used // swift-tools-version:4.2
Fixed with 1.18.0
This still is broken in some cases. For example when using
import Path // mxcl/Path.swift ~> 1.0.1
The error is:
error: unknown package 'Path' in dependencies of target 'makeModule'
The package name should be "Path.swift" instead of "Path" in the generated Package.swift
// swift-tools-version:5.2
import PackageDescription
let pkg = Package(name: "makeModule")
pkg.products = [
.executable(name: "makeModule", targets: ["makeModule"])
]
pkg.dependencies = [
.package(url: "https://github.com/kylef/Commander.git", .upToNextMajor(from: "0.9.1")),
.package(url: "https://github.com/wlisac/Environment.git", .upToNextMajor(from: "0.11.1")),
.package(url: "https://github.com/mxcl/Path.swift.git", .upToNextMajor(from: "1.0.1")),
.package(url: "https://github.com/JohnSundell/ShellOut.git", .upToNextMajor(from: "2.0.0"))
]
pkg.targets = [
.target(name: "makeModule", dependencies: [.product(name: "Commander", package: "Commander"), .product(name: "Environment", package: "Environment"), .product(name: "Path", package: "Path"), .product(name: "ShellOut", package: "ShellOut")], path: ".", sources: ["main.swift"])
]
#if swift(>=5) && os(macOS)
pkg.platforms = [
.macOS(.v10_15)
]
#endif
Thanks for the report, would you mind creating a ticket?