From a176f85875837889911e03fb3d3476a5f450b276 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Wed, 24 Jan 2018 17:52:46 +1030 Subject: [PATCH 1/4] xcproj 4.0 --- Package.resolved | 6 +- Package.swift | 2 +- Sources/ProjectSpec/Config.swift | 2 +- Sources/ProjectSpec/Dependency.swift | 2 +- Sources/ProjectSpec/DeploymentTarget.swift | 2 +- Sources/ProjectSpec/ProjectSpec.swift | 2 +- Sources/ProjectSpec/Scheme.swift | 2 +- Sources/ProjectSpec/Settings.swift | 2 +- Sources/ProjectSpec/SpecLoader.swift | 2 +- Sources/ProjectSpec/Target.swift | 5 +- Sources/ProjectSpec/XCProjExtensions.swift | 2 +- Sources/ProjectSpec/Yaml.swift | 2 +- Sources/XcodeGen/main.swift | 8 +- Sources/XcodeGenKit/PBXProjGenerator.swift | 513 +++++++++--------- Sources/XcodeGenKit/ProjectGenerator.swift | 17 +- Sources/XcodeGenKit/SettingsPresetFile.swift | 2 +- Sources/XcodeGenKit/SourceGenerator.swift | 97 ++-- .../TestProject/App_iOS/AppDelegate.swift | 2 +- .../contents.xcworkspacedata | 11 +- .../xcshareddata/xcschemes/App_iOS.xcscheme | 190 +++++-- Tests/LinuxMain.swift | 2 +- Tests/XcodeGenKitTests/FixtureTests.swift | 8 +- .../ProjectGeneratorTests.swift | 73 +-- Tests/XcodeGenKitTests/ProjectSpecTests.swift | 4 +- Tests/XcodeGenKitTests/SpecLoadingTests.swift | 4 +- Tests/XcodeGenKitTests/TestHelpers.swift | 2 +- 26 files changed, 533 insertions(+), 431 deletions(-) diff --git a/Package.resolved b/Package.resolved index 18762626..6ddc5675 100644 --- a/Package.resolved +++ b/Package.resolved @@ -77,9 +77,9 @@ "package": "xcproj", "repositoryURL": "https://github.com/xcodeswift/xcproj.git", "state": { - "branch": null, - "revision": "1b0864a4417efc35c21fdc7d98d3c9bb0152eaf9", - "version": "1.8.0" + "branch": "ee552d3", + "revision": "ee552d3d2b346210dd5269507328d388c522b0a2", + "version": null } } ] diff --git a/Package.swift b/Package.swift index 7ad0c5e3..52896d9e 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( .package(url: "https://github.com/yonaskolb/JSONUtilities.git", from: "3.3.0"), .package(url: "https://github.com/kylef/Spectre.git", from: "0.8.0"), .package(url: "https://github.com/onevcat/Rainbow.git", from: "3.0.0"), - .package(url: "https://github.com/xcodeswift/xcproj.git", from: "1.7.0") + .package(url: "https://github.com/xcodeswift/xcproj.git", .revision("ee552d3")) ], targets: [ .target(name: "XcodeGen", dependencies: [ diff --git a/Sources/ProjectSpec/Config.swift b/Sources/ProjectSpec/Config.swift index 00e34c05..79c6fd4c 100644 --- a/Sources/ProjectSpec/Config.swift +++ b/Sources/ProjectSpec/Config.swift @@ -1,6 +1,6 @@ import Foundation -import xcproj import JSONUtilities +import xcproj public struct Config: Equatable { public var name: String diff --git a/Sources/ProjectSpec/Dependency.swift b/Sources/ProjectSpec/Dependency.swift index 8b382ad9..ce138e7f 100644 --- a/Sources/ProjectSpec/Dependency.swift +++ b/Sources/ProjectSpec/Dependency.swift @@ -1,6 +1,6 @@ import Foundation -import xcproj import JSONUtilities +import xcproj public struct Dependency: Equatable { diff --git a/Sources/ProjectSpec/DeploymentTarget.swift b/Sources/ProjectSpec/DeploymentTarget.swift index 72e0c2d1..da75f45c 100644 --- a/Sources/ProjectSpec/DeploymentTarget.swift +++ b/Sources/ProjectSpec/DeploymentTarget.swift @@ -1,6 +1,6 @@ import Foundation -import xcproj import JSONUtilities +import xcproj public struct DeploymentTarget: Equatable { diff --git a/Sources/ProjectSpec/ProjectSpec.swift b/Sources/ProjectSpec/ProjectSpec.swift index 794d8e33..f6d5f72a 100644 --- a/Sources/ProjectSpec/ProjectSpec.swift +++ b/Sources/ProjectSpec/ProjectSpec.swift @@ -1,7 +1,7 @@ import Foundation -import xcproj import JSONUtilities import PathKit +import xcproj import Yams public struct ProjectSpec { diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index f53d5e99..4cebe42c 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -1,6 +1,6 @@ import Foundation -import xcproj import JSONUtilities +import xcproj public typealias BuildType = XCScheme.BuildAction.Entry.BuildFor diff --git a/Sources/ProjectSpec/Settings.swift b/Sources/ProjectSpec/Settings.swift index be10a7c3..5e5238d6 100644 --- a/Sources/ProjectSpec/Settings.swift +++ b/Sources/ProjectSpec/Settings.swift @@ -1,7 +1,7 @@ import Foundation import JSONUtilities -import xcproj import PathKit +import xcproj public struct Settings: Equatable, JSONObjectConvertible, CustomStringConvertible { diff --git a/Sources/ProjectSpec/SpecLoader.swift b/Sources/ProjectSpec/SpecLoader.swift index 4de11435..859794ae 100644 --- a/Sources/ProjectSpec/SpecLoader.swift +++ b/Sources/ProjectSpec/SpecLoader.swift @@ -1,7 +1,7 @@ import Foundation +import JSONUtilities import PathKit import Yams -import JSONUtilities extension ProjectSpec { diff --git a/Sources/ProjectSpec/Target.swift b/Sources/ProjectSpec/Target.swift index 9ab3e6cc..b764b4b8 100644 --- a/Sources/ProjectSpec/Target.swift +++ b/Sources/ProjectSpec/Target.swift @@ -1,6 +1,6 @@ import Foundation -import xcproj import JSONUtilities +import xcproj public struct LegacyTarget { public var toolPath: String @@ -37,7 +37,6 @@ public struct Target { return legacy != nil } - public var filename: String { var filename = productName ?? name if let fileExtension = type.fileExtension { @@ -219,7 +218,7 @@ extension Target: NamedJSONDictionaryConvertible { public init(name: String, jsonDictionary: JSONDictionary) throws { self.name = jsonDictionary.json(atKeyPath: "name") ?? name - self.productName = jsonDictionary.json(atKeyPath: "productName") + productName = jsonDictionary.json(atKeyPath: "productName") let typeString: String = try jsonDictionary.json(atKeyPath: "type") if let type = PBXProductType(string: typeString) { self.type = type diff --git a/Sources/ProjectSpec/XCProjExtensions.swift b/Sources/ProjectSpec/XCProjExtensions.swift index 24a957d5..990b59a7 100644 --- a/Sources/ProjectSpec/XCProjExtensions.swift +++ b/Sources/ProjectSpec/XCProjExtensions.swift @@ -1,6 +1,6 @@ import Foundation -import xcproj import PathKit +import xcproj extension PBXProductType { diff --git a/Sources/ProjectSpec/Yaml.swift b/Sources/ProjectSpec/Yaml.swift index af47471c..00322e9e 100644 --- a/Sources/ProjectSpec/Yaml.swift +++ b/Sources/ProjectSpec/Yaml.swift @@ -1,6 +1,6 @@ import Foundation -import Yams import PathKit +import Yams public func loadYamlDictionary(path: Path) throws -> [String: Any] { let string: String = try path.read() diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift index 7b777741..4ec96d47 100644 --- a/Sources/XcodeGen/main.swift +++ b/Sources/XcodeGen/main.swift @@ -1,10 +1,10 @@ -import Foundation -import PathKit import Commander +import Foundation +import JSONUtilities +import PathKit +import ProjectSpec import XcodeGenKit import xcproj -import ProjectSpec -import JSONUtilities let version = "1.5.0" diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 03d537a8..f3962529 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -1,20 +1,19 @@ import Foundation -import PathKit -import xcproj import JSONUtilities -import Yams +import PathKit import ProjectSpec +import xcproj +import Yams public class PBXProjGenerator { let spec: ProjectSpec let proj: PBXProj - let sourceGenerator: SourceGenerator - let referenceGenerator = ReferenceGenerator() + var sourceGenerator: SourceGenerator! - var targetNativeReferences: [String: String] = [:] - var targetBuildFiles: [String: PBXBuildFile] = [:] + var targetObjects: [String: ObjectReference] = [:] + var targetBuildFiles: [String: ObjectReference] = [:] var targetFileReferences: [String: String] = [:] var topLevelGroups: Set = [] var carthageFrameworksByPlatform: [String: Set] = [:] @@ -28,15 +27,21 @@ public class PBXProjGenerator { public init(spec: ProjectSpec) { self.spec = spec - proj = PBXProj(objectVersion: 46, rootObject: referenceGenerator.generate(PBXProject.self, spec.name)) - sourceGenerator = SourceGenerator(spec: spec, referenceGenerator: referenceGenerator) { _ in } - sourceGenerator.addObject = { [weak self] object in - self?.addObject(object) + proj = PBXProj(objectVersion: 46, rootObject: "") + sourceGenerator = SourceGenerator(spec: spec) { [unowned self] id, object in + self.addObject(id: id, object) } } - func addObject(_ object: PBXObject) { - proj.objects.addObject(object) + func addObject(id: String, _ object: PBXObject) -> String { + let reference = proj.objects.generateReference(object, id) + proj.objects.addObject(object, reference: reference) + return reference + } + + func createObject(id: String, _ object: T) -> ObjectReference { + let reference = addObject(id: id, object) + return ObjectReference(reference: reference, object: object) } public func generate() throws -> PBXProj { @@ -44,109 +49,152 @@ public class PBXProjGenerator { fatalError("Cannot use PBXProjGenerator to generate more than once") } generated = true + for group in spec.fileGroups { try sourceGenerator.getFileGroups(path: group) } - let buildConfigs: [XCBuildConfiguration] = spec.configs.map { config in + let buildConfigs: [ObjectReference] = spec.configs.map { config in let buildSettings = spec.getProjectBuildSettings(config: config) var baseConfigurationReference: String? if let configPath = spec.configFiles[config.name] { baseConfigurationReference = sourceGenerator.getContainedFileReference(path: spec.basePath + configPath) } - return XCBuildConfiguration( - reference: referenceGenerator.generate(XCBuildConfiguration.self, config.name), - name: config.name, - baseConfigurationReference: baseConfigurationReference, - buildSettings: buildSettings + return createObject( + id: config.name, + XCBuildConfiguration( + name: config.name, + baseConfigurationReference: baseConfigurationReference, + buildSettings: buildSettings + ) ) } - let buildConfigList = XCConfigurationList( - reference: referenceGenerator.generate(XCConfigurationList.self, spec.name), - buildConfigurations: buildConfigs.references, - defaultConfigurationName: buildConfigs.first?.name ?? "", - defaultConfigurationIsVisible: 0 + let buildConfigList = createObject( + id: spec.name, + XCConfigurationList( + buildConfigurations: buildConfigs.map { $0.reference }, + defaultConfigurationName: buildConfigs.first?.object.name ?? "", + defaultConfigurationIsVisible: 0 + ) ) - buildConfigs.forEach(addObject) - addObject(buildConfigList) + let mainGroup = createObject( + id: "Project", + PBXGroup( + children: [], + sourceTree: .group, + usesTabs: spec.options.usesTabs.map { $0 ? 1 : 0 }, + indentWidth: spec.options.indentWidth, + tabWidth: spec.options.tabWidth + ) + ) + + let project = createObject( + id: spec.name, + PBXProject( + name: spec.name, + buildConfigurationList: buildConfigList.reference, + compatibilityVersion: "Xcode 3.2", + mainGroup: mainGroup.reference, + developmentRegion: spec.options.developmentLanguage ?? "en" + ) + ) + + proj.rootObject = project.reference for target in spec.targets { - targetNativeReferences[target.name] = target.isLegacy ? - referenceGenerator.generate(PBXLegacyTarget.self, target.name) : - referenceGenerator.generate(PBXNativeTarget.self, target.name) + let targetObject: PBXTarget + + if target.isLegacy { + targetObject = PBXLegacyTarget( + name: target.name, + buildToolPath: target.legacy?.toolPath, + buildArgumentsString: target.legacy?.arguments, + passBuildSettingsInEnvironment: target.legacy?.passSettings ?? false, + buildWorkingDirectory: target.legacy?.workingDirectory + ) + } else { + targetObject = PBXNativeTarget(name: target.name) + } + + targetObjects[target.name] = createObject(id: target.name, targetObject) var explicitFileType: String? var lastKnownFileType: String? let fileType = PBXFileReference.fileType(path: Path(target.filename)) - if (target.platform == .macOS || target.type == .framework) { + if target.platform == .macOS || target.type == .framework { explicitFileType = fileType } else { lastKnownFileType = fileType } - let fileReference = PBXFileReference( - reference: referenceGenerator.generate(PBXFileReference.self, target.name), - sourceTree: .buildProductsDir, - explicitFileType: explicitFileType, - lastKnownFileType: lastKnownFileType, - path: target.filename, - includeInIndex: 0 + let fileReference = createObject( + id: target.name, + PBXFileReference( + sourceTree: .buildProductsDir, + explicitFileType: explicitFileType, + lastKnownFileType: lastKnownFileType, + path: target.filename, + includeInIndex: 0 + ) ) - addObject(fileReference) - targetFileReferences[target.name] = fileReference.reference - let buildFile = PBXBuildFile( - reference: referenceGenerator.generate(PBXBuildFile.self, fileReference.reference), - fileRef: fileReference.reference + targetFileReferences[target.name] = fileReference.reference + targetBuildFiles[target.name] = createObject( + id: fileReference.reference, + PBXBuildFile(fileRef: fileReference.reference) ) - addObject(buildFile) - targetBuildFiles[target.name] = buildFile } - let targets = try spec.targets.map(generateTarget) + try spec.targets.forEach(generateTarget) - let productGroup = PBXGroup( - reference: referenceGenerator.generate(PBXGroup.self, "Products"), - children: Array(targetFileReferences.values), - sourceTree: .group, - name: "Products" + let productGroup = createObject( + id: "Products", + PBXGroup( + children: Array(targetFileReferences.values), + sourceTree: .group, + name: "Products" + ) ) - addObject(productGroup) topLevelGroups.insert(productGroup.reference) if !carthageFrameworksByPlatform.isEmpty { var platforms: [PBXGroup] = [] + var platformReferences: [String] = [] for (platform, fileReferences) in carthageFrameworksByPlatform { - let platformGroup = PBXGroup( - reference: referenceGenerator.generate(PBXGroup.self, "Carthage" + platform), - children: fileReferences.sorted(), - sourceTree: .group, - path: platform + let platformGroup: ObjectReference = createObject( + id: "Carthage" + platform, + PBXGroup( + children: fileReferences.sorted(), + sourceTree: .group, + path: platform + ) ) - addObject(platformGroup) - platforms.append(platformGroup) + platformReferences.append(platformGroup.reference) + platforms.append(platformGroup.object) } - let carthageGroup = PBXGroup( - reference: referenceGenerator.generate(PBXGroup.self, "Carthage"), - children: platforms.references.sorted(), - sourceTree: .group, - name: "Carthage", - path: carthageBuildPath + let carthageGroup = createObject( + id: "Carthage", + PBXGroup( + children: platformReferences.sorted(), + sourceTree: .group, + name: "Carthage", + path: carthageBuildPath + ) ) - addObject(carthageGroup) frameworkFiles.append(carthageGroup.reference) } if !frameworkFiles.isEmpty { - let group = PBXGroup( - reference: referenceGenerator.generate(PBXGroup.self, "Frameworks"), - children: frameworkFiles, - sourceTree: .group, - name: "Frameworks" + let group = createObject( + id: "Frameworks", + PBXGroup( + children: frameworkFiles, + sourceTree: .group, + name: "Frameworks" + ) ) - addObject(group) topLevelGroups.insert(group.reference) } @@ -154,93 +202,81 @@ public class PBXProjGenerator { topLevelGroups.insert(rootGroup) } - let mainGroup = PBXGroup( - reference: referenceGenerator.generate(PBXGroup.self, "Project"), - children: Array(topLevelGroups), - sourceTree: .group, - usesTabs: spec.options.usesTabs.map { $0 ? 1 : 0 }, - indentWidth: spec.options.indentWidth, - tabWidth: spec.options.tabWidth - ) - addObject(mainGroup) - + mainGroup.object.children = Array(topLevelGroups) sortGroups(group: mainGroup) let projectAttributes: [String: Any] = ["LastUpgradeCheck": spec.xcodeVersion] .merged(spec.attributes) - .merged(self.generateTargetAttributes() ?? [:]) - - let root = PBXProject( - name: spec.name, - reference: proj.rootObject, - buildConfigurationList: buildConfigList.reference, - compatibilityVersion: "Xcode 3.2", - mainGroup: mainGroup.reference, - developmentRegion: spec.options.developmentLanguage ?? "en", - knownRegions: sourceGenerator.knownRegions.sorted(), - targets: targets.references, - attributes: projectAttributes - ) - proj.objects.projects.append(root) + .merged(generateTargetAttributes() ?? [:]) + + project.object.knownRegions = sourceGenerator.knownRegions.sorted() + project.object.targets = targetObjects.values.sorted { $0.object.name < $1.object.name }.map { $0.reference } + project.object.attributes = projectAttributes return proj } - + func generateTargetAttributes() -> [String: Any]? { - - + var targetAttributes: [String: Any] = [:] - + // look up TEST_TARGET_NAME build setting func testTargetName(_ target: PBXTarget) -> String? { guard let configurationList = target.buildConfigurationList else { return nil } guard let buildConfigurationReferences = self.proj.objects.configurationLists[configurationList]?.buildConfigurations else { return nil } - + let configs = buildConfigurationReferences .flatMap { ref in self.proj.objects.buildConfigurations[ref] } - + return configs .flatMap { $0.buildSettings["TEST_TARGET_NAME"] as? String } .first } - - let uiTestTargets = self.proj.objects.nativeTargets.values - .filter { $0.productType == .uiTestBundle } - + + let uiTestTargets = proj.objects.nativeTargets.objectReferences.filter { $0.object.productType == .uiTestBundle } + for uiTestTarget in uiTestTargets { - guard let name = testTargetName(uiTestTarget) else { continue } + guard let name = testTargetName(uiTestTarget.object) else { continue } guard let target = self.proj.objects.targets(named: name).first else { continue } - - targetAttributes[uiTestTarget.reference] = [ "TestTargetID": target.reference] + + targetAttributes[uiTestTarget.reference] = ["TestTargetID": target.reference] } - + guard !targetAttributes.isEmpty else { return nil } return [ - "TargetAttributes": targetAttributes + "TargetAttributes": targetAttributes, ] - } - func sortGroups(group: PBXGroup) { + func sortGroups(group: ObjectReference) { // sort children - let children = group.children - .flatMap { proj.objects.getFileElement(reference: $0) } + let children = group.object.children + .flatMap { reference -> ObjectReference? in + guard let fileElement = proj.objects.getFileElement(reference: reference) else { + return nil + } + return ObjectReference(reference: reference, object: fileElement) + } .sorted { child1, child2 in - if child1.sortOrder == child2.sortOrder { - return child1.nameOrPath < child2.nameOrPath + if child1.object.sortOrder == child2.object.sortOrder { + return child1.object.nameOrPath < child2.object.nameOrPath } else { - return child1.sortOrder < child2.sortOrder + return child1.object.sortOrder < child2.object.sortOrder } } - group.children = children.map { $0.reference }.filter { $0 != group.reference } + group.object.children = children.map { $0.reference }.filter { $0 != group.reference } // sort sub groups - let childGroups = group.children.flatMap { proj.objects.groups[$0] } + let childGroups = group.object.children.flatMap { reference -> ObjectReference? in + guard let group = proj.objects.groups[reference] else { + return nil + } + return ObjectReference(reference: reference, object: group) } childGroups.forEach(sortGroups) } - func generateTarget(_ target: Target) throws -> PBXTarget { + func generateTarget(_ target: Target) throws { sourceGenerator.targetName = target.name let carthageDependencies = getAllCarthageDependencies(target: target) @@ -250,7 +286,7 @@ public class PBXProjGenerator { var plistPath: Path? var searchForPlist = true - let configs: [XCBuildConfiguration] = spec.configs.map { config in + let configs: [ObjectReference] = spec.configs.map { config in var buildSettings = spec.getTargetBuildSettings(target: target, config: config) // automatically set INFOPLIST_FILE path @@ -307,20 +343,18 @@ public class PBXProjGenerator { if let configPath = target.configFiles[config.name] { baseConfigurationReference = sourceGenerator.getContainedFileReference(path: spec.basePath + configPath) } - return XCBuildConfiguration( - reference: referenceGenerator.generate(XCBuildConfiguration.self, config.name + target.name), + let buildConfig = XCBuildConfiguration( name: config.name, baseConfigurationReference: baseConfigurationReference, buildSettings: buildSettings ) + return createObject(id: config.name + target.name, buildConfig) } - configs.forEach(addObject) - let buildConfigList = XCConfigurationList( - reference: referenceGenerator.generate(XCConfigurationList.self, target.name), - buildConfigurations: configs.references, + + let buildConfigList = createObject(id: target.name, XCConfigurationList( + buildConfigurations: configs.map { $0.reference }, defaultConfigurationName: "" - ) - addObject(buildConfigList) + )) var dependencies: [String] = [] var targetFrameworkBuildFiles: [String] = [] @@ -338,42 +372,44 @@ public class PBXProjGenerator { guard let dependencyTarget = spec.getTarget(dependencyTargetName) else { continue } let dependencyFileReference = targetFileReferences[dependencyTargetName]! - let targetProxy = PBXContainerItemProxy( - reference: referenceGenerator.generate(PBXContainerItemProxy.self, target.name), - containerPortal: proj.rootObject, - remoteGlobalIDString: targetNativeReferences[dependencyTargetName]!, - proxyType: .nativeTarget, - remoteInfo: dependencyTargetName + let targetProxy = createObject( + id: target.name, + PBXContainerItemProxy( + containerPortal: proj.rootObject, + remoteGlobalIDString: targetObjects[dependencyTargetName]!.reference, + proxyType: .nativeTarget, + remoteInfo: dependencyTargetName + ) ) - let targetDependency = PBXTargetDependency( - reference: referenceGenerator.generate(PBXTargetDependency.self, dependencyTargetName + target.name), - target: targetNativeReferences[dependencyTargetName]!, - targetProxy: targetProxy.reference + + let targetDependency = createObject( + id: dependencyTargetName + target.name, + PBXTargetDependency( + target: targetObjects[dependencyTargetName]!.reference, + targetProxy: targetProxy.reference + ) ) - addObject(targetProxy) - addObject(targetDependency) dependencies.append(targetDependency.reference) if (dependencyTarget.type.isLibrary || dependencyTarget.type.isFramework) && dependency.link { let dependencyBuildFile = targetBuildFiles[dependencyTargetName]! - let buildFile = PBXBuildFile( - reference: referenceGenerator.generate(PBXBuildFile.self, dependencyBuildFile.reference + target.name), - fileRef: dependencyBuildFile.fileRef! + let buildFile = createObject( + id: dependencyBuildFile.reference + target.name, + PBXBuildFile(fileRef: dependencyBuildFile.object.fileRef!) ) - addObject(buildFile) targetFrameworkBuildFiles.append(buildFile.reference) } if embed && !dependencyTarget.type.isLibrary { - let embedSettings = dependency.buildSettings - let embedFile = PBXBuildFile( - reference: referenceGenerator.generate(PBXBuildFile.self, dependencyFileReference + target.name), - fileRef: dependencyFileReference, - settings: embedSettings + let embedFile = createObject( + id: dependencyFileReference + target.name, + PBXBuildFile( + fileRef: dependencyFileReference, + settings: dependency.buildSettings + ) ) - addObject(embedFile) if dependencyTarget.type.isExtension { // embed app extension @@ -402,11 +438,10 @@ public class PBXProjGenerator { ) } - let buildFile = PBXBuildFile( - reference: referenceGenerator.generate(PBXBuildFile.self, fileReference + target.name), - fileRef: fileReference + let buildFile = createObject( + id: fileReference + target.name, + PBXBuildFile(fileRef: fileReference) ) - addObject(buildFile) targetFrameworkBuildFiles.append(buildFile.reference) if !frameworkFiles.contains(fileReference) { @@ -414,12 +449,10 @@ public class PBXProjGenerator { } if embed { - let embedFile = PBXBuildFile( - reference: referenceGenerator.generate(PBXBuildFile.self, fileReference + target.name), - fileRef: fileReference, - settings: dependency.buildSettings + let embedFile = createObject( + id: fileReference + target.name, + PBXBuildFile(fileRef: fileReference, settings: dependency.buildSettings) ) - addObject(embedFile) copyFrameworksReferences.append(embedFile.reference) } case .carthage: @@ -430,21 +463,19 @@ public class PBXProjGenerator { } let fileReference = sourceGenerator.getFileReference(path: frameworkPath, inPath: platformPath) - let buildFile = PBXBuildFile( - reference: referenceGenerator.generate(PBXBuildFile.self, fileReference + target.name), - fileRef: fileReference + let buildFile = createObject( + id: fileReference + target.name, + PBXBuildFile(fileRef: fileReference) ) - addObject(buildFile) + carthageFrameworksByPlatform[target.platform.carthageDirectoryName, default: []].insert(fileReference) targetFrameworkBuildFiles.append(buildFile.reference) if target.platform == .macOS && target.type.isApp { - let embedFile = PBXBuildFile( - reference: referenceGenerator.generate(PBXBuildFile.self, fileReference + target.name), - fileRef: fileReference, - settings: dependency.buildSettings + let embedFile = createObject( + id: fileReference + target.name, + PBXBuildFile(fileRef: fileReference, settings: dependency.buildSettings) ) - addObject(embedFile) copyFrameworksReferences.append(embedFile.reference) } } @@ -456,17 +487,17 @@ public class PBXProjGenerator { func getBuildFilesForPhase(_ buildPhase: BuildPhase) -> [String] { let files = sourceFiles .filter { $0.buildPhase == buildPhase } - .reduce(into: [SourceFile]()) { (output, sourceFile) in - if !output.contains(where: { $0.fileReference == sourceFile.fileReference }) { - output.append(sourceFile) - } + .reduce(into: [SourceFile]()) { output, sourceFile in + if !output.contains(where: { $0.fileReference == sourceFile.fileReference }) { + output.append(sourceFile) + } } .sorted { $0.path.lastComponent < $1.path.lastComponent } - files.forEach { addObject($0.buildFile) } - return files.map { $0.buildFile.reference } + return files.map { createObject(id: $0.fileReference + target.name, $0.buildFile) } + .map { $0.reference } } - func getBuildScript(buildScript: BuildScript) throws -> PBXShellScriptBuildPhase { + func generateBuildScript(buildScript: BuildScript) throws { let shellScript: String switch buildScript.script { @@ -477,7 +508,6 @@ public class PBXProjGenerator { } let shellScriptPhase = PBXShellScriptBuildPhase( - reference: referenceGenerator.generate(PBXShellScriptBuildPhase.self, String(describing: buildScript.name) + shellScript + target.name), files: [], name: buildScript.name ?? "Run Script", inputPaths: buildScript.inputFiles, @@ -486,82 +516,81 @@ public class PBXProjGenerator { shellScript: shellScript ) shellScriptPhase.runOnlyForDeploymentPostprocessing = buildScript.runOnlyWhenInstalling ? 1 : 0 - addObject(shellScriptPhase) - buildPhases.append(shellScriptPhase.reference) - return shellScriptPhase + let shellScriptPhaseReference = createObject(id: String(describing: buildScript.name) + shellScript + target.name, shellScriptPhase) + buildPhases.append(shellScriptPhaseReference.reference) } - _ = try target.prebuildScripts.map(getBuildScript) + try target.prebuildScripts.forEach(generateBuildScript) let sourcesBuildPhaseFiles = getBuildFilesForPhase(.sources) if !sourcesBuildPhaseFiles.isEmpty { - let sourcesBuildPhase = PBXSourcesBuildPhase(reference: referenceGenerator.generate(PBXSourcesBuildPhase.self, target.name), files: sourcesBuildPhaseFiles) - addObject(sourcesBuildPhase) + let sourcesBuildPhase = createObject(id: target.name, PBXSourcesBuildPhase(files: sourcesBuildPhaseFiles)) buildPhases.append(sourcesBuildPhase.reference) } let resourcesBuildPhaseFiles = getBuildFilesForPhase(.resources) + copyResourcesReferences if !resourcesBuildPhaseFiles.isEmpty { - let resourcesBuildPhase = PBXResourcesBuildPhase(reference: referenceGenerator.generate(PBXResourcesBuildPhase.self, target.name), files: resourcesBuildPhaseFiles) - addObject(resourcesBuildPhase) + let resourcesBuildPhase = createObject(id: target.name, PBXResourcesBuildPhase(files: resourcesBuildPhaseFiles)) buildPhases.append(resourcesBuildPhase.reference) } let headersBuildPhaseFiles = getBuildFilesForPhase(.headers) if !headersBuildPhaseFiles.isEmpty && (target.type == .framework || target.type == .dynamicLibrary) { - let headersBuildPhase = PBXHeadersBuildPhase(reference: referenceGenerator.generate(PBXHeadersBuildPhase.self, target.name), files: headersBuildPhaseFiles) - addObject(headersBuildPhase) + let headersBuildPhase = createObject(id: target.name, PBXHeadersBuildPhase(files: headersBuildPhaseFiles)) buildPhases.append(headersBuildPhase.reference) } if !targetFrameworkBuildFiles.isEmpty { - let frameworkBuildPhase = PBXFrameworksBuildPhase( - reference: referenceGenerator.generate(PBXFrameworksBuildPhase.self, target.name), - files: targetFrameworkBuildFiles, - runOnlyForDeploymentPostprocessing: 0 + let frameworkBuildPhase = createObject( + id: target.name, + PBXFrameworksBuildPhase( + files: targetFrameworkBuildFiles, + runOnlyForDeploymentPostprocessing: 0 + ) ) - - addObject(frameworkBuildPhase) buildPhases.append(frameworkBuildPhase.reference) } if !extensions.isEmpty { - let copyFilesPhase = PBXCopyFilesBuildPhase( - reference: referenceGenerator.generate(PBXCopyFilesBuildPhase.self, "embed app extensions" + target.name), - dstPath: "", - dstSubfolderSpec: .plugins, - files: extensions + let copyFilesPhase = createObject( + id: "embed app extensions" + target.name, + PBXCopyFilesBuildPhase( + dstPath: "", + dstSubfolderSpec: .plugins, + files: extensions + ) ) - addObject(copyFilesPhase) buildPhases.append(copyFilesPhase.reference) } if !copyFrameworksReferences.isEmpty { - let copyFilesPhase = PBXCopyFilesBuildPhase( - reference: referenceGenerator.generate(PBXCopyFilesBuildPhase.self, "embed frameworks" + target.name), - dstPath: "", - dstSubfolderSpec: .frameworks, - files: copyFrameworksReferences + let copyFilesPhase = createObject( + id: "embed frameworks" + target.name, + PBXCopyFilesBuildPhase( + dstPath: "", + dstSubfolderSpec: .frameworks, + files: copyFrameworksReferences + ) ) - addObject(copyFilesPhase) buildPhases.append(copyFilesPhase.reference) } if !copyWatchReferences.isEmpty { - let copyFilesPhase = PBXCopyFilesBuildPhase( - reference: referenceGenerator.generate(PBXCopyFilesBuildPhase.self, "embed watch content" + target.name), - dstPath: "$(CONTENTS_FOLDER_PATH)/Watch", - dstSubfolderSpec: .productsDirectory, - files: copyWatchReferences + let copyFilesPhase = createObject( + id: "embed watch content" + target.name, + PBXCopyFilesBuildPhase( + dstPath: "$(CONTENTS_FOLDER_PATH)/Watch", + dstSubfolderSpec: .productsDirectory, + files: copyWatchReferences + ) ) - addObject(copyFilesPhase) buildPhases.append(copyFilesPhase.reference) } @@ -579,54 +608,34 @@ public class PBXProjGenerator { .map { "$(SRCROOT)/\(carthageBuildPath)/\(target.platform)/\($0)\($0.contains(".") ? "" : ".framework")" } let outputPaths = carthageFrameworksToEmbed .map { "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/\($0)\($0.contains(".") ? "" : ".framework")" } - let carthageScript = PBXShellScriptBuildPhase( - reference: referenceGenerator.generate(PBXShellScriptBuildPhase.self, "Carthage" + target.name), - files: [], - name: "Carthage", - inputPaths: inputPaths, - outputPaths: outputPaths, - shellPath: "/bin/sh", - shellScript: "/usr/local/bin/carthage copy-frameworks\n" + let carthageScript = createObject( + id: "Carthage" + target.name, + PBXShellScriptBuildPhase( + files: [], + name: "Carthage", + inputPaths: inputPaths, + outputPaths: outputPaths, + shellPath: "/bin/sh", + shellScript: "/usr/local/bin/carthage copy-frameworks\n" + ) ) - addObject(carthageScript) buildPhases.append(carthageScript.reference) } } - _ = try target.postbuildScripts.map(getBuildScript) + try target.postbuildScripts.forEach(generateBuildScript) - let pbxtarget: PBXTarget - if target.isLegacy { - pbxtarget = PBXLegacyTarget( - reference: targetNativeReferences[target.name]!, - name: target.name, - buildToolPath: target.legacy?.toolPath, - buildArgumentsString: target.legacy?.arguments, - passBuildSettingsInEnvironment: target.legacy?.passSettings ?? false, - buildWorkingDirectory: target.legacy?.workingDirectory, - buildConfigurationList: buildConfigList.reference, - buildPhases: buildPhases, - buildRules: [], - dependencies: dependencies, - productName: target.name, - productReference: fileReference, - productType: nil - ) - } else { - pbxtarget = PBXNativeTarget( - reference: targetNativeReferences[target.name]!, - name: target.name, - buildConfigurationList: buildConfigList.reference, - buildPhases: buildPhases, - buildRules: [], - dependencies: dependencies, - productName: target.name, - productReference: fileReference, - productType: target.type - ) + let targetObject = targetObjects[target.name]!.object + + targetObject.name = target.name + targetObject.buildConfigurationList = buildConfigList.reference + targetObject.buildPhases = buildPhases + targetObject.dependencies = dependencies + targetObject.productName = target.name + targetObject.productReference = fileReference + if !target.isLegacy { + targetObject.productType = target.type } - addObject(pbxtarget) - return pbxtarget } func getInfoPlist(_ sources: [TargetSource]) -> Path? { diff --git a/Sources/XcodeGenKit/ProjectGenerator.swift b/Sources/XcodeGenKit/ProjectGenerator.swift index b56bfab5..8a684047 100644 --- a/Sources/XcodeGenKit/ProjectGenerator.swift +++ b/Sources/XcodeGenKit/ProjectGenerator.swift @@ -1,9 +1,9 @@ import Foundation -import PathKit -import xcproj import JSONUtilities -import Yams +import PathKit import ProjectSpec +import xcproj +import Yams public class ProjectGenerator { @@ -31,8 +31,8 @@ public class ProjectGenerator { } func generateWorkspace() throws -> XCWorkspace { - let workspaceReferences: [XCWorkspace.Data.FileRef] = [XCWorkspace.Data.FileRef.project(path: Path(""))] - let workspaceData = XCWorkspace.Data(references: workspaceReferences) + let dataElement: XCWorkspaceDataElement = .file(XCWorkspaceDataFileRef(location: .`self`(""))) + let workspaceData = XCWorkspaceData(children: [dataElement]) return XCWorkspace(data: workspaceData) } @@ -40,15 +40,12 @@ public class ProjectGenerator { func getBuildEntry(_ buildTarget: Scheme.BuildTarget) -> XCScheme.BuildAction.Entry { - let predicate: (PBXTarget) -> Bool = { $0.name == buildTarget.target } - let targetReference = - pbxProject.objects.nativeTargets.referenceValues.first { predicate($0 as PBXTarget) } ?? - pbxProject.objects.legacyTargets.referenceValues.first { predicate($0 as PBXTarget) }! + let targetReference = pbxProject.objects.targets(named: buildTarget.target).first! let buildableReference = XCScheme.BuildableReference( referencedContainer: "container:\(spec.name).xcodeproj", blueprintIdentifier: targetReference.reference, - buildableName: buildTarget.target + (targetReference.productType?.fileExtension.map { ".\($0)" } ?? ""), + buildableName: buildTarget.target + (targetReference.object.productType?.fileExtension.map { ".\($0)" } ?? ""), blueprintName: scheme.name ) diff --git a/Sources/XcodeGenKit/SettingsPresetFile.swift b/Sources/XcodeGenKit/SettingsPresetFile.swift index 0d7bee8e..4fa276b3 100644 --- a/Sources/XcodeGenKit/SettingsPresetFile.swift +++ b/Sources/XcodeGenKit/SettingsPresetFile.swift @@ -1,6 +1,6 @@ import Foundation -import xcproj import ProjectSpec +import xcproj public enum SettingsPresetFile { case config(ConfigType) diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift index 643c77f1..994f781f 100644 --- a/Sources/XcodeGenKit/SourceGenerator.swift +++ b/Sources/XcodeGenKit/SourceGenerator.swift @@ -14,21 +14,28 @@ class SourceGenerator { var rootGroups: Set = [] private var fileReferencesByPath: [String: String] = [:] - private var groupsByPath: [Path: PBXGroup] = [:] - private var variantGroupsByPath: [Path: PBXVariantGroup] = [:] + private var groupsByPath: [Path: ObjectReference] = [:] + private var variantGroupsByPath: [Path: ObjectReference] = [:] private let spec: ProjectSpec - private let referenceGenerator: ReferenceGenerator - var addObject: (PBXObject) -> Void + var addObjectClosure: (String, PBXObject) -> String var targetName: String = "" private(set) var knownRegions: Set = [] - init(spec: ProjectSpec, referenceGenerator: ReferenceGenerator, addObject: @escaping (PBXObject) -> Void) { + init(spec: ProjectSpec, addObjectClosure: @escaping (String, PBXObject) -> String) { self.spec = spec - self.referenceGenerator = referenceGenerator - self.addObject = addObject + self.addObjectClosure = addObjectClosure + } + + func addObject(id: String, _ object: PBXObject) -> String { + return addObjectClosure(id, object) + } + + func createObject(id: String, _ object: T) -> ObjectReference { + let reference = addObject(id: id, object) + return ObjectReference(reference: reference, object: object) } func getAllSourceFiles(sources: [TargetSource]) throws -> [SourceFile] { @@ -61,11 +68,7 @@ class SourceGenerator { settings["COMPILER_FLAGS"] = targetSource.compilerFlags.joined(separator: " ") } - let buildFile = PBXBuildFile( - reference: referenceGenerator.generate(PBXBuildFile.self, fileReference + targetName), - fileRef: fileReference, - settings: settings.isEmpty ? nil : settings - ) + let buildFile = PBXBuildFile(fileRef: fileReference, settings: settings.isEmpty ? nil : settings) return SourceFile( path: path, fileReference: fileReference, @@ -102,14 +105,15 @@ class SourceGenerator { fileReferenceName = nil } let lastKnownFileType = PBXFileReference.fileType(path: path) - let fileReference = PBXFileReference( - reference: referenceGenerator.generate(PBXFileReference.self, path.byRemovingBase(path: spec.basePath).string), - sourceTree: sourceTree, - name: fileReferenceName, - lastKnownFileType: lastKnownFileType, - path: fileReferencePath.string + let fileReference = createObject( + id: path.byRemovingBase(path: spec.basePath).string, + PBXFileReference( + sourceTree: sourceTree, + name: fileReferenceName, + lastKnownFileType: lastKnownFileType, + path: fileReferencePath.string + ) ) - addObject(fileReference) fileReferencesByPath[path.string.lowercased()] = fileReference.reference return fileReference.reference } @@ -130,13 +134,13 @@ class SourceGenerator { return nil } - private func getGroup(path: Path, name: String? = nil, mergingChildren children: [String], createIntermediateGroups: Bool, isBaseGroup: Bool) -> PBXGroup { - let group: PBXGroup + private func getGroup(path: Path, name: String? = nil, mergingChildren children: [String], createIntermediateGroups: Bool, isBaseGroup: Bool) -> ObjectReference { + let groupReference: ObjectReference if let cachedGroup = groupsByPath[path] { // only add the children that aren't already in the cachedGroup - cachedGroup.children = Array(Set(cachedGroup.children + children)) - group = cachedGroup + cachedGroup.object.children = Array(Set(cachedGroup.object.children + children)) + groupReference = cachedGroup } else { // lives outside the spec base path @@ -152,35 +156,33 @@ class SourceGenerator { let groupPath = isTopLevelGroup ? path.byRemovingBase(path: spec.basePath).string : path.lastComponent - group = PBXGroup( - reference: referenceGenerator.generate(PBXGroup.self, path.byRemovingBase(path: spec.basePath).string), + let group = PBXGroup( children: children, sourceTree: .group, name: groupName != groupPath ? groupName : nil, path: groupPath ) - addObject(group) - groupsByPath[path] = group + groupReference = createObject(id: path.byRemovingBase(path: spec.basePath).string, group) + groupsByPath[path] = groupReference if isTopLevelGroup { - rootGroups.insert(group.reference) + rootGroups.insert(groupReference.reference) } } - return group + return groupReference } - private func getVariantGroup(path: Path, inPath: Path) -> PBXVariantGroup { - let variantGroup: PBXVariantGroup + private func getVariantGroup(path: Path, inPath: Path) -> ObjectReference { + let variantGroup: ObjectReference if let cachedGroup = variantGroupsByPath[path] { variantGroup = cachedGroup } else { - variantGroup = PBXVariantGroup( - reference: referenceGenerator.generate(PBXVariantGroup.self, path.byRemovingBase(path: spec.basePath).string), + let group = PBXVariantGroup( children: [], name: path.lastComponent, sourceTree: .group ) - addObject(variantGroup) + variantGroup = createObject(id: path.byRemovingBase(path: spec.basePath).string, group) variantGroupsByPath[path] = variantGroup } return variantGroup @@ -236,7 +238,7 @@ class SourceGenerator { } private func getGroupSources(targetSource: TargetSource, path: Path, isBaseGroup: Bool) - throws -> (sourceFiles: [SourceFile], groups: [PBXGroup]) { + throws -> (sourceFiles: [SourceFile], groups: [ObjectReference]) { let children = try getSourceChildren(targetSource: targetSource, dirPath: path) @@ -256,7 +258,7 @@ class SourceGenerator { var allSourceFiles: [SourceFile] = filePaths.map { generateSourceFile(targetSource: targetSource, path: $0) } - var groups: [PBXGroup] = [] + var groups: [ObjectReference] = [] for path in directories { let subGroups = try getGroupSources(targetSource: targetSource, path: path, isBaseGroup: false) @@ -293,17 +295,12 @@ class SourceGenerator { for filePath in try baseLocalisedDirectory.children().sorted() { let variantGroup = getVariantGroup(path: filePath, inPath: path) groupChildren.append(variantGroup.reference) - baseLocalisationVariantGroups.append(variantGroup) + baseLocalisationVariantGroups.append(variantGroup.object) - let buildFile = PBXBuildFile( - reference: referenceGenerator.generate(PBXBuildFile.self, variantGroup.reference + targetName), - fileRef: variantGroup.reference, - settings: nil - ) let sourceFile = SourceFile( path: filePath, fileReference: variantGroup.reference, - buildFile: buildFile, + buildFile: PBXBuildFile(fileRef: variantGroup.reference), buildPhase: .resources ) allSourceFiles.append(sourceFile) @@ -336,17 +333,13 @@ class SourceGenerator { } } else { // add SourceFile to group if there is no Base.lproj directory - let buildFile = PBXBuildFile( - reference: referenceGenerator.generate(PBXBuildFile.self, fileReference + targetName), - fileRef: fileReference, - settings: nil - ) - allSourceFiles.append(SourceFile( + let sourceFile = SourceFile( path: filePath, fileReference: fileReference, - buildFile: buildFile, + buildFile: PBXBuildFile(fileRef: fileReference), buildPhase: .resources - )) + ) + allSourceFiles.append(sourceFile) groupChildren.append(fileReference) } } @@ -402,7 +395,7 @@ class SourceGenerator { let (groupSourceFiles, groups) = try getGroupSources(targetSource: targetSource, path: path, isBaseGroup: true) let group = groups.first! if let name = targetSource.name { - group.name = name + group.object.name = name } sourceFiles += groupSourceFiles diff --git a/Tests/Fixtures/TestProject/App_iOS/AppDelegate.swift b/Tests/Fixtures/TestProject/App_iOS/AppDelegate.swift index a2a1bd14..3116cdbf 100644 --- a/Tests/Fixtures/TestProject/App_iOS/AppDelegate.swift +++ b/Tests/Fixtures/TestProject/App_iOS/AppDelegate.swift @@ -1,5 +1,5 @@ -import UIKit import Framework +import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Tests/Fixtures/TestProject/Project.xcodeproj/project.xcworkspace/contents.xcworkspacedata index e2b2881e..919434a6 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -1,4 +1,7 @@ - - - - \ No newline at end of file + + + + + diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS.xcscheme index 2386d266..47d66439 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS.xcscheme @@ -1,47 +1,143 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 7d5c97d1..fd97ab24 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -1,5 +1,5 @@ -import XCTest @testable import XcodeGenKitTests +import XCTest XCTMain([ testCase(GeneratorTests.allTests), diff --git a/Tests/XcodeGenKitTests/FixtureTests.swift b/Tests/XcodeGenKitTests/FixtureTests.swift index 5ba3062f..b3e12ede 100644 --- a/Tests/XcodeGenKitTests/FixtureTests.swift +++ b/Tests/XcodeGenKitTests/FixtureTests.swift @@ -1,8 +1,8 @@ -import Spectre import PathKit +import ProjectSpec +import Spectre import XcodeGenKit import xcproj -import ProjectSpec let fixturePath = Path(#file).parent().parent() + "Fixtures" @@ -33,8 +33,8 @@ func fixtureTests() { $0.it("generates variant group") { guard let project = project else { return } - func getFileReferences(_ path: String) -> [PBXFileReference] { - return project.pbxproj.objects.fileReferences.referenceValues.filter { $0.path == path } + func getFileReferences(_ path: String) -> [ObjectReference] { + return project.pbxproj.objects.fileReferences.objectReferences.filter { $0.object.path == path } } func getVariableGroups(_ name: String?) -> [PBXVariantGroup] { diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index bc9726db..b866d4c7 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -1,8 +1,8 @@ +import PathKit +import ProjectSpec import Spectre import XcodeGenKit import xcproj -import PathKit -import ProjectSpec import Yams func projectGeneratorTests() { @@ -34,7 +34,7 @@ func projectGeneratorTests() { platform: .iOS, settings: Settings(buildSettings: ["SETTING_2": "VALUE"]) ) - + let uiTest = Target( name: "MyAppUITests", type: .uiTestBundle, @@ -192,23 +192,23 @@ func projectGeneratorTests() { try expect(nativeTargets.contains { $0.name == framework.name }).beTrue() try expect(nativeTargets.contains { $0.name == uiTest.name }).beTrue() } - + $0.it("generates target attributes") { let pbxProject = try getPbxProj(spec) - + guard let targetAttributes = pbxProject.objects.projects.referenceValues.first?.attributes["TargetAttributes"] as? [String: [String: Any]] else { throw failure("Couldn't find Project TargetAttributes") } - + guard let appTarget = pbxProject.objects.targets(named: application.name).first else { throw failure("Couldn't find App Target") } - + guard let uiTestTarget = pbxProject.objects.targets(named: uiTest.name).first else { throw failure("Couldn't find UITest Target") } - + try expect(targetAttributes[uiTestTarget.reference]?["TestTargetID"] as? String) == appTarget.reference } @@ -243,12 +243,12 @@ func projectGeneratorTests() { $0.it("generates dependencies") { let pbxProject = try getPbxProj(spec) - - let nativeTargets = pbxProject.objects.nativeTargets.referenceValues - let dependencies = pbxProject.objects.targetDependencies.referenceValues + + let nativeTargets = pbxProject.objects.nativeTargets.objectReferences + let dependencies = pbxProject.objects.targetDependencies.objectReferences try expect(dependencies.count) == 2 - try expect(dependencies[0].target) == nativeTargets.first { $0.name == framework.name }!.reference - try expect(dependencies[1].target) == nativeTargets.first { $0.name == application.name }!.reference + try expect(dependencies[0].object.target) == nativeTargets.first { $0.object.name == framework.name }!.reference + try expect(dependencies[1].object.target) == nativeTargets.first { $0.object.name == application.name }!.reference } $0.it("generates run scripts") { @@ -263,15 +263,15 @@ func projectGeneratorTests() { } let buildPhases = nativeTarget.buildPhases - let scripts = pbxProject.objects.shellScriptBuildPhases.referenceValues + let scripts = pbxProject.objects.shellScriptBuildPhases.objectReferences let script1 = scripts[0] let script2 = scripts[1] try expect(scripts.count) == 2 try expect(buildPhases.first) == script1.reference try expect(buildPhases.last) == script2.reference - try expect(script1.shellScript) == "script1" - try expect(script2.shellScript) == "script2" + try expect(script1.object.shellScript) == "script1" + try expect(script2.object.shellScript) == "script2" } $0.it("generates targets with cylical dependencies") { @@ -312,8 +312,8 @@ func projectGeneratorTests() { schemes: [scheme] ) let project = try getProject(spec) - guard let target = project.pbxproj.objects.nativeTargets.referenceValues - .first(where: { $0.name == application.name }) else { + guard let target = project.pbxproj.objects.nativeTargets.objectReferences + .first(where: { $0.object.name == application.name }) else { throw failure("Target not found") } guard let xcscheme = project.sharedData?.schemes.first else { @@ -327,15 +327,15 @@ func projectGeneratorTests() { let buildableReferences: [XCScheme.BuildableReference] = [ buildActionEntry.buildableReference, - xcscheme.launchAction?.buildableProductRunnable.buildableReference, - xcscheme.profileAction?.buildableProductRunnable.buildableReference, + xcscheme.launchAction?.buildableProductRunnable?.buildableReference, + xcscheme.profileAction?.buildableProductRunnable?.buildableReference, xcscheme.testAction?.macroExpansion, ].flatMap { $0 } for buildableReference in buildableReferences { try expect(buildableReference.blueprintIdentifier) == target.reference try expect(buildableReference.blueprintName) == scheme.name - try expect(buildableReference.buildableName) == "\(target.name).\(target.productType!.fileExtension!)" + try expect(buildableReference.buildableName) == "\(target.object.name).\(target.object.productType!.fileExtension!)" } try expect(xcscheme.launchAction?.buildConfiguration) == "Debug" @@ -361,8 +361,8 @@ func projectGeneratorTests() { try expect(project.sharedData?.schemes.count) == 2 - guard let nativeTarget = project.pbxproj.objects.nativeTargets.referenceValues - .first(where: { $0.name == application.name }) else { + guard let nativeTarget = project.pbxproj.objects.nativeTargets.objectReferences + .first(where: { $0.object.name == application.name }) else { throw failure("Target not found") } guard let xcscheme = project.sharedData?.schemes @@ -775,13 +775,12 @@ func projectGeneratorTests() { try project.expectFile(paths: ["C", "Info.plist"], buildPhase: .none) } - $0.it("duplicate TargetSource is included once in sources build phase") { let directories = """ - Sources: - A: - - a.swift - """ + Sources: + A: + - a.swift + """ try createDirectories(directories) let target = Target(name: "Test", type: .application, platform: .iOS, sources: [ @@ -838,8 +837,8 @@ extension PBXProj { } if let buildPhase = buildPhase { - let buildFile = objects.buildFiles.referenceValues - .first(where: { $0.fileRef == fileReference.reference }) + let buildFile = objects.buildFiles.objectReferences + .first(where: { $0.object.fileRef == fileReference.reference }) let actualBuildPhase = buildFile .flatMap { buildFile in objects.buildPhases.referenceValues.first { $0.files.contains(buildFile.reference) } }?.buildPhase @@ -869,7 +868,7 @@ extension PBXProj { } } - func getFileReference(paths: [String], names: [String]) -> PBXFileReference? { + func getFileReference(paths: [String], names: [String]) -> ObjectReference? { guard let project = objects.projects.first?.value else { return nil } guard let mainGroup = objects.groups.getReference(project.mainGroup) else { return nil } @@ -886,7 +885,7 @@ extension PBXProj { return mainGroup } - private func getFileReference(group: PBXGroup, paths: [String], names: [String]) -> PBXFileReference? { + private func getFileReference(group: PBXGroup, paths: [String], names: [String]) -> ObjectReference? { guard !paths.isEmpty else { return nil } let path = paths.first! @@ -894,8 +893,14 @@ extension PBXProj { let restOfPath = Array(paths.dropFirst()) let restOfName = Array(names.dropFirst()) if restOfPath.isEmpty { - let fileReferences = group.children.flatMap { self.objects.fileReferences.getReference($0) } - return fileReferences.first { $0.path == path && $0.nameOrPath == name } + let fileReferences: [ObjectReference] = group.children.flatMap { reference in + if let fileReference = self.objects.fileReferences.getReference(reference) { + return ObjectReference(reference: reference, object: fileReference) + } else { + return nil + } + } + return fileReferences.first { $0.object.path == path && $0.object.nameOrPath == name } } else { let groups = group.children.flatMap { self.objects.groups.getReference($0) } guard let group = groups.first(where: { $0.path == path && $0.nameOrPath == name }) else { return nil } diff --git a/Tests/XcodeGenKitTests/ProjectSpecTests.swift b/Tests/XcodeGenKitTests/ProjectSpecTests.swift index fc6f2c93..6ab4d177 100644 --- a/Tests/XcodeGenKitTests/ProjectSpecTests.swift +++ b/Tests/XcodeGenKitTests/ProjectSpecTests.swift @@ -1,8 +1,8 @@ +import PathKit +import ProjectSpec import Spectre import XcodeGenKit import xcproj -import PathKit -import ProjectSpec func projectSpecTests() { diff --git a/Tests/XcodeGenKitTests/SpecLoadingTests.swift b/Tests/XcodeGenKitTests/SpecLoadingTests.swift index 617b37f7..041c3017 100644 --- a/Tests/XcodeGenKitTests/SpecLoadingTests.swift +++ b/Tests/XcodeGenKitTests/SpecLoadingTests.swift @@ -1,8 +1,8 @@ -import Spectre import PathKit +import ProjectSpec +import Spectre import XcodeGenKit import xcproj -import ProjectSpec func specLoadingTests() { diff --git a/Tests/XcodeGenKitTests/TestHelpers.swift b/Tests/XcodeGenKitTests/TestHelpers.swift index 03065030..f9e65445 100644 --- a/Tests/XcodeGenKitTests/TestHelpers.swift +++ b/Tests/XcodeGenKitTests/TestHelpers.swift @@ -1,7 +1,7 @@ import Foundation +import ProjectSpec import Spectre import xcproj -import ProjectSpec func expectError(_ expectedError: T, _ closure: () throws -> Void) throws where T: CustomStringConvertible { do { From 469795307dca56a9b7e5fb7fa13b81d4bdb12c17 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Thu, 25 Jan 2018 20:59:36 +1030 Subject: [PATCH 2/4] remove ReferenceGenerator --- Sources/XcodeGenKit/ReferenceGenerator.swift | 31 ------------------- .../ProjectGeneratorTests.swift | 27 ---------------- 2 files changed, 58 deletions(-) delete mode 100644 Sources/XcodeGenKit/ReferenceGenerator.swift diff --git a/Sources/XcodeGenKit/ReferenceGenerator.swift b/Sources/XcodeGenKit/ReferenceGenerator.swift deleted file mode 100644 index ab2c3d07..00000000 --- a/Sources/XcodeGenKit/ReferenceGenerator.swift +++ /dev/null @@ -1,31 +0,0 @@ -import Foundation -import xcproj - -public class ReferenceGenerator { - - private var references: Set = [] - - public init() { - } - - public func generate(_ element: T.Type, _ id: String) -> String { - var uuid: String = "" - var counter: UInt = 0 - let characterCount = 16 - let className: String = String(describing: T.self) - .replacingOccurrences(of: "PBX", with: "") - .replacingOccurrences(of: "XC", with: "") - let classAcronym = String(className.filter { String($0).lowercased() != String($0) }) - let stringID = String(abs(id.hashValue).description.prefix(characterCount - classAcronym.count - 2)) - repeat { - uuid = "\(classAcronym)_\(stringID)\(counter > 0 ? "-\(counter)" : "")" - counter += 1 - } while (references.contains(uuid)) - references.insert(uuid) - return uuid - } - - public func clear() { - references.removeAll() - } -} diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index b866d4c7..fb67b017 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -382,33 +382,6 @@ func projectGeneratorTests() { } } - $0.describe("Reference Generator") { - - let referenceGenerator = ReferenceGenerator() - $0.before { - referenceGenerator.clear() - } - - $0.it("generates prefixes") { - let references = [ - referenceGenerator.generate(PBXGroup.self, "a"), - referenceGenerator.generate(PBXFileReference.self, "a"), - referenceGenerator.generate(XCConfigurationList.self, "a"), - ] - try expect(references[0].hasPrefix("G")).to.beTrue() - try expect(references[1].hasPrefix("FR")).to.beTrue() - try expect(references[2].hasPrefix("CL")).to.beTrue() - } - - $0.it("handles duplicates") { - let first = referenceGenerator.generate(PBXGroup.self, "a") - let second = referenceGenerator.generate(PBXGroup.self, "a") - - try expect(first) != second - try expect(second.hasSuffix("-1")).to.beTrue() - } - } - $0.describe("Sources") { let directoryPath = Path("TestDirectory") From 1f7d786d7459fdfd76d44d022ed1a51f9ab9ca56 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Sun, 28 Jan 2018 19:03:12 +1030 Subject: [PATCH 3/4] update packages --- Package.resolved | 14 +++++++------- Package.swift | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Package.resolved b/Package.resolved index 6ddc5675..9b67b865 100644 --- a/Package.resolved +++ b/Package.resolved @@ -42,8 +42,8 @@ "repositoryURL": "https://github.com/onevcat/Rainbow.git", "state": { "branch": null, - "revision": "f407235c7e473c3cb2d2907bb6822616d22a0b78", - "version": "3.0.3" + "revision": "f69961599ad524251d677fbec9e4bac57385d6fc", + "version": "3.1.1" } }, { @@ -51,8 +51,8 @@ "repositoryURL": "https://github.com/JohnSundell/ShellOut.git", "state": { "branch": null, - "revision": "479a89d9bfa7585496bd4a3e4faffac5b01af37f", - "version": "2.0.0" + "revision": "f1c253a34a40df4bfd268b09fdb101b059f6d52d", + "version": "2.1.0" } }, { @@ -77,9 +77,9 @@ "package": "xcproj", "repositoryURL": "https://github.com/xcodeswift/xcproj.git", "state": { - "branch": "ee552d3", - "revision": "ee552d3d2b346210dd5269507328d388c522b0a2", - "version": null + "branch": null, + "revision": "5f68ad74627a537cdd3d022644edd0fa7a80d4a7", + "version": "4.0.0" } } ] diff --git a/Package.swift b/Package.swift index 52896d9e..6f6251fa 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( .package(url: "https://github.com/yonaskolb/JSONUtilities.git", from: "3.3.0"), .package(url: "https://github.com/kylef/Spectre.git", from: "0.8.0"), .package(url: "https://github.com/onevcat/Rainbow.git", from: "3.0.0"), - .package(url: "https://github.com/xcodeswift/xcproj.git", .revision("ee552d3")) + .package(url: "https://github.com/xcodeswift/xcproj.git", from: "4.0.0") ], targets: [ .target(name: "XcodeGen", dependencies: [ From 7efe9c17f66fec6dcbe3a6d3d7abff91e12968c8 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Sun, 28 Jan 2018 19:31:47 +1030 Subject: [PATCH 4/4] update to xcproj 4.0 --- Sources/ProjectSpec/ProjectSpec.swift | 12 ++++++------ Sources/XcodeGenKit/PBXProjGenerator.swift | 16 ++++++---------- .../Project.xcodeproj/project.pbxproj | 15 ++++++++++----- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Sources/ProjectSpec/ProjectSpec.swift b/Sources/ProjectSpec/ProjectSpec.swift index f6d5f72a..02d1c00c 100644 --- a/Sources/ProjectSpec/ProjectSpec.swift +++ b/Sources/ProjectSpec/ProjectSpec.swift @@ -27,8 +27,8 @@ public struct ProjectSpec { public var disabledValidations: [ValidationType] public var developmentLanguage: String? public var usesTabs: Bool? - public var tabWidth: Int? - public var indentWidth: Int? + public var tabWidth: UInt? + public var indentWidth: UInt? public var xcodeVersion: String? public var deploymentTarget: DeploymentTarget @@ -59,8 +59,8 @@ public struct ProjectSpec { bundleIdPrefix: String? = nil, settingPresets: SettingPresets = .all, developmentLanguage: String? = nil, - indentWidth: Int? = nil, - tabWidth: Int? = nil, + indentWidth: UInt? = nil, + tabWidth: UInt? = nil, usesTabs: Bool? = nil, xcodeVersion: String? = nil, deploymentTarget: DeploymentTarget = .init(), @@ -208,8 +208,8 @@ extension ProjectSpec.Options: JSONObjectConvertible { createIntermediateGroups = jsonDictionary.json(atKeyPath: "createIntermediateGroups") ?? false developmentLanguage = jsonDictionary.json(atKeyPath: "developmentLanguage") usesTabs = jsonDictionary.json(atKeyPath: "usesTabs") - indentWidth = jsonDictionary.json(atKeyPath: "indentWidth") - tabWidth = jsonDictionary.json(atKeyPath: "tabWidth") + indentWidth = (jsonDictionary.json(atKeyPath: "indentWidth") as Int?).flatMap(UInt.init) + tabWidth = (jsonDictionary.json(atKeyPath: "tabWidth") as Int?).flatMap(UInt.init) deploymentTarget = jsonDictionary.json(atKeyPath: "deploymentTarget") ?? DeploymentTarget() disabledValidations = jsonDictionary.json(atKeyPath: "disabledValidations") ?? [] } diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index f3962529..09b33315 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -27,7 +27,7 @@ public class PBXProjGenerator { public init(spec: ProjectSpec) { self.spec = spec - proj = PBXProj(objectVersion: 46, rootObject: "") + proj = PBXProj(rootObject: "", objectVersion: 46) sourceGenerator = SourceGenerator(spec: spec) { [unowned self] id, object in self.addObject(id: id, object) } @@ -74,8 +74,7 @@ public class PBXProjGenerator { id: spec.name, XCConfigurationList( buildConfigurations: buildConfigs.map { $0.reference }, - defaultConfigurationName: buildConfigs.first?.object.name ?? "", - defaultConfigurationIsVisible: 0 + defaultConfigurationName: buildConfigs.first?.object.name ?? "" ) ) @@ -84,7 +83,7 @@ public class PBXProjGenerator { PBXGroup( children: [], sourceTree: .group, - usesTabs: spec.options.usesTabs.map { $0 ? 1 : 0 }, + usesTabs: spec.options.usesTabs, indentWidth: spec.options.indentWidth, tabWidth: spec.options.tabWidth ) @@ -136,7 +135,7 @@ public class PBXProjGenerator { explicitFileType: explicitFileType, lastKnownFileType: lastKnownFileType, path: target.filename, - includeInIndex: 0 + includeInIndex: false ) ) @@ -515,7 +514,7 @@ public class PBXProjGenerator { shellPath: buildScript.shell ?? "/bin/sh", shellScript: shellScript ) - shellScriptPhase.runOnlyForDeploymentPostprocessing = buildScript.runOnlyWhenInstalling ? 1 : 0 + shellScriptPhase.runOnlyForDeploymentPostprocessing = buildScript.runOnlyWhenInstalling let shellScriptPhaseReference = createObject(id: String(describing: buildScript.name) + shellScript + target.name, shellScriptPhase) buildPhases.append(shellScriptPhaseReference.reference) } @@ -544,10 +543,7 @@ public class PBXProjGenerator { let frameworkBuildPhase = createObject( id: target.name, - PBXFrameworksBuildPhase( - files: targetFrameworkBuildFiles, - runOnlyForDeploymentPostprocessing: 0 - ) + PBXFrameworksBuildPhase(files: targetFrameworkBuildFiles) ) buildPhases.append(frameworkBuildPhase.reference) } diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index e7ae944a..84e425c6 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -114,7 +114,7 @@ FR_481575785861 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; FR_500792082643 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/LocalizedStoryboard.strings; sourceTree = ""; }; FR_525119120469 /* Framework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Framework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - FR_602633703434 /* en */ = {isa = PBXFileReference; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; + FR_602633703434 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; FR_609193904586 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; FR_635802719871 /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = ""; }; FR_643034527839 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -124,7 +124,7 @@ FR_675266829517 /* Standalone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Standalone.swift; sourceTree = ""; }; FR_722239415598 /* TestProjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestProjectTests.swift; sourceTree = ""; }; FR_725187762757 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - FR_746876637628 /* Base */ = {isa = PBXFileReference; name = Base; path = Base.lproj/Localizable.stringsdict; sourceTree = ""; }; + FR_746876637628 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.stringsdict; sourceTree = ""; }; FR_752394658615 /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Alamofire.framework; sourceTree = ""; }; FR_771029596306 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; FR_783122899910 /* App_iOS_Tests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = App_iOS_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -395,8 +395,6 @@ buildConfigurationList = CL_479264660374 /* Build configuration list for PBXLegacyTarget "Legacy" */; buildPhases = ( ); - buildRules = ( - ); buildToolPath = /usr/bin/true; dependencies = ( ); @@ -606,6 +604,7 @@ runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "echo \"You ran a script\"\n"; + showEnvVarsInLog = 0; }; SSBP_3886691194 /* MyScript */ = { isa = PBXShellScriptBuildPhase; @@ -620,6 +619,7 @@ runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "echo \"You ran a script\"\n"; + showEnvVarsInLog = 0; }; SSBP_5106020372 /* Strip Unused Architectures from Frameworks */ = { isa = PBXShellScriptBuildPhase; @@ -634,6 +634,7 @@ runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; shellScript = "################################################################################\n#\n# Copyright 2015 Realm Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n################################################################################\n\n# This script strips all non-valid architectures from dynamic libraries in\n# the application's `Frameworks` directory.\n#\n# The following environment variables are required:\n#\n# BUILT_PRODUCTS_DIR\n# FRAMEWORKS_FOLDER_PATH\n# VALID_ARCHS\n# EXPANDED_CODE_SIGN_IDENTITY\n\n\n# Signs a framework with the provided identity\ncode_sign() {\n # Use the current code_sign_identitiy\n echo \"Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}\"\n echo \"/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements $1\"\n /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"\n}\n\n# Set working directory to product’s embedded frameworks\ncd \"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}\"\n\nif [ \"$ACTION\" = \"install\" ]; then\n echo \"Copy .bcsymbolmap files to .xcarchive\"\n find . -name '*.bcsymbolmap' -type f -exec mv {} \"${CONFIGURATION_BUILD_DIR}\" \\;\nelse\n # Delete *.bcsymbolmap files from framework bundle unless archiving\n find . -name '*.bcsymbolmap' -type f -exec rm -rf \"{}\" +\\;\nfi\n\necho \"Stripping frameworks\"\n\nfor file in $(find . -type f -perm +111); do\n # Skip non-dynamic libraries\n if ! [[ \"$(file \"$file\")\" == *\"dynamically linked shared library\"* ]]; then\n continue\n fi\n # Get architectures for current file\n archs=\"$(lipo -info \"${file}\" | rev | cut -d ':' -f1 | rev)\"\n stripped=\"\"\n for arch in $archs; do\n if ! [[ \"${VALID_ARCHS}\" == *\"$arch\"* ]]; then\n # Strip non-valid architectures in-place\n lipo -remove \"$arch\" -output \"$file\" \"$file\" || exit 1\n stripped=\"$stripped $arch\"\n fi\n done\n if [[ \"$stripped\" != \"\" ]]; then\n echo \"Stripped $file of architectures:$stripped\"\n if [ \"${CODE_SIGNING_REQUIRED}\" == \"YES\" ]; then\n code_sign \"${file}\"\n fi\n fi\ndone\n"; + showEnvVarsInLog = 0; }; SSBP_6331376344 /* MyScript */ = { isa = PBXShellScriptBuildPhase; @@ -648,6 +649,7 @@ runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "echo \"You ran a script\"\n"; + showEnvVarsInLog = 0; }; SSBP_8106229290 /* Carthage */ = { isa = PBXShellScriptBuildPhase; @@ -664,6 +666,7 @@ runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/usr/local/bin/carthage copy-frameworks\n"; + showEnvVarsInLog = 0; }; SSBP_8255377629 /* MyScript */ = { isa = PBXShellScriptBuildPhase; @@ -678,6 +681,7 @@ runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "echo \"You ran a script\"\n"; + showEnvVarsInLog = 0; }; SSBP_8706434794 /* MyScript */ = { isa = PBXShellScriptBuildPhase; @@ -692,6 +696,7 @@ runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "echo \"You ran a script!\"\n"; + showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -2188,7 +2193,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = ""; }; - CL_479264660374 = { + CL_479264660374 /* Build configuration list for PBXLegacyTarget "Legacy" */ = { isa = XCConfigurationList; buildConfigurations = ( BC_805283956103 /* Production Debug */,