10

I'm writing a Swift script as a standalone Swift Package. Part of this script needs to generate some files, for which I have templates.

Now, these templates are not compilable (they're HTML files); so in order to include them in the package I've included them as .copy("Templates").

When debugging my script, I can access the templates just fine, but when I try to archive the product, the executable doesn't have access to them anymore.

Here's my Package.swift:

let package = Package(
    name: "flucs",
    products: [
        .executable(name: "Flucs",
                    targets: ["flucs"])
    ],
    dependencies: [
        .package(url: "https://github.com/MrSkwiggs/Netswift", .exact(.init(0, 3, 1))),
    ],
    targets: [
        .target(
            name: "flucs",
            dependencies: ["Netswift"],
            path: "Sources",
            resources: [
                .copy("Templates")
            ]),
        
        .testTarget(
            name: "flucsTests",
            dependencies: ["flucs"]),
    ]
)

My folder structure:

folder structure

How can I distribute my script so that it also includes its resources?

Skwiggs
  • 1,348
  • 2
  • 17
  • 42

1 Answers1

3

SPM compiles your resources to a separate bundle but command line tool is just an executable without a bundle and any resources you add to your executable is simply ignored by Xcode (Build Phases > Copy Bundle Resources) for Release(Archive) builds.

If you look inside Bundle.module you can find:

...
// For command-line tools.
Bundle.main.bundleURL,
...

Where Bundle.main.bundleURL is a valid file url for the directory containing your command line executable so that it looks for your bundle next to your executable. And it works for Debug because XCode just compiles your resource bundle near your executable.

The simplest way to get Release executable with compiled .bundle file is build your package from command line:

swift build --configuration release

And then you can find them both in .build/release folder.

iUrii
  • 11,742
  • 1
  • 33
  • 48
  • But so, if I want to distribute my script, does that mean I always have to do so together with the bundle?? This is no really convenient :/ – Skwiggs Dec 01 '20 at 13:13
  • @Skwiggs One possible solution with Swift Package is moving your templates as strings to your code and they will be compiled to the binary. But you can always get rid of Swift Package and make application (.app) that supports bundles instead of command line (pure binary). – iUrii Dec 01 '20 at 14:20
  • Yeah for now I'm including the raw template text as variables in my code... not super handy but easier than writing an actual app – Skwiggs Dec 01 '20 at 16:29