diff --git a/tools/generators/files_and_groups/src/ElementCreator/CreateFileElement.swift b/tools/generators/files_and_groups/src/ElementCreator/CreateFileElement.swift index 6f74eee377..32a6875a3e 100644 --- a/tools/generators/files_and_groups/src/ElementCreator/CreateFileElement.swift +++ b/tools/generators/files_and_groups/src/ElementCreator/CreateFileElement.swift @@ -93,7 +93,8 @@ extension ElementCreator.CreateFileElement { let content = """ {isa = PBXFileReference; \ \(calculateFileTypeType(basename: name, extension: impliedExt)) = \( - impliedExt.flatMap(Xcode.pbxProjEscapedFileType) ?? "file" + impliedExt.flatMap(Xcode.pbxProjEscapedFileType) ?? + Xcode.unknownFileType ); \ \(nameAttribute)\ path = \(attributes.elementAttributes.path.pbxProjEscaped); \ diff --git a/tools/generators/files_and_groups/src/ElementCreator/CreateLocalizedFileElement.swift b/tools/generators/files_and_groups/src/ElementCreator/CreateLocalizedFileElement.swift index 3fca4fe06c..17fc71b9b5 100644 --- a/tools/generators/files_and_groups/src/ElementCreator/CreateLocalizedFileElement.swift +++ b/tools/generators/files_and_groups/src/ElementCreator/CreateLocalizedFileElement.swift @@ -66,7 +66,7 @@ extension ElementCreator.CreateLocalizedFileElement { fileTypeType = "lastKnownFileType" fileType = ext .flatMap { Xcode.pbxProjEscapedFileType(extension: $0) } ?? - "file" + Xcode.unknownFileType } let content = """ diff --git a/tools/generators/files_and_groups/src/Xcode.swift b/tools/generators/files_and_groups/src/Xcode.swift index fe4e182892..5c10d38f04 100644 --- a/tools/generators/files_and_groups/src/Xcode.swift +++ b/tools/generators/files_and_groups/src/Xcode.swift @@ -273,6 +273,17 @@ enum Xcode { "Podfile": "rb", ] + /// The `lastKnownFileType` used for files whose extension isn't in + /// `pbxProjEscapedFileTypes`. + /// + /// Xcode determines the type of such files by sniffing their contents, + /// and writes `text` for text files (e.g. `.graphql`, `LICENSE`) and + /// `file` for binary ones. We only see paths (and the files might not + /// exist yet, e.g. generated files), so we use `text`, as unknown files in + /// source trees are overwhelmingly text. Matching Xcode prevents it from + /// rewriting the `project.pbxproj` when it next saves the project. + public static let unknownFileType = "text" + /// Returns the Xcode file type for any given extension. /// /// - Parameters: diff --git a/tools/generators/files_and_groups/test/ElementCreator/CreateFileElementTests.swift b/tools/generators/files_and_groups/test/ElementCreator/CreateFileElementTests.swift index 77e21b1d18..669287bf44 100644 --- a/tools/generators/files_and_groups/test/ElementCreator/CreateFileElementTests.swift +++ b/tools/generators/files_and_groups/test/ElementCreator/CreateFileElementTests.swift @@ -125,7 +125,7 @@ final class CreateFileElementTests: XCTestCase { ) let expectedContent = #""" -{isa = PBXFileReference; lastKnownFileType = file; path = "a path"; sourceTree = SOURCE_ROOT; } +{isa = PBXFileReference; lastKnownFileType = text; path = "a path"; sourceTree = SOURCE_ROOT; } """# // Act @@ -160,7 +160,7 @@ final class CreateFileElementTests: XCTestCase { ) let expectedContent = #""" -{isa = PBXFileReference; lastKnownFileType = file; path = a_path; sourceTree = ""; } +{isa = PBXFileReference; lastKnownFileType = text; path = a_path; sourceTree = ""; } """# // Act @@ -428,7 +428,7 @@ final class CreateFileElementTests: XCTestCase { ) let expectedContent = #""" -{isa = PBXFileReference; lastKnownFileType = file; name = "a name"; path = a_path; sourceTree = ""; } +{isa = PBXFileReference; lastKnownFileType = text; name = "a name"; path = a_path; sourceTree = ""; } """# // Act