SwiftFormat icon indicating copy to clipboard operation
SwiftFormat copied to clipboard

error: Failed to write file <File Location>

Open NoamEfergan opened this issue 2 years ago • 11 comments

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?

NoamEfergan avatar Oct 11 '23 13:10 NoamEfergan

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.

nicklockwood avatar Oct 11 '23 15:10 nicklockwood

i have on the main app, but on the package i can't (or at least don't know where?)

NoamEfergan avatar Oct 11 '23 15:10 NoamEfergan

Yeah, I'm not sure either I'm afraid. It's not a use-case I've tried myself.

nicklockwood avatar Oct 11 '23 15:10 nicklockwood

if i find a fix i'll post it here, maybe even (if i'm lucky!) i'll contribute!

NoamEfergan avatar Oct 11 '23 15:10 NoamEfergan

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

NoamEfergan avatar Nov 01 '23 16:11 NoamEfergan

I hit the same situation.

@NoamKitman Do you mean it's impossible to write files from Command/Build Plugins?

giginet avatar Nov 24 '23 05:11 giginet

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 avatar Nov 24 '23 08:11 giginet

@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?

image

NoamEfergan avatar Nov 24 '23 08:11 NoamEfergan

You can pass the option with CLI arguments.

$ swift package plugin --allow-writing-to-directory . your_plugin

See swift package plugin --help for details.

giginet avatar Nov 24 '23 08:11 giginet

I tried this as a command plugin. But your question is for Build Tools plugins. So it may not help you.

giginet avatar Nov 24 '23 08:11 giginet

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!

NoamEfergan avatar Nov 24 '23 08:11 NoamEfergan