Package pre build script execution

Hello, i am currently trying to implement a pre build script execution in a package. I am using this tutorial to implement it. But it only shows how to use the pre build feature with an already existing feature. I want to execute a skript on my pc every time i build the project. I can't use apples prebuild skript feature in the build settings because it is a package.

Right now my code looks like this:

import Foundation
import OSLog
import PackagePlugin


@main struct GenerateLocalizer: BuildToolPlugin {

    do {
      let commandlineOutput = try shell("./testScript.sh")

    } catch {

    }
    return [.prebuildCommand(displayName: "Generate Strings", executable: PackagePlugin.Path("./scrips/generate_strings.sh"), arguments: [], outputFilesDirectory: target.directory)]
  }

  func shell(_ command: String) throws -> String {
    let task = Process()
    let pipe = Pipe()
    task.standardOutput = pipe
    task.standardError = pipe
    task.arguments = [command]
    os_log("%{public}@", log: log, task.arguments?.joined(separator: " ") ?? "not found")
    task.launchPath = "/bin/zsh"
    task.standardInput = nil
    try task.run()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = String(data: data, encoding: .utf8)!

    return output
  }
}


and my Package file looks something like that

      name: "CustomSdk",
      dependencies: ["CustomSdk-Objc"],
      path: "CustomSdk",
      exclude: ["Info.plist", "CustomSdk.podspec"],
      plugins: [
        .plugin(name: "GenerateLocalizer")
      ]
    ),

    .plugin(name: "GenerateLocalizer",
        capability: .buildTool(),
        dependencies: ["CustomSdk-Objc"]
    )

It gets called properly but when want to write files in my "testScript.sh" it only says: Operation not permitted.

Anyone got any ideas how to fix this or is there another way to utitlize custom scripts with custom packages?

Greetings Ben

Post not yet marked as solved Up vote post of benkai Down vote post of benkai
2.3k views

Replies

Did you ever find an answer? I'm facing the same situation!

Also facing the same situation.

I'd like to run a script that generates code (the script is in the package directory, and the generated code should also end up in the package directory).

Using a buildTool plugin, I can get the plugin to run before each build, but cannot get it to save files outside of DerivedData directory, which is the issue @benkai is hitting.

If I change it to a command() plugin, I can get it to write to the package directory, but can't figure out how to run it without manually typing swift package <command>.

Has anyone discovered if it's possible to do both:

  1. Run a script before each package build (like a .buildTool plugin)
  2. Write to the package directory (like a command plugin)

How can I just give my buildTool plugin permission to write anywhere?