diff --git a/Tests/TuistCoreTests/Graph/Nodes/TargetNodeTests.swift b/Tests/TuistCoreTests/Graph/Nodes/TargetNodeTests.swift index 855c7232182..51973947555 100644 --- a/Tests/TuistCoreTests/Graph/Nodes/TargetNodeTests.swift +++ b/Tests/TuistCoreTests/Graph/Nodes/TargetNodeTests.swift @@ -54,7 +54,7 @@ final class TargetNodeTests: XCTestCase { let library = LibraryNode.test() let framework = FrameworkNode.test() let cocoapods = CocoaPodsNode.test() - let xcframework = try XCFrameworkNode.test() + let xcframework = XCFrameworkNode.test() let node = TargetNode(project: .test(path: AbsolutePath("/")), target: .test(name: "Target"), dependencies: [library, framework, cocoapods, xcframework]) diff --git a/Tests/TuistGeneratorTests/Generator/LinkGeneratorTests.swift b/Tests/TuistGeneratorTests/Generator/LinkGeneratorTests.swift index b921be92139..867f291092f 100644 --- a/Tests/TuistGeneratorTests/Generator/LinkGeneratorTests.swift +++ b/Tests/TuistGeneratorTests/Generator/LinkGeneratorTests.swift @@ -99,19 +99,11 @@ final class LinkGeneratorErrorTests: XCTestCase { let group = PBXGroup() pbxproj.add(object: group) - - let from = AbsolutePath("/Frameworks/") + let fileAbsolutePath = AbsolutePath("/Frameworks/Test.xcframework") - let fileRelativePath = RelativePath("./Test.xcframework") - let fileElements = ProjectFileElements() - fileElements.addFileElement(from: from, - fileAbsolutePath: fileAbsolutePath, - fileRelativePath: fileRelativePath, - name: nil, - toGroup: group, - pbxproj: pbxproj) - let wakaFile = fileElements.file(path: fileAbsolutePath) + let fileElements = createFileElements(fileAbsolutePath: fileAbsolutePath, + pbxproj: pbxproj) // When try subject.generateEmbedPhase(dependencies: dependencies, @@ -121,12 +113,13 @@ final class LinkGeneratorErrorTests: XCTestCase { sourceRootPath: sourceRootPath) // Then - let copyBuildPhase: PBXCopyFilesBuildPhase? = pbxTarget.buildPhases.last as? PBXCopyFilesBuildPhase - XCTAssertEqual(copyBuildPhase?.name, "Embed Frameworks") - let wakaBuildFile: PBXBuildFile? = copyBuildPhase?.files?.last - XCTAssertEqual(wakaBuildFile?.file, wakaFile) - let settings: [String: [String]]? = wakaBuildFile?.settings as? [String: [String]] - XCTAssertEqual(settings, ["ATTRIBUTES": ["CodeSignOnCopy"]]) + let copyBuildPhase = try XCTUnwrap(pbxTarget.embedFrameworksBuildPhases().first) + XCTAssertEqual(copyBuildPhase.name, "Embed Frameworks") + let buildFiles = try XCTUnwrap(copyBuildPhase.files) + XCTAssertEqual(buildFiles.map { $0.file?.path }, [ "Test.xcframework"]) + XCTAssertEqual(buildFiles.map { $0.settings as? [String: [String]] }, [ + ["ATTRIBUTES": ["CodeSignOnCopy"]] + ]) } func test_setupFrameworkSearchPath() throws { @@ -522,4 +515,19 @@ final class LinkGeneratorErrorTests: XCTestCase { return projectFileElements } + + private func createFileElements(fileAbsolutePath: AbsolutePath, + pbxproj: PBXProj) -> ProjectFileElements { + let fileElements = ProjectFileElements() + let from = AbsolutePath("/Frameworks/") + let fileRelativePath = RelativePath("./Test.xcframework") + + fileElements.addFileElement(from: from, + fileAbsolutePath: fileAbsolutePath, + fileRelativePath: fileRelativePath, + name: nil, + toGroup: pbxproj.groups.first!, + pbxproj: pbxproj) + return fileElements + } } diff --git a/docs/usage/dependencies.mdx b/docs/usage/dependencies.mdx index 137788030e8..a116c0211a4 100644 --- a/docs/usage/dependencies.mdx +++ b/docs/usage/dependencies.mdx @@ -10,7 +10,7 @@ import Message from '../components/message' Imagine a modular app made of 8 projects, with at least two targets each of them \(to compile the framework/library and run the tests\), with dependencies between them. That's a very common setup in large projects, especially if you need to reuse code across different targets. With 16 targets to set up, **there's much knowledge that the developers need to keep in mind to do things the right way**. Who is depending on this target? Where do I need to embed this dynamic framework? Which build settings should I update to make the public interface of the library available? -Fortunately, **Tuist takes care of all that work for you**. It allows you to define dependencies and it uses that knowledge to set up the targets with the right build phases and build settings. +Fortunately, **Tuist takes care of all that work for you**. It allows you to define dependencies and it uses that knowledge to set up the targets with the right build phases and build settings. If you noticed when we first introduced the manifest file, there isn't any public model for defining linking build phases. We made that on purpose because **we'd like to figure out all those things for you**. ## Defining dependencies @@ -113,6 +113,14 @@ Tuist looks up CocoaPods using Bundler. If it's not defined, it falls back to th description="Tuist does not parse the CocoaPods dependency graph nor runs any validation. It's the user responsibility ensure the right format of the 'Podfile'." /> +## XCFramework dependencies + +```swift +.xcFramework(path: "Frameworks/Alamofire.xcframework") +``` + +It defines a dependency with a pre-compiled xcframework. + --- As we mentioned, the beauty of defining your dependencies with Tuist is that when you generate the project, things are set up and ready for you to successfully compile your targets. diff --git a/fixtures/ios_app_with_xcframeworks/Tests/xcframeworksTests.swift b/fixtures/ios_app_with_xcframeworks/Tests/xcframeworksTests.swift index 861c4da3885..621b46fc16a 100644 --- a/fixtures/ios_app_with_xcframeworks/Tests/xcframeworksTests.swift +++ b/fixtures/ios_app_with_xcframeworks/Tests/xcframeworksTests.swift @@ -1,7 +1,7 @@ import Foundation import XCTest -@testable import xcframeworks +@testable import App final class xcframeworksTests: XCTestCase {