diff --git a/CHANGELOG.md b/CHANGELOG.md
index a659ed9b..54eac105 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@
- Fixed duplicate addition of carthage static frameworks. [#829](https://github.com/yonaskolb/XcodeGen/pull/829) @funzin
- Fix handling of SWIFT_INSTALL_OBJC_HEADER when its value is YES/NO. [#827](https://github.com/yonaskolb/XcodeGen/pull/827) @ileitch
- Set `preActions` and `postActions` on the `build` action of a TargetScheme instead of the other actions. [#823](https://github.com/yonaskolb/XcodeGen/pull/823) @brentleyjones
+- Implicitly include bundles in the Copy Bundle Resources build phase. [#838](https://github.com/yonaskolb/XcodeGen/pull/838) @skirchmeier
## 2.15.1
diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift
index ca13ccaa..c4a93704 100644
--- a/Sources/XcodeGenKit/SourceGenerator.swift
+++ b/Sources/XcodeGenKit/SourceGenerator.swift
@@ -413,14 +413,13 @@ class SourceGenerator {
let children = try getSourceChildren(targetSource: targetSource, dirPath: path, excludePaths: excludePaths, includePaths: includePaths)
let createIntermediateGroups = targetSource.createIntermediateGroups ?? project.options.createIntermediateGroups
- let directoryExtensionsToSkip = ["lproj", "bundle", "xcassets", "xcdatamodeld"]
+ let specialDirectoryExtensions: [String?] = ["bundle", "lproj", "xcassets", "xcdatamodeld"]
let directories = children
- .filter { $0.isDirectory && !directoryExtensionsToSkip.contains($0.extension ?? "") }
+ .filter { $0.isDirectory && !specialDirectoryExtensions.contains($0.extension) }
- let whitelistedDirectoryExtensionsForFilePath = ["xcdatamodeld", "xcdatamodel" , "xcassets"]
let filePaths = children
- .filter { $0.isFile || $0.extension != nil && $0.extension != "lproj" && (whitelistedDirectoryExtensionsForFilePath.contains($0.extension ?? "") || !$0.isDirectory) }
+ .filter { $0.isFile || $0.isDirectory && $0.extension != "lproj" && specialDirectoryExtensions.contains($0.extension) }
let localisedDirectories = children
.filter { $0.extension == "lproj" }
diff --git a/Tests/Fixtures/TestProject/App_iOS/Settings.bundle/Root.plist b/Tests/Fixtures/TestProject/App_iOS/Settings.bundle/Root.plist
new file mode 100644
index 00000000..b1b6fea5
--- /dev/null
+++ b/Tests/Fixtures/TestProject/App_iOS/Settings.bundle/Root.plist
@@ -0,0 +1,61 @@
+
+
+
+
+ StringsTable
+ Root
+ PreferenceSpecifiers
+
+
+ Type
+ PSGroupSpecifier
+ Title
+ Group
+
+
+ Type
+ PSTextFieldSpecifier
+ Title
+ Name
+ Key
+ name_preference
+ DefaultValue
+
+ IsSecure
+
+ KeyboardType
+ Alphabet
+ AutocapitalizationType
+ None
+ AutocorrectionType
+ No
+
+
+ Type
+ PSToggleSwitchSpecifier
+ Title
+ Enabled
+ Key
+ enabled_preference
+ DefaultValue
+
+
+
+ Type
+ PSSliderSpecifier
+ Key
+ slider_preference
+ DefaultValue
+ 0.5
+ MinimumValue
+ 0
+ MaximumValue
+ 1
+ MinimumValueImage
+
+ MaximumValueImage
+
+
+
+
+
diff --git a/Tests/Fixtures/TestProject/App_iOS/Settings.bundle/en.lproj/Root.strings b/Tests/Fixtures/TestProject/App_iOS/Settings.bundle/en.lproj/Root.strings
new file mode 100644
index 00000000..8cd87b9d
Binary files /dev/null and b/Tests/Fixtures/TestProject/App_iOS/Settings.bundle/en.lproj/Root.strings differ
diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj
index 194539f4..b3446959 100644
--- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj
+++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj
@@ -43,6 +43,7 @@
262891CCD5F74316610437FA /* Framework2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3EF21DF245F66BEF5446AAEF /* Framework2.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
265B6A05C0198FD2EB485173 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93C033648A37D95027845BD3 /* main.swift */; };
2730C6D0A35AED4ADD6EDF17 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0704B6CAFBB53E0EBB08F6B3 /* ViewController.swift */; settings = {COMPILER_FLAGS = "-Werror"; }; };
+ 28A96EBC76D53817AABDA91C /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8AF20308873AEEEC4D8C45D1 /* Settings.bundle */; };
2A5356FCC03EE312F1738C61 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09B82F603D981398F38D762E /* AppDelegate.swift */; };
2A7EB1A9A365A7EC5D49AFCF /* LocalizedStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0C6BA0D12467A13EC012C728 /* LocalizedStoryboard.storyboard */; };
2B940E57041A72E6A39B6BF0 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C872631362DDBAFCE71E5C66 /* Interface.storyboard */; };
@@ -526,6 +527,7 @@
86169DEEDEAF09AB89C8A31D /* libStaticLibrary_ObjC.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libStaticLibrary_ObjC.a; sourceTree = BUILT_PRODUCTS_DIR; };
87DF9DCA8399E3214A7E27CF /* TestProjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestProjectTests.swift; sourceTree = ""; };
8A9274BE42A03DC5DA1FAD04 /* Framework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Framework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8AF20308873AEEEC4D8C45D1 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; };
8CAF6C55B555E3E1352645B6 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = ""; };
8CB86294FB939FE6E90932E1 /* libStaticLibrary_Swift.a */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = archive.ar; path = libStaticLibrary_Swift.a; sourceTree = BUILT_PRODUCTS_DIR; };
93C033648A37D95027845BD3 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; };
@@ -704,6 +706,7 @@
306796628DD52FA55E833B65 /* Model.xcdatamodeld */,
C7809CE9FE9852C2AA87ACE5 /* module.modulemap */,
553D289724905857912C7A1D /* outputList.xcfilelist */,
+ 8AF20308873AEEEC4D8C45D1 /* Settings.bundle */,
0704B6CAFBB53E0EBB08F6B3 /* ViewController.swift */,
);
name = App;
@@ -1748,6 +1751,7 @@
49A4B8937BB5520B36EA33F0 /* Main.storyboard in Resources */,
900CFAD929CAEE3861127627 /* MyBundle.bundle in Resources */,
C88598A49087A212990F4E8B /* ResourceFolder in Resources */,
+ 28A96EBC76D53817AABDA91C /* Settings.bundle in Resources */,
E8A135F768448632F8D77C8F /* StandaloneAssets.xcassets in Resources */,
818D448D4DDD6649B5B26098 /* example.mp4 in Resources */,
2C7C03B45571A13D472D6B23 /* iMessageApp.app in Resources */,
diff --git a/Tests/XcodeGenKitTests/SourceGeneratorTests.swift b/Tests/XcodeGenKitTests/SourceGeneratorTests.swift
index 452cd4c1..4555c652 100644
--- a/Tests/XcodeGenKitTests/SourceGeneratorTests.swift
+++ b/Tests/XcodeGenKitTests/SourceGeneratorTests.swift
@@ -576,6 +576,12 @@ class SourceGeneratorTests: XCTestCase {
- file.mlmodel
- Info.plist
- Intent.intentdefinition
+ - Settings.bundle:
+ - en.lproj:
+ - Root.strings
+ - Root.plist
+ - WithPeriod2.0:
+ - file.swift
"""
try createDirectories(directories)
@@ -625,6 +631,12 @@ class SourceGeneratorTests: XCTestCase {
try pbxProj.expectFile(paths: ["C", "file.metal"], buildPhase: .sources)
try pbxProj.expectFile(paths: ["C", "file.mlmodel"], buildPhase: .sources)
try pbxProj.expectFile(paths: ["C", "Intent.intentdefinition"], buildPhase: .sources)
+ try pbxProj.expectFile(paths: ["C", "Settings.bundle"], buildPhase: .resources)
+ try pbxProj.expectFileMissing(paths: ["C", "Settings.bundle", "en.lproj"])
+ try pbxProj.expectFileMissing(paths: ["C", "Settings.bundle", "en.lproj", "Root.strings"])
+ try pbxProj.expectFileMissing(paths: ["C", "Settings.bundle", "Root.plist"])
+ try pbxProj.expectFileMissing(paths: ["C", "WithPeriod2.0"])
+ try pbxProj.expectFile(paths: ["C", "WithPeriod2.0", "file.swift"], buildPhase: .sources)
}
$0.it("duplicate TargetSource is included once in sources build phase") {