error: Failed to write file <File Location>
I'm trying to run SwiftFormat whenever my SPM package builds (when it's not embedded in an app. when it is, it's just a build phase) To do so i've got the following:
// MARK: - CodeFormatPlugin
enum CodeFormatPlugin {
static let name = "CodeFormatPlugin"
static var plugin: Product {
.plugin(name: name, targets: [name])
}
static var pluginTarget: Target {
.plugin(name: name,
capability: .buildTool(),
dependencies: ["klswiftformat"])
}
static var swiftformatBinaryTarget: Target {
.binaryTarget(name: "klswiftformat",
url: "https://github.com/nicklockwood/SwiftFormat/releases/download/0.52.2/swiftformat.artifactbundle.zip",
checksum: "af5f0d8854bc88ffd1120cb65782c24f6794c3fdbb01fdc68cd0115473c3cfa0")
}
}
and in my Package.swift file:
...
products: [
CodeFormatPlugin.plugin,
...
targets: [
CodeFormatPlugin.swiftformatBinaryTarget,
CodeFormatPlugin.pluginTarget,
The actual file looks like this:
import Foundation
import PackagePlugin
// MARK: - CodeFormatPlugin
@main
struct CodeFormatPlugin {}
// MARK: BuildToolPlugin
extension CodeFormatPlugin: BuildToolPlugin {
func createBuildCommands(context: PackagePlugin.PluginContext,
target: PackagePlugin.Target) async throws -> [PackagePlugin.Command] {
// We don't want this to run on the CI, since it creates errors.
guard ProcessInfo.processInfo.environment["CIRCLECI"] == nil else {
return []
}
guard let _ = target as? SourceModuleTarget else {
return []
}
let tool = try context.tool(named: "swiftformat")
let output = context.pluginWorkDirectory
let packageDir = context.package.directory.string
return [
.prebuildCommand(displayName: "CodeFormatPlugin: Run swiftformat at: \(packageDir)",
executable: tool.path,
arguments: [
packageDir
],
outputFilesDirectory: output)
]
}
}
Any idea what i might be doing wrong?
Have you disabled script sandboxing?
NOTE (2): If you are using Xcode 15 or later, make sure that the ENABLE_USER_SCRIPT_SANDBOXING (aka "User Script Sandboxing") option is set to NO, otherwise SwiftFormat won't be able to run correctly.
i have on the main app, but on the package i can't (or at least don't know where?)
Yeah, I'm not sure either I'm afraid. It's not a use-case I've tried myself.
if i find a fix i'll post it here, maybe even (if i'm lucky!) i'll contribute!
Just to confirm, to fix was found on my side, and there seems to be no way to have the tool run on a package from the package
I hit the same situation.
@NoamKitman Do you mean it's impossible to write files from Command/Build Plugins?
How about using --allow-writing-to-directory . instead of --allow-writing-to-package-directory?
I tried passing this option, it seems to work fine. Please try this.
@giginet passing that where ? the only one i can see is writeToPackageDirectory. or do you pass it in as pre build thing from Xcode iteself?
You can pass the option with CLI arguments.
$ swift package plugin --allow-writing-to-directory . your_plugin
See swift package plugin --help for details.
I tried this as a command plugin. But your question is for Build Tools plugins. So it may not help you.
hmm yeah my issue is that i wanted it to run on the project every time i build. thanks for the attempt to help thought!