diff --git a/Fixtures/Miscellaneous/TIF/Package.swift b/Fixtures/Miscellaneous/TIF/Package.swift new file mode 100644 index 00000000000..b14b92366c2 --- /dev/null +++ b/Fixtures/Miscellaneous/TIF/Package.swift @@ -0,0 +1,17 @@ +// swift-tools-version:5.3 +import PackageDescription + +let package = Package( + name: "TIF", + products: [ + .library(name: "TIF", targets: ["TIF"]) + ], + targets: [ + .target( + name: "TIF", + resources: [ + .copy("some.txt") + ] + ), + ] +) diff --git a/Fixtures/Miscellaneous/TIF/README.md b/Fixtures/Miscellaneous/TIF/README.md new file mode 100644 index 00000000000..e32520dc79b --- /dev/null +++ b/Fixtures/Miscellaneous/TIF/README.md @@ -0,0 +1,3 @@ +# TIF + +A description of this package. diff --git a/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAlert.swift b/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAlert.swift new file mode 100644 index 00000000000..9f0895cc761 --- /dev/null +++ b/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAlert.swift @@ -0,0 +1,26 @@ +// +// SomeAlert.swift +// MyFwk +// +// Created by ankit on 10/31/19. +// Copyright © 2019 Ankit. All rights reserved. +// + +import Cocoa + +public class SomeAlert: NSViewController { + + @IBOutlet var label: NSTextField! + + override public func viewDidLoad() { + super.viewDidLoad() + let bundlePath = Bundle.main.path(forResource: "TIF_TIF", ofType: "bundle")! + let bundle = Bundle(path: bundlePath)! + + let txt = bundle.path(forResource: "some", ofType: "txt")! + let c = FileManager.default.contents(atPath: txt)! + + label.stringValue = String(data:c, encoding: .utf8)! + // Do view setup here. + } +} diff --git a/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAlert.xib b/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAlert.xib new file mode 100644 index 00000000000..25914673c2c --- /dev/null +++ b/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAlert.xib @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAssets.xcassets/Contents.json b/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAssets.xcassets/Contents.json new file mode 100644 index 00000000000..73c00596a7f --- /dev/null +++ b/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAssets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAssets.xcassets/this_is_fine.imageset/Contents.json b/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAssets.xcassets/this_is_fine.imageset/Contents.json new file mode 100644 index 00000000000..516317731f0 --- /dev/null +++ b/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAssets.xcassets/this_is_fine.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "this_is_fine.jpg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAssets.xcassets/this_is_fine.imageset/this_is_fine.jpg b/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAssets.xcassets/this_is_fine.imageset/this_is_fine.jpg new file mode 100644 index 00000000000..3c605bfd150 Binary files /dev/null and b/Fixtures/Miscellaneous/TIF/Sources/TIF/SomeAssets.xcassets/this_is_fine.imageset/this_is_fine.jpg differ diff --git a/Fixtures/Miscellaneous/TIF/Sources/TIF/some.txt b/Fixtures/Miscellaneous/TIF/Sources/TIF/some.txt new file mode 100644 index 00000000000..4662991d0b5 --- /dev/null +++ b/Fixtures/Miscellaneous/TIF/Sources/TIF/some.txt @@ -0,0 +1 @@ +This is being read from some.txt file in the bundle. diff --git a/Sources/SwiftBuildSupport/PackagePIFProjectBuilder.swift b/Sources/SwiftBuildSupport/PackagePIFProjectBuilder.swift index 391fb15be9d..6684a2e5e9e 100644 --- a/Sources/SwiftBuildSupport/PackagePIFProjectBuilder.swift +++ b/Sources/SwiftBuildSupport/PackagePIFProjectBuilder.swift @@ -211,6 +211,9 @@ struct PackagePIFProjectBuilder { settings[.PRODUCT_MODULE_NAME] = bundleName settings[.PRODUCT_BUNDLE_IDENTIFIER] = "\(self.package.identity).\(module.name).resources" .spm_mangledToBundleIdentifier() + // Resource bundles are not executable. Setting the name to an empty string will + // omit the CFBundleExecutable key from the Info.plist. + settings[.EXECUTABLE_NAME] = "" settings[.GENERATE_INFOPLIST_FILE] = "YES" settings[.PACKAGE_RESOURCE_TARGET_KIND] = "resource" diff --git a/Tests/CommandsTests/BuildCommandTests.swift b/Tests/CommandsTests/BuildCommandTests.swift index 59cef0466b2..35eca4d2c1d 100644 --- a/Tests/CommandsTests/BuildCommandTests.swift +++ b/Tests/CommandsTests/BuildCommandTests.swift @@ -1760,6 +1760,45 @@ struct BuildCommandTestCases { data.config == .release } } + + @Test( + .requireHostOS(.macOS), + .tags( + .Feature.CommandLineArguments.BuildSystem, + .Feature.CommandLineArguments.Configuration, + ), + arguments: getBuildData(for: [.swiftbuild]), + ) + func trivialPackageResources( + data: BuildData, + ) async throws { + let buildSystem = data.buildSystem + try await fixture(name: "Miscellaneous/TIF") { fixturePath in + let result = try await build( + [], + packagePath: fixturePath, + configuration: data.config, + cleanAfterward: false, + buildSystem: buildSystem, + ) + try #require(result.binContents.contains("TIF_TIF.bundle")) + let contentsDir = result.binPath.appending("TIF_TIF.bundle", "Contents") + let bundleResourceDir = contentsDir.appending("Resources") + + let bundleResources = try localFileSystem.getDirectoryContents(bundleResourceDir) + #expect(bundleResources.contains("some.txt")) + #expect(bundleResources.contains("Assets.car")) + #expect(bundleResources.contains("SomeAlert.nib")) + + // Check that the Info.plist of the resource bundle looks reasonable. In particular, it shouldn't have a CFBundleExecutable key, since it's a codeless bundle. + let infoPlistPath = contentsDir.appending("Info.plist") + let infoPlistBytes = try localFileSystem.readFileContents(infoPlistPath) + let infoPlist = try infoPlistBytes.withData({ + try #require(PropertyListSerialization.propertyList(from: $0, options: [], format: nil) as? NSDictionary, "couldn't parse built resource bundle's Info.plist as a property list") + }) + #expect(infoPlist["CFBundleExecutable"] == nil, "Expected CFBundleExecutable to be omitted from the Info.plist of a codeless resource bundle") + } + } } extension Triple {