nicklockwood / SwiftFormat

A command-line tool and Xcode Extension for formatting Swift code
MIT License
7.63k stars 623 forks source link

Keep getting "The file has been changed by another application" Xcode error when building #1178

Open bpisano opened 2 years ago

bpisano commented 2 years ago

Hi everyone, I'm having a weird issue with SwiftFormat and I would like to know if you could help me find a workaround for it.

Description

This issue could be related to Xcode, but as I was not able to find anything on the web about it, I decided to open an issue here. After installing SwiftFormat and added a build phase script, I keep getting this error when building my Xcode project:

Capture d’écran 2022-05-10 à 11 13 32

This is probably due to Xcode file watcher not working well and not detecting the changes made by SwiftFormat. One of the solution is to make an automator script to call SwiftFormat when ⌘S a file on Xcode. But this doesn't work with autosave so you have to think about manually formatting each file.

Does anyone have already faced this issue ? Any help would be very appreciated. Thanks in advance.

Infos

SwiftFormat version: 0.49.8 macOS version: 12.3.1 (21E258) Xcode version: 13.3.1 (13E500a) The project use workspaces: NO The project use Swift Packages: YES Location of the build phase script in the build phase: right after the Dependencies Build phase script:

export PATH="$PATH:/opt/homebrew/bin"

if which swiftformat >/dev/null; then
  swiftformat .
else
  echo "warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat"
fi
nicklockwood commented 2 years ago

I'd suggest only running SwiftFormat in --lint mode for a build phase script, or alternatively setting it yo format only when you run the unit tests. The problem with having it format on every build is that it overwrites the files as they are being compiled, causing the issue you're seeing.

bpisano commented 2 years ago

Thanks for your quick reply. This in fact a working solution. But I was initially looking for a formater such as ESLint but for Swift, running on Xcode. And adding --lint as an option remove as expected the auto formatting feature, and I still get the error after building my unit tests.

The issue is probably not on your side. I really suspect the Xcode file watcher to be the cause here. But even if there is no workaround, I'll keep using SwiftFormat. The tool is really worth it despite this annoying warning.

Here is a link for the solution I'm using for now. It use automator to trigger SwiftFormat when ⌘S in an Xcode file.

dangalasko commented 1 year ago

I don't think its the file watcher. If you're using SwiftUI, Xcode auto-builds the project whenever you make changes to keep the canvas live. If you have a build phase (like SwiftFormat) that modifies files then this will wreck havoc.

dangalasko commented 1 year ago

My suggestion @nicklockwood @bpisano is to explicitly return in the build phase (I have tested this). Whilst I agree with having it in tests, I can see value in supporting it in non test targets as well.

Update your script to return early like so:

if [ "${ENABLE_PREVIEWS}" = "YES" ]; then
  echo "Not running Swift Format for Xcode Previews"
  exit 0;
fi