Thanks for the replies. I took a closer look at the proposal and think it's really powerful. Mapping resources via enum in the manifest is really flexible (btw an associated enum would be really nice here: roles: [.resource("*.dat")]).
Although I did have the same questions you brought up regarding multiple pattern matches conflicting. Would leveraging SwiftPM's existing conventions help simplify implementation while still leave options for the future? For example, how about a convention like this which plays off the existing convention:
MySwiftPackage
|-- Resources
|-- MySwiftPackage
|-- MySwiftPackageTests
|-- Sources
|-- MySwiftPackage
|-- Tests
|-- MySwiftPackageTests
It's true you can't mix code and resources with this, but think it's a fair trade to get the feature off the ground. It would still be a welcomed update later and an easy "migration" if anyone wishes to mix code and resources at that point (or wouldn't hurt if one decides to opt out).
Regarding the generated bundle name, would it make sense to generate it off the package name? What I mean is since the module name is known, how about import declarations or a typealias such as:
import MySwiftPackage
import bundle MySwiftPackage.bundle //or
typealias MySwiftPackageBundle = MySwiftPackage.bundle
I didn't realize resources fundamentally could not be embedded within static libraries. Is this still true even with the changes that came with SwiftPM? If there needs to be some kind of automation script to copy the bundle during the build process, there is a discussion and an experimental script that may help. In case you missed it here is the link and the script:
#!/usr/bin/swift
// FILE: swift-copy-testresources.sh
// verify swift path with "which -a swift"
// macOS: /usr/bin/swift
// Ubuntu: /opt/swift/current/usr/bin/swift
import Foundation
func copyTestResources() {
let argv = ProcessInfo.processInfo.arguments
// for i in 0..<argv.count {
// print("argv[\(i)] = \(argv[i])")
// }
let pwd = argv[argv.count-1]
print("Executing swift-copy-testresources")
print(" PWD=\(pwd)")
let fm = FileManager.default
let pwdUrl = URL(fileURLWithPath: pwd, isDirectory: true)
let srcUrl = pwdUrl
.appendingPathComponent("TestResources", isDirectory: true)
let buildUrl = pwdUrl
.appendingPathComponent(".build", isDirectory: true)
let dstUrl = buildUrl
.appendingPathComponent("Contents", isDirectory: true)
.appendingPathComponent("Resources", isDirectory: true)
do {
let contents = try fm.contentsOfDirectory(at: srcUrl, includingPropertiesForKeys: [])
do { try fm.removeItem(at: dstUrl) } catch { }
try fm.createDirectory(at: dstUrl, withIntermediateDirectories: true)
for fromUrl in contents {
try fm.copyItem(
at: fromUrl,
to: dstUrl.appendingPathComponent(fromUrl.lastPathComponent)
)
}
} catch {
print(" SKIP TestResources not copied. ")
return
}
print(" SUCCESS TestResources copy completed.\n FROM \(srcUrl)\n TO \(dstUrl)")
}
copyTestResources()
There was a suggestion in that discussion about adding resources as local dependencies which seems like a clever approach as well.
Thanks again for the replies and proposal.