diff --git a/App.xcodeproj/project.pbxproj b/App.xcodeproj/project.pbxproj index 1c5373118..e60205dda 100644 --- a/App.xcodeproj/project.pbxproj +++ b/App.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ 3D92B78020A823FF006711E5 /* NSError+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B77F20A823FF006711E5 /* NSError+TestData.swift */; }; 3D92B78E20A8298F006711E5 /* ConfigGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B78D20A8298F006711E5 /* ConfigGeneratorTests.swift */; }; 3D92B79120A82A82006711E5 /* Graph+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B79020A82A82006711E5 /* Graph+TestData.swift */; }; + 3D92B79320A83BC3006711E5 /* ProjectGroups.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B79220A83BC3006711E5 /* ProjectGroups.swift */; }; 66F6DC2FC19AB1F6D332D8E8 /* ArgumentParserResult+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F6D37333CBFF51EA0098DD /* ArgumentParserResult+TestData.swift */; }; B9013DD5206FEEDF007B1A34 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9013DD4206FEEDF007B1A34 /* Sparkle.framework */; }; B9013DD6206FEEEA007B1A34 /* Sparkle.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B9013DD4206FEEDF007B1A34 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -237,6 +238,7 @@ 3D92B77F20A823FF006711E5 /* NSError+TestData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSError+TestData.swift"; sourceTree = ""; }; 3D92B78D20A8298F006711E5 /* ConfigGeneratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigGeneratorTests.swift; sourceTree = ""; }; 3D92B79020A82A82006711E5 /* Graph+TestData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Graph+TestData.swift"; sourceTree = ""; }; + 3D92B79220A83BC3006711E5 /* ProjectGroups.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectGroups.swift; sourceTree = ""; }; 66F6D37333CBFF51EA0098DD /* ArgumentParserResult+TestData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ArgumentParserResult+TestData.swift"; sourceTree = ""; }; B9013DD4206FEEDF007B1A34 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = ""; }; B9157D5220A24B4300C2EEBA /* VersionCommandTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionCommandTests.swift; sourceTree = ""; }; @@ -651,6 +653,7 @@ B95895FA208A2FFB00F00ACF /* WorkspaceGenerator.swift */, 3D4C0B8720A6507B003D09B0 /* ConfigGenerator.swift */, 3D4C0B9B20A6C470003D09B0 /* FileGenerator.swift */, + 3D92B79220A83BC3006711E5 /* ProjectGroups.swift */, ); path = Generator; sourceTree = ""; @@ -1053,6 +1056,7 @@ B95895F3208A2ACF00F00ACF /* ProjectGenerator.swift in Sources */, B9FB2DE52086544900BC2FB3 /* Workspace.swift in Sources */, B9B629C120864E7D00EE9E07 /* DumpCommand.swift in Sources */, + 3D92B79320A83BC3006711E5 /* ProjectGroups.swift in Sources */, 3D4C0BA220A6ED37003D09B0 /* CommandCheck.swift in Sources */, B9FB2DE42086544900BC2FB3 /* Config.swift in Sources */, B9FB2DDF208653E000BC2FB3 /* GraphNode.swift in Sources */, diff --git a/App/xcbuddykit/Sources/Generator/ConfigGenerator.swift b/App/xcbuddykit/Sources/Generator/ConfigGenerator.swift index a513637f9..53415d839 100644 --- a/App/xcbuddykit/Sources/Generator/ConfigGenerator.swift +++ b/App/xcbuddykit/Sources/Generator/ConfigGenerator.swift @@ -9,18 +9,41 @@ protocol ConfigGenerating: AnyObject { /// - Parameters: /// - project: project spec. /// - pbxproj: Xcode project PBXProj object. - /// - mainGroup: Xcode project main group. + /// - groups: Project groups. /// - sourceRootPath: path to the folder that contains the generated project. /// - context: generation context. - /// - Returns: the confniguration list reference. + /// - Returns: the configuration list reference. /// - Throws: an error if the generation fails. func generateProjectConfig(project: Project, pbxproj: PBXProj, - mainGroup: PBXGroup, + groups: ProjectGroups, sourceRootPath: AbsolutePath, context: GeneratorContexting) throws -> PBXObjectReference + /// Generates the manifests target configuration. + /// + /// - Parameters: + /// - pbxproj: Xcode project PBXProj object. + /// - context: generation context. + /// - Returns: the configuration list reference. + /// - Throws: an error if the generation fails. func generateManifestsConfig(pbxproj: PBXProj, context: GeneratorContexting) throws -> PBXObjectReference + + /// Generates the target configuration list and configurations. + /// + /// - Parameters: + /// - target: target spec. + /// - pbxproj: Xcode project PBXProj object. + /// - groups: Project groups. + /// - sourceRootPath: path to the folder that contains the generated project. + /// - context: generation context. + /// - Returns: the configuration list reference. + /// - Throws: an error if the generation fails. + func generateTargetConfig(target: Target, + pbxproj: PBXProj, + groups: ProjectGroups, + sourceRootPath: AbsolutePath, + context: GeneratorContexting) throws -> PBXObjectReference } /// Config generator. @@ -40,21 +63,16 @@ final class ConfigGenerator: ConfigGenerating { /// - Parameters: /// - project: project spec. /// - pbxproj: Xcode project PBXProj object. - /// - mainGroup: Xcode project main group. + /// - groups: Project groups. /// - sourceRootPath: path to the folder that contains the generated project. /// - context: generation context. /// - Returns: the confniguration list reference. /// - Throws: an error if the generation fails. func generateProjectConfig(project: Project, pbxproj: PBXProj, - mainGroup: PBXGroup, + groups: ProjectGroups, sourceRootPath: AbsolutePath, context: GeneratorContexting) throws -> PBXObjectReference { - /// Configurations group - let configsGroup = PBXGroup(children: [], sourceTree: .group, name: "Configurations") - let configsGroupReference = pbxproj.objects.addObject(configsGroup) - mainGroup.children.append(configsGroupReference) - /// Default build settings let defaultAll = BuildSettingsProvider.projectDefault(variant: .all) let defaultDebug = BuildSettingsProvider.projectDefault(variant: .debug) @@ -70,7 +88,7 @@ final class ConfigGenerator: ConfigGenerating { extend(buildSettings: &debugSettings, with: debugConfig.settings) if let xcconfigDebug = debugConfig.xcconfig { let fileReference = try fileGenerator.generateFile(path: xcconfigDebug, - in: configsGroup, + in: groups.projectConfigurations(), sourceRootPath: sourceRootPath, context: context) debugConfiguration.baseConfigurationReference = fileReference.reference @@ -89,7 +107,7 @@ final class ConfigGenerator: ConfigGenerating { extend(buildSettings: &releaseSettings, with: releaseConfig.settings) if let xcconfigRelease = releaseConfig.xcconfig { let fileReference = try fileGenerator.generateFile(path: xcconfigRelease, - in: configsGroup, + in: groups.projectConfigurations(), sourceRootPath: sourceRootPath, context: context) releaseConfiguration.baseConfigurationReference = fileReference.reference @@ -135,6 +153,29 @@ final class ConfigGenerator: ConfigGenerating { return configurationListReference } + /// Generates the target configuration list and configurations. + /// + /// - Parameters: + /// - target: target spec. + /// - pbxproj: Xcode project PBXProj object. + /// - groups: Project groups. + /// - sourceRootPath: path to the folder that contains the generated project. + /// - context: generation context. + /// - Returns: the configuration list reference. + /// - Throws: an error if the generation fails. + func generateTargetConfig(target _: Target, + pbxproj: PBXProj, + groups _: ProjectGroups, + sourceRootPath _: AbsolutePath, + context _: GeneratorContexting) throws -> PBXObjectReference { + let configurationList = XCConfigurationList(buildConfigurations: []) + let configurationListReference = pbxproj.objects.addObject(configurationList) + // TODO: + return configurationListReference + } + + // MARK: - Private + /// Extends build settings with other build settings. /// /// - Parameters: diff --git a/App/xcbuddykit/Sources/Generator/ProjectGenerator.swift b/App/xcbuddykit/Sources/Generator/ProjectGenerator.swift index c6a9b2fff..e8c0fe7ca 100644 --- a/App/xcbuddykit/Sources/Generator/ProjectGenerator.swift +++ b/App/xcbuddykit/Sources/Generator/ProjectGenerator.swift @@ -53,34 +53,22 @@ final class ProjectGenerator: ProjectGenerating { let pbxproj = PBXProj(objectVersion: Xcode.Default.objectVersion, archiveVersion: Xcode.LastKnown.archiveVersion, classes: [:]) - - /// Main group - let mainGroup = PBXGroup(children: [], - sourceTree: .group, - path: project.path.relative(to: sourceRootPath).asString) - let mainGroupReference = pbxproj.objects.addObject(mainGroup) - - // Configuration + let groups = ProjectGroups.generate(project: project, pbxproj: pbxproj, sourceRootPath: sourceRootPath) let configurationListReference = try configGenerator.generateProjectConfig(project: project, pbxproj: pbxproj, - mainGroup: mainGroup, + groups: groups, sourceRootPath: sourceRootPath, context: context) - /// Products group - let productsGroup = PBXGroup(children: [], sourceTree: .buildProductsDir, name: "Products") - let productsGroupReference = pbxproj.objects.addObject(productsGroup) - mainGroup.children.append(productsGroupReference) - /// Generate project object. let pbxProject = PBXProject(name: project.name, buildConfigurationList: configurationListReference, compatibilityVersion: Xcode.Default.compatibilityVersion, - mainGroup: mainGroupReference, + mainGroup: groups.main.reference, developmentRegion: Xcode.Default.developmentRegion, hasScannedForEncodings: 0, knownRegions: ["en"], - productRefGroup: productsGroupReference, + productRefGroup: groups.products.reference, projectDirPath: "", projectReferences: [], projectRoots: [], @@ -89,14 +77,20 @@ final class ProjectGenerator: ProjectGenerating { let projectReference = pbxproj.objects.addObject(pbxProject) pbxproj.rootObject = projectReference - /// Targets try targetGenerator.generateManifestsTarget(project: project, pbxproj: pbxproj, pbxProject: pbxProject, - mainGroup: mainGroup, - productsGroup: productsGroup, + groups: groups, sourceRootPath: sourceRootPath, context: context) + try project.targets.forEach { target in + try targetGenerator.generateTarget(target: target, + pbxproj: pbxproj, + pbxProject: pbxProject, + groups: groups, + sourceRootPath: sourceRootPath, + context: context) + } /// Write. let xcodeproj = XcodeProj(workspace: workspace, pbxproj: pbxproj) diff --git a/App/xcbuddykit/Sources/Generator/ProjectGroups.swift b/App/xcbuddykit/Sources/Generator/ProjectGroups.swift new file mode 100644 index 000000000..a61a6813f --- /dev/null +++ b/App/xcbuddykit/Sources/Generator/ProjectGroups.swift @@ -0,0 +1,165 @@ +import Basic +import Foundation +import xcodeproj + +/// Object that contains references to the project base groups. +class ProjectGroups { + /// Project main group. + let main: PBXGroup + + /// Project products group. + let products: PBXGroup + + /// Project support group. + let support: PBXGroup + + /// Project project description group. + let projectDescription: PBXGroup + + /// Targets group. + fileprivate let targets: PBXGroup + + /// Frameworks group. + fileprivate let frameworks: PBXGroup + + /// PBXProj instance. + fileprivate let pbxproj: PBXProj + + /// Project configurations group. + fileprivate let configurations: PBXGroup + + /// Initializes the object with the group. + /// + /// - Parameters: + /// - main: main group. + /// - products: products group. + /// - configurations: configurations group. + /// - support: support group. + /// - targets: targets group. + /// - projectDescription: project description group. + init(main: PBXGroup, + products: PBXGroup, + configurations: PBXGroup, + support: PBXGroup, + targets: PBXGroup, + projectDescription: PBXGroup, + frameworks: PBXGroup, + pbxproj: PBXProj) { + self.main = main + self.products = products + self.support = support + self.targets = targets + self.configurations = configurations + self.projectDescription = projectDescription + self.frameworks = frameworks + self.pbxproj = pbxproj + } + + /// Returns a group that should contain all the target build files (sources & resources) + /// + /// - Parameter name: target name. + /// - Returns: group to be used. + /// - Throws: an error if the creation fails. + func target(name: String) throws -> PBXGroup { + if let group = targets.group(named: name) { + return group + } else { + return try targets.addGroup(named: name, options: .withoutFolder).first! + } + } + + /// Returns a group that should contain all the frameworks of a given target. + /// + /// - Parameter target: target name. + /// - Returns: group to be used. + /// - Throws: an error if the creation fails. + func targetFrameworks(target: String) throws -> PBXGroup { + if let group = frameworks.group(named: target) { + return group + } else { + return try frameworks.addGroup(named: target, options: .withoutFolder).first! + } + } + + /// Returns a group that should contain all the configurations of a given target. + /// + /// - Parameter target: target name. + /// - Returns: group to be used. + /// - Throws: an error if the creation fails. + func targetConfigurations(_ target: String) throws -> PBXGroup { + if let group = configurations.group(named: target) { + return group + } else { + return try configurations.addGroup(named: target, options: .withoutFolder).first! + } + } + + /// Returns a group that should contain all the configurations of a project. + /// + /// - Returns: the group to be used. + /// - Throws: an error if the creation fails. + func projectConfigurations() throws -> PBXGroup { + if let group = configurations.group(named: "Project") { + return group + } else { + return try configurations.addGroup(named: "Project", options: .withoutFolder).first! + } + } + + /// Generates all the Xcode project base groups and returns an instance of ProjectGroups + /// that contains a reference to them. + /// + /// - Parameters: + /// - project: project spec. + /// - pbxproj: PBXProj instance. + /// - sourceRootPath: path to the folder where the Xcode project is getting created. + /// - Returns: project groups instance. + static func generate(project: Project, + pbxproj: PBXProj, + sourceRootPath: AbsolutePath) -> ProjectGroups { + /// Main + let mainGroup = PBXGroup(children: [], + sourceTree: .group, + path: project.path.relative(to: sourceRootPath).asString) + pbxproj.objects.addObject(mainGroup) + + /// Targets + let targetsGroup = PBXGroup(children: [], sourceTree: .group, name: "Targets") + let targetsGroupReference = pbxproj.objects.addObject(targetsGroup) + mainGroup.children.append(targetsGroupReference) + + /// Configurations + let configurationsGroup = PBXGroup(children: [], sourceTree: .group, name: "Configurations") + let configurationsGroupReference = pbxproj.objects.addObject(configurationsGroup) + mainGroup.children.append(configurationsGroupReference) + + /// Support + let supportGroup = PBXGroup(children: [], sourceTree: .group, name: "Support") + let supportGroupReference = pbxproj.objects.addObject(supportGroup) + mainGroup.children.append(supportGroupReference) + + /// Configurations + let projectDescriptionGroup = PBXGroup(children: [], sourceTree: .group, name: "ProjectDescription") + let projectDescriptionGroupReference = pbxproj.objects.addObject(projectDescriptionGroup) + mainGroup.children.append(projectDescriptionGroupReference) + + /// Frameworks + let frameworksGroup = PBXGroup(children: [], sourceTree: .group, name: "Frameworks") + let frameworksGroupReference = pbxproj.objects.addObject(frameworksGroup) + mainGroup.children.append(frameworksGroupReference) + + /// Products + let productsGroup = PBXGroup(children: [], sourceTree: .buildProductsDir, name: "Products") + let productsGroupReference = pbxproj.objects.addObject(productsGroup) + mainGroup.children.append(productsGroupReference) + + return ProjectGroups(main: mainGroup, + products: productsGroup, + configurations: configurationsGroup, + support: supportGroup, + targets: targetsGroup, + projectDescription: projectDescriptionGroup, + frameworks: frameworksGroup, + pbxproj: pbxproj) + } +} diff --git a/App/xcbuddykit/Sources/Generator/TargetGenerator.swift b/App/xcbuddykit/Sources/Generator/TargetGenerator.swift index b96fe18df..67cbfc28e 100644 --- a/App/xcbuddykit/Sources/Generator/TargetGenerator.swift +++ b/App/xcbuddykit/Sources/Generator/TargetGenerator.swift @@ -2,16 +2,44 @@ import Basic import Foundation import xcodeproj +/// Interface for targets generation. protocol TargetGenerating: AnyObject { + /// Generates the manifests target. + /// + /// - Parameters: + /// - project: Project spec. + /// - pbxproj: PBXProj instance from the generated Xcode project. + /// - pbxProject: PBXProject instance from the generated project. + /// - groups: Project groups. + /// - sourceRootPath: Path to the folder that contains the project that is getting generated. + /// - context: generation context. + /// - Throws: an error if the generation fails. func generateManifestsTarget(project: Project, pbxproj: PBXProj, pbxProject: PBXProject, - mainGroup: PBXGroup, - productsGroup: PBXGroup, + groups: ProjectGroups, sourceRootPath: AbsolutePath, context: GeneratorContexting) throws + + /// Generates a native target. + /// + /// - Parameters: + /// - target: Target spec. + /// - pbxproj: PBXProj instance from the generated Xcode project. + /// - pbxProject: PBXProject instance from the generated project. + /// - groups: Project groups. + /// - sourceRootPath: Path to the folder that contains the project that is getting generated. + /// - context: generation context. + /// - Throws: an error if the generation fails. + func generateTarget(target: Target, + pbxproj: PBXProj, + pbxProject: PBXProject, + groups: ProjectGroups, + sourceRootPath: AbsolutePath, + context: GeneratorContexting) throws } +/// Target generator. final class TargetGenerator: TargetGenerating { /// Config generator. let configGenerator: ConfigGenerating @@ -19,17 +47,31 @@ final class TargetGenerator: TargetGenerating { /// File generator. let fileGenerator: FileGenerating + /// Initializes the target generator with its attributes. + /// + /// - Parameters: + /// - configGenerator: config generator. + /// - fileGenerator: file generator. init(configGenerator: ConfigGenerating = ConfigGenerator(), fileGenerator: FileGenerating = FileGenerator()) { self.configGenerator = configGenerator self.fileGenerator = fileGenerator } + /// Generates the manifests target. + /// + /// - Parameters: + /// - project: Project spec. + /// - pbxproj: PBXProj instance from the generated Xcode project. + /// - pbxProject: PBXProject instance from the generated project. + /// - groups: Project groups. + /// - sourceRootPath: Path to the folder that contains the project that is getting generated. + /// - context: generation context. + /// - Throws: an error if the generation fails. func generateManifestsTarget(project: Project, pbxproj: PBXProj, pbxProject: PBXProject, - mainGroup: PBXGroup, - productsGroup: PBXGroup, + groups: ProjectGroups, sourceRootPath: AbsolutePath, context: GeneratorContexting) throws { /// Names @@ -39,21 +81,22 @@ final class TargetGenerator: TargetGenerating { /// Products reference. let productFileReference = PBXFileReference(sourceTree: .buildProductsDir, name: frameworkName) let productFileReferenceRef = pbxproj.objects.addObject(productFileReference) - productsGroup.children.append(productFileReferenceRef) - - /// Group - let group = PBXGroup(sourceTree: .group, name: name) - let groupReference = pbxproj.objects.addObject(group) - mainGroup.children.insert(groupReference, at: 0) + groups.products.children.append(productFileReferenceRef) /// Files var files: [PBXObjectReference] = [] let projectManifestPath = project.path.appending(component: Constants.Manifest.project) - let projectManifest = try fileGenerator.generateFile(path: projectManifestPath, in: group, sourceRootPath: sourceRootPath, context: context) + let projectManifest = try fileGenerator.generateFile(path: projectManifestPath, + in: groups.projectDescription, + sourceRootPath: sourceRootPath, + context: context) files.append(projectManifest.reference) if let config = project.config { let configManifestPath = config.path.appending(component: Constants.Manifest.config) - let configManifest = try fileGenerator.generateFile(path: configManifestPath, in: group, sourceRootPath: sourceRootPath, context: context) + let configManifest = try fileGenerator.generateFile(path: configManifestPath, + in: groups.projectDescription, + sourceRootPath: sourceRootPath, + context: context) files.append(configManifest.reference) } @@ -75,4 +118,45 @@ final class TargetGenerator: TargetGenerating { let targetReference = pbxproj.objects.addObject(target) pbxProject.targets.append(targetReference) } + + /// Generates a native target. + /// + /// - Parameters: + /// - target: Target spec. + /// - pbxproj: PBXProj instance from the generated Xcode project. + /// - pbxProject: PBXProject instance from the generated project. + /// - groups: Project groups. + /// - sourceRootPath: Path to the folder that contains the project that is getting generated. + /// - context: generation context. + /// - Throws: an error if the generation fails. + func generateTarget(target: Target, + pbxproj: PBXProj, + pbxProject: PBXProject, + groups: ProjectGroups, + sourceRootPath _: AbsolutePath, + context _: GeneratorContexting) throws { + /// Names + let name = target.name + let productName = "\(target.name).\(target.product.xcodeValue.fileExtension!)" + + /// Products reference. + let productFileReference = PBXFileReference(sourceTree: .buildProductsDir, name: productName) + let productFileReferenceRef = pbxproj.objects.addObject(productFileReference) + groups.products.children.append(productFileReferenceRef) + + /// Group + let group = try groups.target(name: target.name) + + /// Target + let target = PBXNativeTarget(name: target.name, + buildConfigurationList: nil, + buildPhases: [], + buildRules: [], + dependencies: [], + productName: productName, + productReference: productFileReferenceRef, + productType: target.product.xcodeValue) + let targetReference = pbxproj.objects.addObject(target) + pbxProject.targets.append(targetReference) + } } diff --git a/App/xcbuddykit/Sources/Models/Product.swift b/App/xcbuddykit/Sources/Models/Product.swift index c5333ef95..c150ba268 100644 --- a/App/xcbuddykit/Sources/Models/Product.swift +++ b/App/xcbuddykit/Sources/Models/Product.swift @@ -1,4 +1,5 @@ import Foundation +import xcodeproj /// Product type. /// @@ -37,38 +38,38 @@ public enum Product: String { extension Product { /// Returns the Xcode value. - var xcodeValue: String { + var xcodeValue: PBXProductType { switch self { case .app: - return "com.apple.product-type.application" + return .application case .staticLibrary: - return "com.apple.product-type.library.static" + return .staticLibrary case .dynamicLibrary: - return "com.apple.product-type.library.dynamic" + return .dynamicLibrary case .framework: - return "com.apple.product-type.framework" + return .framework case .unitTests: - return "com.apple.product-type.bundle.unit-test" + return .unitTestBundle case .uiTests: - return "com.apple.product-type.bundle.ui-testing" + return .uiTestBundle case .appExtension: - return "com.apple.product-type.app-extension" + return .appExtension case .watchApp: - return "com.apple.product-type.application.watchapp" + return .watchApp case .watch2App: - return "com.apple.product-type.application.watchapp2" + return .watch2App case .watchExtension: - return "com.apple.product-type.watchkit-extension" + return .watch2App case .watch2Extension: - return "com.apple.product-type.watchkit2-extension" + return .watch2Extension case .tvExtension: - return "com.apple.product-type.tv-app-extension" + return .watch2Extension case .messagesApplication: - return "com.apple.product-type.application.messages" + return .messagesApplication case .messagesExtension: - return "com.apple.product-type.app-extension.messages" + return .messagesExtension case .stickerPack: - return "com.apple.product-type.app-extension.messages-sticker-pack" + return .stickerPack } } } diff --git a/App/xcbuddykit/Tests/Generator/ConfigGeneratorTests.swift b/App/xcbuddykit/Tests/Generator/ConfigGeneratorTests.swift index 46940064c..37cb29e27 100644 --- a/App/xcbuddykit/Tests/Generator/ConfigGeneratorTests.swift +++ b/App/xcbuddykit/Tests/Generator/ConfigGeneratorTests.swift @@ -19,12 +19,10 @@ final class ConfigGeneratorTests: XCTestCase { } func testGenerateProjectConfig() throws { - let mainGroup = try generateProjectConfig() + let groups = try generateProjectConfig() - XCTAssertEqual(mainGroup.children.count, 1) - - let configurationsGroup: PBXGroup = try mainGroup.children.first!.object() - XCTAssertEqual(configurationsGroup.name, "Configurations") + let configurationsGroup: PBXGroup = try groups.projectConfigurations() + XCTAssertEqual(configurationsGroup.name, "Project") XCTAssertEqual(configurationsGroup.sourceTree, .group) XCTAssertNil(configurationsGroup.path) @@ -56,10 +54,8 @@ final class ConfigGeneratorTests: XCTestCase { XCTAssertEqual(releaseConfig.buildSettings["Base"] as? String, "Base") } - private func generateProjectConfig() throws -> PBXGroup { + private func generateProjectConfig() throws -> ProjectGroups { let dir = try TemporaryDirectory() - let mainGroup = PBXGroup(sourceTree: .absolute, name: "main", path: dir.path.asString) - _ = pbxproj.objects.addObject(mainGroup) let xcconfigsDir = dir.path.appending(component: "xcconfigs") try xcconfigsDir.mkpath() try xcconfigsDir.appending(component: "debug.xcconfig").write("") @@ -74,11 +70,12 @@ final class ConfigGeneratorTests: XCTestCase { release: Configuration(settings: ["Release": "Release"], xcconfig: xcconfigsDir.appending(component: "release.xcconfig"))), targets: []) + let groups = ProjectGroups.generate(project: project, pbxproj: pbxproj, sourceRootPath: dir.path) _ = try subject.generateProjectConfig(project: project, pbxproj: pbxproj, - mainGroup: mainGroup, + groups: groups, sourceRootPath: dir.path, context: context) - return mainGroup + return groups } } diff --git a/App/xcbuddykit/Tests/Models/ProductTests .swift b/App/xcbuddykit/Tests/Models/ProductTests .swift index b28513d58..5d0cabd8f 100644 --- a/App/xcbuddykit/Tests/Models/ProductTests .swift +++ b/App/xcbuddykit/Tests/Models/ProductTests .swift @@ -1,23 +1,24 @@ import Foundation @testable import xcbuddykit +@testable import xcodeproj import XCTest final class ProductTests: XCTestCase { func test_xcodeValue() { - XCTAssertEqual(Product.app.xcodeValue, "com.apple.product-type.application") - XCTAssertEqual(Product.staticLibrary.xcodeValue, "com.apple.product-type.library.static") - XCTAssertEqual(Product.dynamicLibrary.xcodeValue, "com.apple.product-type.library.dynamic") - XCTAssertEqual(Product.framework.xcodeValue, "com.apple.product-type.framework") - XCTAssertEqual(Product.unitTests.xcodeValue, "com.apple.product-type.bundle.unit-test") - XCTAssertEqual(Product.uiTests.xcodeValue, "com.apple.product-type.bundle.ui-testing") - XCTAssertEqual(Product.appExtension.xcodeValue, "com.apple.product-type.app-extension") - XCTAssertEqual(Product.watchApp.xcodeValue, "com.apple.product-type.application.watchapp") - XCTAssertEqual(Product.watch2App.xcodeValue, "com.apple.product-type.application.watchapp2") - XCTAssertEqual(Product.watchExtension.xcodeValue, "com.apple.product-type.watchkit-extension") - XCTAssertEqual(Product.watch2Extension.xcodeValue, "com.apple.product-type.watchkit2-extension") - XCTAssertEqual(Product.tvExtension.xcodeValue, "com.apple.product-type.tv-app-extension") - XCTAssertEqual(Product.messagesApplication.xcodeValue, "com.apple.product-type.application.messages") - XCTAssertEqual(Product.messagesExtension.xcodeValue, "com.apple.product-type.app-extension.messages") - XCTAssertEqual(Product.stickerPack.xcodeValue, "com.apple.product-type.app-extension.messages-sticker-pack") + XCTAssertEqual(Product.app.xcodeValue, PBXProductType.application) + XCTAssertEqual(Product.staticLibrary.xcodeValue, PBXProductType.staticLibrary) + XCTAssertEqual(Product.dynamicLibrary.xcodeValue, PBXProductType.dynamicLibrary) + XCTAssertEqual(Product.framework.xcodeValue, PBXProductType.framework) + XCTAssertEqual(Product.unitTests.xcodeValue, PBXProductType.unitTestBundle) + XCTAssertEqual(Product.uiTests.xcodeValue, PBXProductType.uiTestBundle) + XCTAssertEqual(Product.appExtension.xcodeValue, PBXProductType.appExtension) + XCTAssertEqual(Product.watchApp.xcodeValue, PBXProductType.watchApp) + XCTAssertEqual(Product.watch2App.xcodeValue, PBXProductType.watch2App) + XCTAssertEqual(Product.watchExtension.xcodeValue, PBXProductType.watchExtension) + XCTAssertEqual(Product.watch2Extension.xcodeValue, PBXProductType.watch2Extension) + XCTAssertEqual(Product.tvExtension.xcodeValue, PBXProductType.tvExtension) + XCTAssertEqual(Product.messagesApplication.xcodeValue, PBXProductType.messagesApplication) + XCTAssertEqual(Product.messagesExtension.xcodeValue, PBXProductType.messagesExtension) + XCTAssertEqual(Product.stickerPack.xcodeValue, PBXProductType.stickerPack) } }