Merge pull request #33 from yonaskolb/upgrade_xcodeproj

Upgrade to xcodeproj 0.1.1
This commit is contained in:
Yonas Kolb
2017-08-25 16:21:06 +02:00
committed by GitHub
10 changed files with 133 additions and 109 deletions
@@ -43,7 +43,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
BF3862341101 /* MyFramework.framework in CopyFiles */,
BF3862341101 /* MyFramework.framework */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -71,7 +71,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
BF5986511201,
BF5986511201 /* TestProject.app */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -79,7 +79,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
BF2753556301,
BF2753556301 /* MyFramework.framework */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -155,7 +155,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
BF3515549501,
BF3515549501 /* MyFramework.h */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -266,7 +266,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BF3154421201,
BF3154421201 /* Assets.xcassets */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -308,7 +308,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BF9001417701 /* TestProjectTests.swift in Sources */,
BF9001417701 /* TestProjectTests.swift */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -316,7 +316,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BF9155249601 /* FrameworkFile.swift in Sources */,
BF9155249601 /* FrameworkFile.swift */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -324,8 +324,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BF1073850101 /* AppDelegate.swift in Sources */,
BF1744565901 /* ViewController.swift in Sources */,
BF1073850101 /* AppDelegate.swift */,
BF1744565901 /* ViewController.swift */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+2 -2
View File
@@ -47,13 +47,13 @@
"package": "Yams",
"reason": null,
"repositoryURL": "https://github.com/jpsim/Yams.git",
"version": "0.3.4"
"version": "0.3.5"
},
{
"package": "xcodeproj",
"reason": null,
"repositoryURL": "https://github.com/carambalabs/xcodeproj.git",
"version": "0.0.9"
"version": "0.1.1"
}
],
"version": 1
+1 -1
View File
@@ -16,6 +16,6 @@ let package = Package(
.Package(url: "https://github.com/yonaskolb/JSONUtilities.git", majorVersion: 3, minor: 3),
.Package(url: "https://github.com/kylef/Spectre.git", majorVersion: 0, minor: 7),
.Package(url: "https://github.com/onevcat/Rainbow", majorVersion: 2),
.Package(url: "https://github.com/carambalabs/xcodeproj.git", majorVersion: 0, minor: 0),
.Package(url: "https://github.com/carambalabs/xcodeproj.git", majorVersion: 0, minor: 1),
]
)
+11 -17
View File
@@ -10,7 +10,7 @@ import Foundation
import xcodeproj
import PathKit
extension Array where Element: ProjectElement {
extension Array where Element: Referenceable {
public var referenceList: [String] {
return map { $0.reference }
@@ -21,28 +21,22 @@ extension Array where Element: ProjectElement {
}
}
extension BuildSettings: CustomStringConvertible {
extension Dictionary where Key == String, Value: Any {
public init() {
dictionary = [:]
public func merged(_ dictionary: [Key: Value]) -> [Key: Value] {
var mergedDictionary = self
mergedDictionary.merge(dictionary)
return mergedDictionary
}
public static let empty = BuildSettings()
public func merged(_ buildSettings: BuildSettings) -> BuildSettings {
var mergedSettings = self
mergedSettings.merge(buildSettings)
return mergedSettings
}
public mutating func merge(_ buildSettings: BuildSettings) {
for (key, value) in buildSettings.dictionary {
dictionary[key] = value
public mutating func merge(_ dictionary: [Key: Value]) {
for (key, value) in dictionary {
self[key] = value
}
}
public var description: String {
return dictionary.map { "\($0) = \($1)" }.joined(separator: "\n")
public func equals(_ dictionary: BuildSettings) -> Bool {
return NSDictionary(dictionary: self).isEqual(to: dictionary)
}
}
+10 -15
View File
@@ -9,21 +9,22 @@
import Foundation
import JSONUtilities
import xcodeproj
import PathKit
import Yams
public struct Settings: Equatable, JSONObjectConvertible, CustomStringConvertible {
public let buildSettings: BuildSettings
public let configSettings: [String: Settings]
public let presets: [String]
public init(buildSettings: BuildSettings = .empty, configSettings: [String: Settings] = [:], presets: [String] = []) {
public init(buildSettings: BuildSettings = [:], configSettings: [String: Settings] = [:], presets: [String] = []) {
self.buildSettings = buildSettings
self.configSettings = configSettings
self.presets = presets
}
public init(dictionary: [String: Any]) {
buildSettings = BuildSettings(dictionary: dictionary)
buildSettings = dictionary
configSettings = [:]
presets = []
}
@@ -33,25 +34,26 @@ public struct Settings: Equatable, JSONObjectConvertible, CustomStringConvertibl
public init(jsonDictionary: JSONDictionary) throws {
if jsonDictionary["configs"] != nil || jsonDictionary["presets"] != nil || jsonDictionary["base"] != nil {
presets = jsonDictionary.json(atKeyPath: "presets") ?? []
buildSettings = jsonDictionary.json(atKeyPath: "base") ?? [:]
let buildSettingsDictionary: JSONDictionary = jsonDictionary.json(atKeyPath: "base") ?? [:]
buildSettings = buildSettingsDictionary
configSettings = jsonDictionary.json(atKeyPath: "configs") ?? [:]
} else {
buildSettings = BuildSettings(dictionary: jsonDictionary)
buildSettings = jsonDictionary
configSettings = [:]
presets = []
}
}
public static func ==(lhs: Settings, rhs: Settings) -> Bool {
return lhs.buildSettings == rhs.buildSettings &&
return NSDictionary(dictionary: lhs.buildSettings).isEqual(to: rhs.buildSettings) &&
lhs.configSettings == rhs.configSettings &&
lhs.presets == rhs.presets
}
public var description: String {
var string: String = ""
if !buildSettings.dictionary.isEmpty {
let buildSettingDescription = buildSettings.description
if !buildSettings.isEmpty {
let buildSettingDescription = buildSettings.map { "\($0) = \($1)" }.joined(separator: "\n")
if !configSettings.isEmpty || !presets.isEmpty {
string += "base:\n " + buildSettingDescription.replacingOccurrences(of: "(.)\n", with: "$1\n ", options: .regularExpression, range: nil)
} else {
@@ -87,10 +89,3 @@ extension Settings: ExpressibleByDictionaryLiteral {
self.init(dictionary: dictionary)
}
}
extension BuildSettings: JSONObjectConvertible {
public init(jsonDictionary: JSONDictionary) throws {
self.init(dictionary: jsonDictionary)
}
}
+65 -44
View File
@@ -19,7 +19,6 @@ public class PBXProjGenerator {
let spec: ProjectSpec
let basePath: Path
var objects: [PBXObject] = []
var fileReferencesByPath: [Path: String] = [:]
var groupsByPath: [Path: PBXGroup] = [:]
@@ -31,17 +30,14 @@ public class PBXProjGenerator {
var frameworkFiles: [String] = []
var uuids: Set<String> = []
var projectReference: String
var project: PBXProj!
public init(spec: ProjectSpec, path: Path) {
self.spec = spec
basePath = path
projectReference = ""
projectReference = generateUUID(PBXProject.self, spec.name)
}
public func generateUUID<T: ProjectElement>(_ element: T.Type, _ id: String) -> String {
public func generateUUID<T: PBXObject>(_ element: T.Type, _ id: String) -> String {
var uuid: String = ""
var counter: UInt = 0
let className: String = String(describing: T.self).replacingOccurrences(of: "PBX", with: "")
@@ -55,8 +51,34 @@ public class PBXProjGenerator {
return uuid
}
func addObject(_ object: PBXObject) {
switch object {
case let object as PBXBuildFile: project.buildFiles.append(object)
case let object as PBXAggregateTarget: project.aggregateTargets.append(object)
case let object as PBXContainerItemProxy: project.containerItemProxies.append(object)
case let object as PBXCopyFilesBuildPhase: project.copyFilesBuildPhases.append(object)
case let object as PBXGroup: project.groups.append(object)
case let object as PBXFileElement: project.fileElements.append(object)
case let object as XCConfigurationList: project.configurationLists.append(object)
case let object as XCBuildConfiguration: project.buildConfigurations.append(object)
case let object as PBXVariantGroup: project.variantGroups.append(object)
case let object as PBXTargetDependency: project.targetDependencies.append(object)
case let object as PBXSourcesBuildPhase: project.sourcesBuildPhases.append(object)
case let object as PBXShellScriptBuildPhase: project.shellScriptBuildPhases.append(object)
case let object as PBXResourcesBuildPhase: project.resourcesBuildPhases.append(object)
case let object as PBXFrameworksBuildPhase: project.frameworksBuildPhases.append(object)
case let object as PBXHeadersBuildPhase: project.headersBuildPhases.append(object)
case let object as PBXNativeTarget: project.nativeTargets.append(object)
case let object as PBXFileReference: project.fileReferences.append(object)
case let object as PBXProject: project.projects.append(object)
default: break
}
}
public func generate() throws -> PBXProj {
uuids = []
project = PBXProj(archiveVersion: 1, objectVersion: 46, rootObject: generateUUID(PBXProject.self, spec.name))
let buildConfigs: [XCBuildConfiguration] = spec.configs.map { config in
let buildSettings = spec.getProjectBuildSettings(config: config)
return XCBuildConfiguration(reference: generateUUID(XCBuildConfiguration.self, config.name), name: config.name, baseConfigurationReference: nil, buildSettings: buildSettings)
@@ -64,53 +86,53 @@ public class PBXProjGenerator {
let buildConfigList = XCConfigurationList(reference: generateUUID(XCConfigurationList.self, spec.name), buildConfigurations: buildConfigs.referenceSet, defaultConfigurationName: buildConfigs.first?.name ?? "", defaultConfigurationIsVisible: 0)
objects += buildConfigs.map { .xcBuildConfiguration($0) }
objects.append(.xcConfigurationList(buildConfigList))
buildConfigs.forEach(addObject)
addObject(buildConfigList)
for target in spec.targets {
targetNativeReferences[target.name] = generateUUID(PBXNativeTarget.self, target.name)
let fileReference = PBXFileReference(reference: generateUUID(PBXFileReference.self, target.name), sourceTree: .buildProductsDir, explicitFileType: target.type.fileExtension, path: target.filename, includeInIndex: 0)
objects.append(.pbxFileReference(fileReference))
addObject(fileReference)
targetFileReferences[target.name] = fileReference.reference
let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference.reference), fileRef: fileReference.reference)
objects.append(.pbxBuildFile(buildFile))
addObject(buildFile)
targetBuildFileReferences[target.name] = buildFile.reference
}
let targets = try spec.targets.map(generateTarget)
let productGroup = PBXGroup(reference: generateUUID(PBXGroup.self, "Products"), children: Array(targetFileReferences.values), sourceTree: .group, name: "Products")
objects.append(.pbxGroup(productGroup))
addObject(productGroup)
topLevelGroups.append(productGroup)
if !carthageFrameworksByPlatform.isEmpty {
var platforms: [PBXGroup] = []
for (platform, fileReferences) in carthageFrameworksByPlatform {
let platformGroup = PBXGroup(reference: generateUUID(PBXGroup.self, platform), children: fileReferences, sourceTree: .group, name: platform, path: platform)
objects.append(.pbxGroup(platformGroup))
addObject(platformGroup)
platforms.append(platformGroup)
}
let carthageGroup = PBXGroup(reference: generateUUID(PBXGroup.self, "Carthage"), children: platforms.referenceList, sourceTree: .group, name: "Carthage", path: "Carthage/Build")
objects.append(.pbxGroup(carthageGroup))
addObject(carthageGroup)
topLevelGroups.append(carthageGroup)
}
if !frameworkFiles.isEmpty {
let group = PBXGroup(reference: generateUUID(PBXGroup.self, "Frameworks"), children: frameworkFiles, sourceTree: .group, name: "Frameworks")
objects.append(.pbxGroup(group))
addObject(group)
topLevelGroups.append(group)
}
let mainGroup = PBXGroup(reference: generateUUID(PBXGroup.self, "Project"), children: topLevelGroups.referenceList, sourceTree: .group)
objects.append(.pbxGroup(mainGroup))
addObject(mainGroup)
let knownRegions: [String] = ["en", "Base"]
let pbxProjectRoot = PBXProject(reference: projectReference, buildConfigurationList: buildConfigList.reference, compatibilityVersion: "Xcode 3.2", mainGroup: mainGroup.reference, developmentRegion: "English", knownRegions: knownRegions, targets: targets.referenceList)
objects.append(.pbxProject(pbxProjectRoot))
let root = PBXProject(reference: project.rootObject, buildConfigurationList: buildConfigList.reference, compatibilityVersion: "Xcode 3.2", mainGroup: mainGroup.reference, developmentRegion: "English", knownRegions: knownRegions, targets: targets.referenceList)
project.projects.append(root)
return PBXProj(archiveVersion: 1, objectVersion: 46, rootObject: projectReference, objects: objects)
return project
}
struct SourceFile {
@@ -126,7 +148,7 @@ public class PBXProjGenerator {
settings = ["ATTRIBUTES": ["Public"]]
}
let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference), fileRef: fileReference, settings: settings)
objects.append(.pbxBuildFile(buildFile))
addObject(buildFile)
return SourceFile(path: path, fileReference: fileReference, buildFile: buildFile)
}
@@ -150,9 +172,9 @@ public class PBXProjGenerator {
}
return XCBuildConfiguration(reference: generateUUID(XCBuildConfiguration.self, config.name + target.name), name: config.name, baseConfigurationReference: baseConfigurationReference, buildSettings: buildSettings)
}
objects += configs.map { .xcBuildConfiguration($0) }
configs.forEach(addObject)
let buildConfigList = XCConfigurationList(reference: generateUUID(XCConfigurationList.self, target.name), buildConfigurations: configs.referenceSet, defaultConfigurationName: "")
objects.append(.xcConfigurationList(buildConfigList))
addObject(buildConfigList)
var dependancies: [String] = []
var targetFrameworkBuildFiles: [String] = []
@@ -165,11 +187,11 @@ public class PBXProjGenerator {
guard let dependencyTarget = spec.getTarget(dependencyTargetName) else { continue }
let dependencyFileReference = targetFileReferences[dependencyTargetName]!
let targetProxy = PBXContainerItemProxy(reference: generateUUID(PBXContainerItemProxy.self, target.name), containerPortal: projectReference, remoteGlobalIDString: targetNativeReferences[dependencyTargetName]!, proxyType: .nativeTarget, remoteInfo: dependencyTargetName)
let targetProxy = PBXContainerItemProxy(reference: generateUUID(PBXContainerItemProxy.self, target.name), containerPortal: project.rootObject, remoteGlobalIDString: targetNativeReferences[dependencyTargetName]!, proxyType: .nativeTarget, remoteInfo: dependencyTargetName)
let targetDependancy = PBXTargetDependency(reference: generateUUID(PBXTargetDependency.self, dependencyTargetName + target.name), target: targetNativeReferences[dependencyTargetName]!, targetProxy: targetProxy.reference)
objects.append(.pbxContainerItemProxy(targetProxy))
objects.append(.pbxTargetDependency(targetDependancy))
addObject(targetProxy)
addObject(targetDependancy)
dependancies.append(targetDependancy.reference)
let dependencyBuildFile = targetBuildFileReferences[dependencyTargetName]!
@@ -181,13 +203,13 @@ public class PBXProjGenerator {
// embed app extensions
let embedSettings: [String: Any] = ["ATTRIBUTES": ["RemoveHeadersOnCopy"]]
let embedFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, dependencyFileReference + target.name), fileRef: dependencyFileReference, settings: embedSettings)
objects.append(.pbxBuildFile(embedFile))
addObject(embedFile)
extensions.append(embedFile.reference)
} else {
// embed frameworks
let embedSettings: [String: Any] = ["ATTRIBUTES": ["CodeSignOnCopy", "RemoveHeadersOnCopy"]]
let embedFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, dependencyFileReference + target.name), fileRef: dependencyFileReference, settings: embedSettings)
objects.append(.pbxBuildFile(embedFile))
addObject(embedFile)
copyFiles.append(embedFile.reference)
}
}
@@ -195,7 +217,7 @@ public class PBXProjGenerator {
case let .framework(framework):
let fileReference = getFileReference(path: Path(framework), inPath: basePath)
let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference + target.name), fileRef: fileReference)
objects.append(.pbxBuildFile(buildFile))
addObject(buildFile)
targetFrameworkBuildFiles.append(buildFile.reference)
if !frameworkFiles.contains(fileReference) {
frameworkFiles.append(fileReference)
@@ -217,7 +239,7 @@ public class PBXProjGenerator {
let fileReference = getFileReference(path: frameworkPath, inPath: platformPath)
let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference + target.name), fileRef: fileReference)
objects.append(.pbxBuildFile(buildFile))
addObject(buildFile)
carthageFrameworksByPlatform[target.platform.rawValue]?.append(fileReference)
targetFrameworkBuildFiles.append(buildFile.reference)
@@ -241,17 +263,16 @@ public class PBXProjGenerator {
case let .script(script):
shellScript = script
}
let escapedScript = shellScript.replacingOccurrences(of: "\"", with: "\\\"").replacingOccurrences(of: "\n", with: "\\n")
var shellScriptPhase = PBXShellScriptBuildPhase(
let shellScriptPhase = PBXShellScriptBuildPhase(
reference: generateUUID(PBXShellScriptBuildPhase.self, String(describing: runScript.name) + shellScript + target.name),
files: [],
name: runScript.name ?? "Run Script",
inputPaths: Set(runScript.inputFiles),
outputPaths: Set(runScript.outputFiles),
shellPath: runScript.shell ?? "/bin/sh",
shellScript: escapedScript)
shellScript: shellScript)
shellScriptPhase.runOnlyForDeploymentPostprocessing = runScript.runOnlyWhenInstalling ? 1 : 0
objects.append(.pbxShellScriptBuildPhase(shellScriptPhase))
addObject(shellScriptPhase)
buildPhases.append(shellScriptPhase.reference)
return shellScriptPhase
}
@@ -259,15 +280,15 @@ public class PBXProjGenerator {
_ = try target.prebuildScripts.map(getRunScript)
let sourcesBuildPhase = PBXSourcesBuildPhase(reference: generateUUID(PBXSourcesBuildPhase.self, target.name), files: getBuildFilesForPhase(.sources))
objects.append(.pbxSourcesBuildPhase(sourcesBuildPhase))
addObject(sourcesBuildPhase)
buildPhases.append(sourcesBuildPhase.reference)
let resourcesBuildPhase = PBXResourcesBuildPhase(reference: generateUUID(PBXResourcesBuildPhase.self, target.name), files: getBuildFilesForPhase(.resources))
objects.append(.pbxResourcesBuildPhase(resourcesBuildPhase))
addObject(resourcesBuildPhase)
buildPhases.append(resourcesBuildPhase.reference)
let headersBuildPhase = PBXHeadersBuildPhase(reference: generateUUID(PBXHeadersBuildPhase.self, target.name), files: getBuildFilesForPhase(.headers))
objects.append(.pbxHeadersBuildPhase(headersBuildPhase))
addObject(headersBuildPhase)
buildPhases.append(headersBuildPhase.reference)
if !targetFrameworkBuildFiles.isEmpty {
@@ -277,7 +298,7 @@ public class PBXProjGenerator {
files: Set(targetFrameworkBuildFiles),
runOnlyForDeploymentPostprocessing: 0)
objects.append(.pbxFrameworksBuildPhase(frameworkBuildPhase))
addObject(frameworkBuildPhase)
buildPhases.append(frameworkBuildPhase.reference)
}
@@ -289,7 +310,7 @@ public class PBXProjGenerator {
dstSubfolderSpec: .plugins,
files: Set(extensions))
objects.append(.pbxCopyFilesBuildPhase(copyFilesPhase))
addObject(copyFilesPhase)
buildPhases.append(copyFilesPhase.reference)
}
@@ -301,7 +322,7 @@ public class PBXProjGenerator {
dstSubfolderSpec: .frameworks,
files: Set(copyFiles))
objects.append(.pbxCopyFilesBuildPhase(copyFilesPhase))
addObject(copyFilesPhase)
buildPhases.append(copyFilesPhase.reference)
}
@@ -325,7 +346,7 @@ public class PBXProjGenerator {
if !carthageFrameworks.isEmpty {
let inputPaths = carthageFrameworks.map { "$(SRCROOT)/Carthage/Build/\(target.platform)/\($0)\($0.contains(".") ? "" : ".framework")" }
let carthageScript = PBXShellScriptBuildPhase(reference: generateUUID(PBXShellScriptBuildPhase.self, "Carthage" + target.name), files: [], name: "Carthage", inputPaths: Set(inputPaths), outputPaths: [], shellPath: "/bin/sh", shellScript: "/usr/local/bin/carthage copy-frameworks\n")
objects.append(.pbxShellScriptBuildPhase(carthageScript))
addObject(carthageScript)
buildPhases.append(carthageScript.reference)
}
}
@@ -341,7 +362,7 @@ public class PBXProjGenerator {
name: target.name,
productReference: fileReference,
productType: target.type)
objects.append(.pbxNativeTarget(nativeTarget))
addObject(nativeTarget)
return nativeTarget
}
@@ -365,7 +386,7 @@ public class PBXProjGenerator {
return fileReference
} else {
let fileReference = PBXFileReference(reference: generateUUID(PBXFileReference.self, path.lastComponent), sourceTree: .group, path: path.byRemovingBase(path: inPath).string)
objects.append(.pbxFileReference(fileReference))
addObject(fileReference)
fileReferencesByPath[path] = fileReference.reference
return fileReference.reference
}
@@ -397,10 +418,10 @@ public class PBXProjGenerator {
for path in try localisedDirectory.children() {
let filePath = "\(localisedDirectory.lastComponent)/\(path.lastComponent)"
let fileReference = PBXFileReference(reference: generateUUID(PBXFileReference.self, localisedDirectory.lastComponent), sourceTree: .group, name: localisedDirectory.lastComponentWithoutExtension, path: filePath)
objects.append(.pbxFileReference(fileReference))
addObject(fileReference)
let variantGroup = PBXVariantGroup(reference: generateUUID(PBXVariantGroup.self, path.lastComponent), children: Set([fileReference.reference]), name: path.lastComponent, sourceTree: .group)
objects.append(.pbxVariantGroup(variantGroup))
addObject(variantGroup)
fileReferencesByPath[path] = variantGroup.reference
groupChildren.append(variantGroup.reference)
@@ -414,7 +435,7 @@ public class PBXProjGenerator {
group = cachedGroup
} else {
group = PBXGroup(reference: generateUUID(PBXGroup.self, path.lastComponent), children: groupChildren, sourceTree: .group, name: path.lastComponent, path: groupPath)
objects.append(.pbxGroup(group))
addObject(group)
if depth == 0 {
topLevelGroups.append(group)
}
+1 -1
View File
@@ -161,7 +161,7 @@ public class ProjectGenerator {
func getBuildEntry(_ buildTarget: Scheme.BuildTarget) -> XCScheme.BuildAction.Entry {
let targetReference = pbxProject.objects.nativeTargets.first { $0.name == buildTarget.target }!
let targetReference = pbxProject.nativeTargets.first { $0.name == buildTarget.target }!
let buildableReference = XCScheme.BuildableReference(referencedContainer: "container:\(spec.name).xcodeproj", blueprintIdentifier: targetReference.reference, buildableName: "\(buildTarget.target).\(targetReference.productType!.fileExtension!)", blueprintName: scheme.name)
+17 -3
View File
@@ -10,12 +10,14 @@ import Foundation
import xcodeproj
import PathKit
import ProjectSpec
import Yams
import JSONUtilities
extension ProjectSpec {
public func getProjectBuildSettings(config: Config) -> BuildSettings {
var buildSettings: BuildSettings = .empty
var buildSettings: BuildSettings = [:]
buildSettings += SettingsPresetFile.base.getBuildSettings()
if let type = config.type {
@@ -38,7 +40,7 @@ extension ProjectSpec {
}
public func getBuildSettings(settings: Settings, config: Config) -> BuildSettings {
var buildSettings: BuildSettings = .empty
var buildSettings: BuildSettings = [:]
for preset in settings.presets {
let presetSettings = settingPresets[preset]!
@@ -80,11 +82,23 @@ extension SettingsPresetFile {
return nil
}
guard let buildSettings = try? BuildSettings(path: settingsPath) else {
guard let buildSettings = try? loadSettings(path: settingsPath) else {
print("Error parsing \"\(name)\" settings")
return nil
}
buildSettingFiles[path] = buildSettings
return buildSettings
}
public func loadSettings(path: Path) throws -> BuildSettings {
let content: String = try path.read()
if content == "" {
return [:]
}
let yaml = try Yams.load(yaml: content)
guard let dictionary = yaml as? JSONDictionary else {
throw JSONUtilsError.fileNotAJSONDictionary
}
return dictionary
}
}
@@ -18,11 +18,11 @@ func projectGeneratorTests() {
describe("Project Generator") {
let application = Target(name: "MyApp", type: .application, platform: .iOS,
settings: Settings(buildSettings: BuildSettings(dictionary: ["SETTING_1": "VALUE"])),
settings: Settings(buildSettings: ["SETTING_1": "VALUE"]),
dependencies: [.target("MyFramework")])
let framework = Target(name: "MyFramework", type: .framework, platform: .iOS,
settings: Settings(buildSettings: BuildSettings(dictionary: ["SETTING_2": "VALUE"])))
settings: Settings(buildSettings: ["SETTING_2": "VALUE"]))
let targets = [application, framework]
@@ -31,7 +31,7 @@ func projectGeneratorTests() {
$0.it("generates config defaults") {
let spec = ProjectSpec(name: "test")
let project = try getProject(spec)
let configs = project.pbxproj.objects.buildConfigurations
let configs = project.pbxproj.buildConfigurations
try expect(configs.count) == 2
try expect(configs).contains(name: "Debug")
try expect(configs).contains(name: "Release")
@@ -40,7 +40,7 @@ func projectGeneratorTests() {
$0.it("generates configs") {
let spec = ProjectSpec(name: "test", configs: [Config(name: "config1"), Config(name: "config2")])
let project = try getProject(spec)
let configs = project.pbxproj.objects.buildConfigurations
let configs = project.pbxproj.buildConfigurations
try expect(configs.count) == 2
try expect(configs).contains(name: "config1")
try expect(configs).contains(name: "config2")
@@ -63,14 +63,14 @@ func projectGeneratorTests() {
"SETTING 5": "value 5",
"SETTING 6": "value 6",
]
try expect(debugProjectSettings) == buildSettings
try expect(debugProjectSettings.equals(buildSettings)).beTrue()
var expectedTargetDebugSettings = BuildSettings()
expectedTargetDebugSettings += SettingsPresetFile.product(.application).getBuildSettings()
expectedTargetDebugSettings += SettingsPresetFile.platform(.iOS).getBuildSettings()
expectedTargetDebugSettings += ["SETTING 2": "value 2", "SETTING 3": "value 3", "SETTING": "value"]
try expect(targetDebugSettings) == expectedTargetDebugSettings
try expect(targetDebugSettings.equals(expectedTargetDebugSettings)).beTrue()
}
}
@@ -80,7 +80,7 @@ func projectGeneratorTests() {
$0.it("generates targets") {
let pbxProject = try getPbxProj(spec)
let nativeTargets = pbxProject.objects.nativeTargets
let nativeTargets = pbxProject.nativeTargets
try expect(nativeTargets.count) == 2
try expect(nativeTargets.contains { $0.name == application.name }).beTrue()
try expect(nativeTargets.contains { $0.name == framework.name }).beTrue()
@@ -88,16 +88,16 @@ func projectGeneratorTests() {
$0.it("generates dependencies") {
let pbxProject = try getPbxProj(spec)
let nativeTargets = pbxProject.objects.nativeTargets
let dependencies = pbxProject.objects.targetDependencies
let nativeTargets = pbxProject.nativeTargets
let dependencies = pbxProject.targetDependencies
try expect(dependencies.count) == 1
try expect(dependencies.first!.target) == nativeTargets.first { $0.name == framework.name }!.reference
}
$0.it("generates dependencies") {
let pbxProject = try getPbxProj(spec)
let nativeTargets = pbxProject.objects.nativeTargets
let dependencies = pbxProject.objects.targetDependencies
let nativeTargets = pbxProject.nativeTargets
let dependencies = pbxProject.targetDependencies
try expect(dependencies.count) == 1
try expect(dependencies.first!.target) == nativeTargets.first { $0.name == framework.name }!.reference
}
@@ -108,9 +108,9 @@ func projectGeneratorTests() {
scriptSpec.targets[0].postbuildScripts = [RunScript(script: .script("script2"))]
let pbxProject = try getPbxProj(scriptSpec)
guard let buildPhases = pbxProject.objects.nativeTargets.first?.buildPhases else { throw failure("Build phases not found") }
guard let buildPhases = pbxProject.nativeTargets.first?.buildPhases else { throw failure("Build phases not found") }
let scripts = pbxProject.objects.shellScriptBuildPhases
let scripts = pbxProject.shellScriptBuildPhases
let script1 = scripts[0]
let script2 = scripts[1]
try expect(scripts.count) == 2
@@ -129,7 +129,7 @@ func projectGeneratorTests() {
let scheme = Scheme(name: "MyScheme", build: Scheme.Build(targets: [buildTarget]))
let spec = ProjectSpec(name: "test", targets: [application, framework], schemes: [scheme])
let project = try getProject(spec)
guard let target = project.pbxproj.objects.nativeTargets.first(where: { $0.name == application.name }) else { throw failure("Target not found") }
guard let target = project.pbxproj.nativeTargets.first(where: { $0.name == application.name }) else { throw failure("Target not found") }
guard let xcscheme = project.sharedData?.schemes.first else { throw failure("Scheme not found") }
try expect(scheme.name) == "MyScheme"
guard let buildActionEntry = xcscheme.buildAction?.buildActionEntries.first else { throw failure("Build Action entry not found") }
@@ -171,7 +171,7 @@ func projectGeneratorTests() {
try expect(project.sharedData?.schemes.count) == 2
guard let nativeTarget = project.pbxproj.objects.nativeTargets.first(where: { $0.name == application.name }) else { throw failure("Target not found") }
guard let nativeTarget = project.pbxproj.nativeTargets.first(where: { $0.name == application.name }) else { throw failure("Target not found") }
guard let xcscheme = project.sharedData?.schemes.first(where: { $0.name == "\(target.name) Test" }) else { throw failure("Scheme not found") }
guard let buildActionEntry = xcscheme.buildAction?.buildActionEntries.first else { throw failure("Build Action entry not found") }
try expect(buildActionEntry.buildableReference.blueprintIdentifier) == nativeTarget.reference
@@ -95,13 +95,13 @@ func specLoadingTests() {
let presets = ["preset1"]
let preset1 = Settings(buildSettings: buildSettings, configSettings: [:], presets: [])
let preset2 = Settings(buildSettings: .empty, configSettings: configSettings, presets: [])
let preset2 = Settings(buildSettings: [:], configSettings: configSettings, presets: [])
let preset3 = Settings(buildSettings: buildSettings, configSettings: configSettings, presets: [])
let preset4 = Settings(buildSettings: buildSettings, configSettings: [:], presets: [])
let preset5 = Settings(buildSettings: buildSettings, configSettings: [:], presets: presets)
let preset6 = Settings(buildSettings: buildSettings, configSettings: configSettings, presets: presets)
let preset7 = Settings(buildSettings: buildSettings, configSettings: ["config1": Settings(buildSettings: buildSettings, presets: presets)])
let preset8 = Settings(buildSettings: .empty, configSettings: ["config1": Settings(configSettings: configSettings)])
let preset8 = Settings(buildSettings: [:], configSettings: ["config1": Settings(configSettings: configSettings)])
try expect(spec.settingPresets.count) == 8
try expect(spec.settingPresets["preset1"]) == preset1