diff --git a/Sources/TuistCore/Graph/Graph.swift b/Sources/TuistCore/Graph/Graph.swift index dad8d43f984..acac19ead39 100644 --- a/Sources/TuistCore/Graph/Graph.swift +++ b/Sources/TuistCore/Graph/Graph.swift @@ -464,9 +464,9 @@ extension Graph { // swiftlint:disable:next line_length func frameworkUsesDynamicLinking(frameworkMetadataProvider: FrameworkMetadataProviding = FrameworkMetadataProvider()) -> (_ frameworkNode: PrecompiledNode) -> Bool { { frameworkNode in - let isDynamicLink = try? frameworkMetadataProvider.linking(precompiled: frameworkNode) == .dynamic - return isDynamicLink ?? false - } + let isDynamicLink = try? frameworkMetadataProvider.linking(precompiled: frameworkNode) == .dynamic + return isDynamicLink ?? false + } } } diff --git a/Sources/TuistKit/Cache/XCFrameworkBuilder.swift b/Sources/TuistKit/Cache/XCFrameworkBuilder.swift index c9a92a78b1e..bc2d6f9a46c 100644 --- a/Sources/TuistKit/Cache/XCFrameworkBuilder.swift +++ b/Sources/TuistKit/Cache/XCFrameworkBuilder.swift @@ -43,19 +43,32 @@ protocol XCFrameworkBuilding { } final class XCFrameworkBuilder: XCFrameworkBuilding { + // MARK: - Attributes + + /// When true the builder outputs the output from xcodebuild. + private let printOutput: Bool + + // MARK: - Init + + /// Initializes the builder. + /// - Parameter printOutput: When true the builder outputs the output from xcodebuild. + init(printOutput: Bool = true) { + self.printOutput = printOutput + } + // MARK: - XCFrameworkBuilding func build(workspacePath: AbsolutePath, target: Target) throws -> AbsolutePath { - return try build(arguments: ["-workspace", workspacePath.pathString], target: target) + try build(arguments: ["-workspace", workspacePath.pathString], target: target) } func build(projectPath: AbsolutePath, target: Target) throws -> AbsolutePath { - return try build(arguments: ["-workspace", projectPath.pathString], target: target) + try build(arguments: ["-project", projectPath.pathString], target: target) } // MARK: - Fileprivate - fileprivate func build(arguments _: [String], target: Target) throws -> AbsolutePath { + fileprivate func build(arguments: [String], target: Target) throws -> AbsolutePath { if target.product != .framework { throw XCFrameworkBuilderError.nonFrameworkTarget(target.name) } @@ -73,8 +86,9 @@ final class XCFrameworkBuilder: XCFrameworkBuilding { sdk: target.platform.xcodeDeviceSDK, derivedDataPath: derivedDataPath.path) deviceArguments.append(contentsOf: ["-archivePath", deviceArchivePath.pathString]) + deviceArguments.append(contentsOf: arguments) Printer.shared.print(subsection: "Building \(target.productName) for device") - try System.shared.runAndPrint(deviceArguments) + try runCommand(deviceArguments) // Build for the simulator var simulatorArchivePath: AbsolutePath? @@ -82,11 +96,12 @@ final class XCFrameworkBuilder: XCFrameworkBuilding { simulatorArchivePath = derivedDataPath.path.appending(component: "simulator.xcarchive") var simulatorArguments = xcodebuildCommand(scheme: target.name, destination: target.platform.xcodeSimulatorDestination!, - sdk: target.platform.xcodeDeviceSDK, + sdk: target.platform.xcodeSimulatorSDK!, derivedDataPath: derivedDataPath.path) simulatorArguments.append(contentsOf: ["-archivePath", simulatorArchivePath!.pathString]) + simulatorArguments.append(contentsOf: arguments) Printer.shared.print(subsection: "Building \(target.productName) for simulator") - try System.shared.runAndPrint(simulatorArguments) + try runCommand(simulatorArguments) } // Build the xcframework @@ -96,11 +111,21 @@ final class XCFrameworkBuilder: XCFrameworkBuilding { simulatorArchivePath: simulatorArchivePath, productName: target.productName, xcframeworkPath: xcframeworkPath) - try System.shared.runAndPrint(xcframeworkArguments) + try runCommand(xcframeworkArguments) return xcframeworkPath } + /// Runs the given command. + /// - Parameter arguments: Command arguments. + fileprivate func runCommand(_ arguments: [String]) throws { + if printOutput { + try System.shared.runAndPrint(arguments) + } else { + try System.shared.run(arguments) + } + } + /// Returns the arguments that should be passed to xcodebuild to compile for a device on the given platform. /// - Parameter platform: Platform we are compiling for. fileprivate func deviceDestination(platform: Platform) -> String { @@ -141,7 +166,7 @@ final class XCFrameworkBuilder: XCFrameworkBuilding { var command = ["xcrun", "xcodebuild", "clean", "archive"] command.append(contentsOf: ["-scheme", scheme.spm_shellEscaped()]) command.append(contentsOf: ["-sdk", sdk]) - command.append(contentsOf: ["-destination", destination]) + command.append(contentsOf: ["-destination='\(destination)'"]) command.append(contentsOf: ["-derivedDataPath", derivedDataPath.pathString]) command.append(contentsOf: ["SKIP_INSTALL=NO", "BUILD_LIBRARY_FOR_DISTRIBUTION=YES"]) return command diff --git a/Sources/TuistSupportTesting/TestCase/TuistTestCase.swift b/Sources/TuistSupportTesting/TestCase/TuistTestCase.swift index b0acfd0f4f7..b1f56374975 100644 --- a/Sources/TuistSupportTesting/TestCase/TuistTestCase.swift +++ b/Sources/TuistSupportTesting/TestCase/TuistTestCase.swift @@ -102,4 +102,12 @@ public class TuistTestCase: XCTestCase { """ XCTAssertTrue(printer.standardErrorMatches(with: expected), message, file: file, line: line) } + + public func temporaryFixture(_ pathString: String) -> AbsolutePath { + let path = RelativePath(pathString) + let fixturePath = self.fixturePath(path: path) + let destinationPath = (try! temporaryPath()).appending(component: path.basename) + try! FileHandler.shared.copy(from: fixturePath, to: destinationPath) + return destinationPath + } } diff --git a/Tests/TuistCoreIntegrationTests/Utils/FrameworkMetadataProviderIntegrationTests.swift b/Tests/TuistCoreIntegrationTests/Utils/FrameworkMetadataProviderIntegrationTests.swift index 0c303db180e..5b99defe5ef 100644 --- a/Tests/TuistCoreIntegrationTests/Utils/FrameworkMetadataProviderIntegrationTests.swift +++ b/Tests/TuistCoreIntegrationTests/Utils/FrameworkMetadataProviderIntegrationTests.swift @@ -47,12 +47,4 @@ final class FrameworkMetadataProviderIntegrationTests: TuistTestCase { // Then XCTAssertTrue(got == carthagePath.appending(component: "\(frameworkPath.basename).dSYM")) } - - fileprivate func temporaryFixture(_ pathString: String) -> AbsolutePath { - let path = RelativePath(pathString) - let fixturePath = self.fixturePath(path: path) - let destinationPath = (try! temporaryPath()).appending(component: path.basename) - try! FileHandler.shared.copy(from: fixturePath, to: destinationPath) - return destinationPath - } } diff --git a/Tests/TuistCoreIntegrationTests/Utils/PrecompiledMetadataProviderIntegrationTests.swift b/Tests/TuistCoreIntegrationTests/Utils/PrecompiledMetadataProviderIntegrationTests.swift index b6fa699a1cc..3fab00f63cf 100644 --- a/Tests/TuistCoreIntegrationTests/Utils/PrecompiledMetadataProviderIntegrationTests.swift +++ b/Tests/TuistCoreIntegrationTests/Utils/PrecompiledMetadataProviderIntegrationTests.swift @@ -46,12 +46,4 @@ final class PrecompiledMetadataProviderIntegrationTests: TuistTestCase { ]) XCTAssertEqual(got, expected) } - - fileprivate func temporaryFixture(_ pathString: String) -> AbsolutePath { - let path = RelativePath(pathString) - let fixturePath = self.fixturePath(path: path) - let destinationPath = (try! temporaryPath()).appending(component: path.basename) - try! FileHandler.shared.copy(from: fixturePath, to: destinationPath) - return destinationPath - } } diff --git a/Tests/TuistGeneratorIntegrationTests/Utils/EmbedScriptGeneratorIntegrationTests.swift b/Tests/TuistGeneratorIntegrationTests/Utils/EmbedScriptGeneratorIntegrationTests.swift index 1ac6359ee8e..97483bd3dec 100644 --- a/Tests/TuistGeneratorIntegrationTests/Utils/EmbedScriptGeneratorIntegrationTests.swift +++ b/Tests/TuistGeneratorIntegrationTests/Utils/EmbedScriptGeneratorIntegrationTests.swift @@ -45,12 +45,4 @@ final class EmbedScriptGeneratorIntegrationTests: TuistTestCase { XCTAssertTrue(got.script.contains("install_bcsymbolmap \"2510FE01-4D40-3956-BB71-857D3B2D9E73.bcsymbolmap\"")) XCTAssertTrue(got.script.contains("install_bcsymbolmap \"773847A9-0D05-35AF-9865-94A9A670080B.bcsymbolmap\"")) } - - fileprivate func temporaryFixture(_ pathString: String) -> AbsolutePath { - let path = RelativePath(pathString) - let fixturePath = self.fixturePath(path: path) - let destinationPath = (try! temporaryPath()).appending(component: path.basename) - try! FileHandler.shared.copy(from: fixturePath, to: destinationPath) - return destinationPath - } } diff --git a/Tests/TuistKitIntegrationTests/Cache/XCFrameworkBuilderIntegrationTests.swift b/Tests/TuistKitIntegrationTests/Cache/XCFrameworkBuilderIntegrationTests.swift index 5d87f0498d5..5ef396b713e 100644 --- a/Tests/TuistKitIntegrationTests/Cache/XCFrameworkBuilderIntegrationTests.swift +++ b/Tests/TuistKitIntegrationTests/Cache/XCFrameworkBuilderIntegrationTests.swift @@ -39,6 +39,12 @@ final class XCFrameworkBuilderIntegrationTests: TuistTestCase { XCTAssertNotNil(infoPlist.availableLibraries.first(where: { $0.supportedArchitectures.contains("arm64") })) XCTAssertNotNil(infoPlist.availableLibraries.first(where: { $0.supportedArchitectures.contains("x86_64") })) XCTAssertTrue(infoPlist.availableLibraries.allSatisfy { $0.supportedPlatform == "ios" }) + XCTAssertPrinterOutputContains(""" + Building .xcframework for iOS + Building iOS for device + Building iOS for simulator + Exporting xcframework for iOS + """) try FileHandler.shared.delete(xcframeworkPath) } @@ -56,6 +62,11 @@ final class XCFrameworkBuilderIntegrationTests: TuistTestCase { XCTAssertTrue(FileHandler.shared.exists(xcframeworkPath)) XCTAssertNotNil(infoPlist.availableLibraries.first(where: { $0.supportedArchitectures.contains("x86_64") })) XCTAssertTrue(infoPlist.availableLibraries.allSatisfy { $0.supportedPlatform == "macos" }) + XCTAssertPrinterOutputContains(""" + Building .xcframework for macOS + Building macOS for device + Exporting xcframework for macOS + """) try FileHandler.shared.delete(xcframeworkPath) } @@ -74,6 +85,12 @@ final class XCFrameworkBuilderIntegrationTests: TuistTestCase { XCTAssertNotNil(infoPlist.availableLibraries.first(where: { $0.supportedArchitectures.contains("x86_64") })) XCTAssertNotNil(infoPlist.availableLibraries.first(where: { $0.supportedArchitectures.contains("arm64") })) XCTAssertTrue(infoPlist.availableLibraries.allSatisfy { $0.supportedPlatform == "tvos" }) + XCTAssertPrinterOutputContains(""" + Building .xcframework for tvOS + Building tvOS for device + Building tvOS for simulator + Exporting xcframework for tvOS + """) try FileHandler.shared.delete(xcframeworkPath) } @@ -93,6 +110,12 @@ final class XCFrameworkBuilderIntegrationTests: TuistTestCase { XCTAssertNotNil(infoPlist.availableLibraries.first(where: { $0.supportedArchitectures.contains("armv7k") })) XCTAssertNotNil(infoPlist.availableLibraries.first(where: { $0.supportedArchitectures.contains("arm64_32") })) XCTAssertTrue(infoPlist.availableLibraries.allSatisfy { $0.supportedPlatform == "watchos" }) + XCTAssertPrinterOutputContains(""" + Building .xcframework for watchOS + Building watchOS for device + Building watchOS for simulator + Exporting xcframework for watchOS + """) try FileHandler.shared.delete(xcframeworkPath) }