mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2026-03-18 20:02:25 +00:00
Rename uses of spec to project
This commit is contained in:
1 parent
e589364ae8
commit
29f4fa2123
11 files changed
+362
-362
No files matched your search
+14
-14
@@ -21,37 +21,37 @@ func generate(spec: String, project: String, isQuiet: Bool, justVersion: Bool) {
|
||||
exit(1)
|
||||
}
|
||||
|
||||
let specPath = Path(spec).absolute()
|
||||
let projectPath = project == "" ? specPath.parent() : Path(project).absolute()
|
||||
let projectSpecPath = Path(spec).absolute()
|
||||
let projectPath = project == "" ? projectSpecPath.parent() : Path(project).absolute()
|
||||
|
||||
if !specPath.exists {
|
||||
fatalError("No project spec found at \(specPath.absolute())")
|
||||
if !projectSpecPath.exists {
|
||||
fatalError("No project spec found at \(projectSpecPath.absolute())")
|
||||
}
|
||||
|
||||
let spec: Project
|
||||
let project: Project
|
||||
do {
|
||||
spec = try Project(path: specPath)
|
||||
logger.info("📋 Loaded spec:\n \(spec.debugDescription.replacingOccurrences(of: "\n", with: "\n "))")
|
||||
project = try Project(path: projectSpecPath)
|
||||
logger.info("📋 Loaded project:\n \(project.debugDescription.replacingOccurrences(of: "\n", with: "\n "))")
|
||||
} catch let error as JSONUtilities.DecodingError {
|
||||
fatalError("Parsing spec failed: \(error.description)")
|
||||
fatalError("Parsing project spec failed: \(error.description)")
|
||||
} catch {
|
||||
fatalError("Parsing spec failed: \(error.localizedDescription)")
|
||||
fatalError("Parsing project spec failed: \(error.localizedDescription)")
|
||||
}
|
||||
|
||||
do {
|
||||
logger.info("⚙️ Generating project...")
|
||||
let projectGenerator = ProjectGenerator(spec: spec)
|
||||
let project = try projectGenerator.generateProject()
|
||||
let projectGenerator = ProjectGenerator(project: project)
|
||||
let xcodeProject = try projectGenerator.generateXcodeProject()
|
||||
|
||||
logger.info("⚙️ Writing project...")
|
||||
|
||||
let projectFile = projectPath + "\(spec.name).xcodeproj"
|
||||
let projectFile = projectPath + "\(project.name).xcodeproj"
|
||||
let tempPath = Path.temporary + "XcodeGen_\(Int(NSTimeIntervalSince1970))"
|
||||
try? tempPath.delete()
|
||||
if projectFile.exists {
|
||||
try projectFile.copy(tempPath)
|
||||
}
|
||||
try project.write(path: tempPath, override: true)
|
||||
try xcodeProject.write(path: tempPath, override: true)
|
||||
try? projectFile.delete()
|
||||
try tempPath.copy(projectFile)
|
||||
try? tempPath.delete()
|
||||
@@ -69,7 +69,7 @@ command(
|
||||
"spec",
|
||||
default: "project.yml",
|
||||
flag: "s",
|
||||
description: "The path to the spec file"
|
||||
description: "The path to the project spec file"
|
||||
),
|
||||
Option<String>(
|
||||
"project",
|
||||
|
||||
@@ -7,9 +7,9 @@ import Yams
|
||||
|
||||
public class PBXProjGenerator {
|
||||
|
||||
let spec: Project
|
||||
let project: Project
|
||||
|
||||
let proj: PBXProj
|
||||
let pbxProj: PBXProj
|
||||
var sourceGenerator: SourceGenerator!
|
||||
|
||||
var targetObjects: [String: ObjectReference<PBXTarget>] = [:]
|
||||
@@ -22,20 +22,20 @@ public class PBXProjGenerator {
|
||||
var generated = false
|
||||
|
||||
var carthageBuildPath: String {
|
||||
return spec.options.carthageBuildPath ?? "Carthage/Build"
|
||||
return project.options.carthageBuildPath ?? "Carthage/Build"
|
||||
}
|
||||
|
||||
public init(spec: Project) {
|
||||
self.spec = spec
|
||||
proj = PBXProj(rootObject: "", objectVersion: 46)
|
||||
sourceGenerator = SourceGenerator(spec: spec) { [unowned self] id, object in
|
||||
public init(project: Project) {
|
||||
self.project = project
|
||||
pbxProj = PBXProj(rootObject: "", objectVersion: 46)
|
||||
sourceGenerator = SourceGenerator(project: project) { [unowned self] id, object in
|
||||
self.addObject(id: id, object)
|
||||
}
|
||||
}
|
||||
|
||||
func addObject(id: String, _ object: PBXObject) -> String {
|
||||
let reference = proj.objects.generateReference(object, id)
|
||||
proj.objects.addObject(object, reference: reference)
|
||||
let reference = pbxProj.objects.generateReference(object, id)
|
||||
pbxProj.objects.addObject(object, reference: reference)
|
||||
return reference
|
||||
}
|
||||
|
||||
@@ -50,15 +50,15 @@ public class PBXProjGenerator {
|
||||
}
|
||||
generated = true
|
||||
|
||||
for group in spec.fileGroups {
|
||||
for group in project.fileGroups {
|
||||
try sourceGenerator.getFileGroups(path: group)
|
||||
}
|
||||
|
||||
let buildConfigs: [ObjectReference<XCBuildConfiguration>] = spec.configs.map { config in
|
||||
let buildSettings = spec.getProjectBuildSettings(config: config)
|
||||
let buildConfigs: [ObjectReference<XCBuildConfiguration>] = project.configs.map { config in
|
||||
let buildSettings = project.getProjectBuildSettings(config: config)
|
||||
var baseConfigurationReference: String?
|
||||
if let configPath = spec.configFiles[config.name] {
|
||||
baseConfigurationReference = sourceGenerator.getContainedFileReference(path: spec.basePath + configPath)
|
||||
if let configPath = project.configFiles[config.name] {
|
||||
baseConfigurationReference = sourceGenerator.getContainedFileReference(path: project.basePath + configPath)
|
||||
}
|
||||
return createObject(
|
||||
id: config.name,
|
||||
@@ -70,9 +70,9 @@ public class PBXProjGenerator {
|
||||
)
|
||||
}
|
||||
|
||||
let configName = spec.options.defaultConfig ?? buildConfigs.first?.object.name ?? ""
|
||||
let configName = project.options.defaultConfig ?? buildConfigs.first?.object.name ?? ""
|
||||
let buildConfigList = createObject(
|
||||
id: spec.name,
|
||||
id: project.name,
|
||||
XCConfigurationList(
|
||||
buildConfigurations: buildConfigs.map { $0.reference },
|
||||
defaultConfigurationName: configName
|
||||
@@ -84,26 +84,26 @@ public class PBXProjGenerator {
|
||||
PBXGroup(
|
||||
children: [],
|
||||
sourceTree: .group,
|
||||
usesTabs: spec.options.usesTabs,
|
||||
indentWidth: spec.options.indentWidth,
|
||||
tabWidth: spec.options.tabWidth
|
||||
usesTabs: project.options.usesTabs,
|
||||
indentWidth: project.options.indentWidth,
|
||||
tabWidth: project.options.tabWidth
|
||||
)
|
||||
)
|
||||
|
||||
let project = createObject(
|
||||
id: spec.name,
|
||||
let pbxProject = createObject(
|
||||
id: project.name,
|
||||
PBXProject(
|
||||
name: spec.name,
|
||||
name: project.name,
|
||||
buildConfigurationList: buildConfigList.reference,
|
||||
compatibilityVersion: "Xcode 3.2",
|
||||
mainGroup: mainGroup.reference,
|
||||
developmentRegion: spec.options.developmentLanguage ?? "en"
|
||||
developmentRegion: project.options.developmentLanguage ?? "en"
|
||||
)
|
||||
)
|
||||
|
||||
proj.rootObject = project.reference
|
||||
pbxProj.rootObject = pbxProject.reference
|
||||
|
||||
for target in spec.targets {
|
||||
for target in project.targets {
|
||||
let targetObject: PBXTarget
|
||||
|
||||
if target.isLegacy {
|
||||
@@ -147,7 +147,7 @@ public class PBXProjGenerator {
|
||||
)
|
||||
}
|
||||
|
||||
try spec.targets.forEach(generateTarget)
|
||||
try project.targets.forEach(generateTarget)
|
||||
|
||||
let productGroup = createObject(
|
||||
id: "Products",
|
||||
@@ -205,31 +205,31 @@ public class PBXProjGenerator {
|
||||
mainGroup.object.children = Array(topLevelGroups)
|
||||
sortGroups(group: mainGroup)
|
||||
|
||||
let projectAttributes: [String: Any] = ["LastUpgradeCheck": spec.xcodeVersion]
|
||||
.merged(spec.attributes)
|
||||
let projectAttributes: [String: Any] = ["LastUpgradeCheck": project.xcodeVersion]
|
||||
.merged(project.attributes)
|
||||
.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
|
||||
pbxProject.object.knownRegions = sourceGenerator.knownRegions.sorted()
|
||||
pbxProject.object.targets = targetObjects.values.sorted { $0.object.name < $1.object.name }.map { $0.reference }
|
||||
pbxProject.object.attributes = projectAttributes
|
||||
|
||||
return proj
|
||||
return pbxProj
|
||||
}
|
||||
|
||||
func generateTargetAttributes() -> [String: Any]? {
|
||||
|
||||
var targetAttributes: [String: [String: Any]] = [:]
|
||||
|
||||
let uiTestTargets = proj.objects.nativeTargets.objectReferences.filter { $0.object.productType == .uiTestBundle }
|
||||
let uiTestTargets = pbxProj.objects.nativeTargets.objectReferences.filter { $0.object.productType == .uiTestBundle }
|
||||
for uiTestTarget in uiTestTargets {
|
||||
|
||||
// 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 }
|
||||
guard let buildConfigurationReferences = self.pbxProj.objects.configurationLists[configurationList]?.buildConfigurations else { return nil }
|
||||
|
||||
let configs = buildConfigurationReferences
|
||||
.flatMap { ref in self.proj.objects.buildConfigurations[ref] }
|
||||
.flatMap { ref in self.pbxProj.objects.buildConfigurations[ref] }
|
||||
|
||||
return configs
|
||||
.flatMap { $0.buildSettings["TEST_TARGET_NAME"] as? String }
|
||||
@@ -237,12 +237,12 @@ public class PBXProjGenerator {
|
||||
}
|
||||
|
||||
guard let name = testTargetName(uiTestTarget.object) else { continue }
|
||||
guard let target = self.proj.objects.targets(named: name).first else { continue }
|
||||
guard let target = self.pbxProj.objects.targets(named: name).first else { continue }
|
||||
|
||||
targetAttributes[uiTestTarget.reference, default: [:]].merge(["TestTargetID": target.reference])
|
||||
}
|
||||
|
||||
for target in spec.targets {
|
||||
for target in project.targets {
|
||||
guard let targetReference = targetObjects[target.name]?.reference else {
|
||||
continue
|
||||
}
|
||||
@@ -251,10 +251,10 @@ public class PBXProjGenerator {
|
||||
}
|
||||
|
||||
func getSingleBuildSetting(_ setting: String) -> String? {
|
||||
let settings = spec.configs.flatMap {
|
||||
spec.getCombinedBuildSettings(basePath: spec.basePath, target: target, config: $0)[setting] as? String
|
||||
let settings = project.configs.flatMap {
|
||||
project.getCombinedBuildSettings(basePath: project.basePath, target: target, config: $0)[setting] as? String
|
||||
}
|
||||
guard settings.count == spec.configs.count,
|
||||
guard settings.count == project.configs.count,
|
||||
let firstSetting = settings.first,
|
||||
settings.filter({ $0 == firstSetting }).count == settings.count else {
|
||||
return nil
|
||||
@@ -279,7 +279,7 @@ public class PBXProjGenerator {
|
||||
// sort children
|
||||
let children = group.object.children
|
||||
.flatMap { reference -> ObjectReference<PBXFileElement>? in
|
||||
guard let fileElement = proj.objects.getFileElement(reference: reference) else {
|
||||
guard let fileElement = pbxProj.objects.getFileElement(reference: reference) else {
|
||||
return nil
|
||||
}
|
||||
return ObjectReference(reference: reference, object: fileElement)
|
||||
@@ -290,12 +290,12 @@ public class PBXProjGenerator {
|
||||
} else {
|
||||
return child1.object.sortOrder < child2.object.sortOrder
|
||||
}
|
||||
}
|
||||
}
|
||||
group.object.children = children.map { $0.reference }.filter { $0 != group.reference }
|
||||
|
||||
// sort sub groups
|
||||
let childGroups = group.object.children.flatMap { reference -> ObjectReference<PBXGroup>? in
|
||||
guard let group = proj.objects.groups[reference] else {
|
||||
guard let group = pbxProj.objects.groups[reference] else {
|
||||
return nil
|
||||
}
|
||||
return ObjectReference(reference: reference, object: group) }
|
||||
@@ -312,23 +312,23 @@ public class PBXProjGenerator {
|
||||
var plistPath: Path?
|
||||
var searchForPlist = true
|
||||
|
||||
let configs: [ObjectReference<XCBuildConfiguration>] = spec.configs.map { config in
|
||||
var buildSettings = spec.getTargetBuildSettings(target: target, config: config)
|
||||
let configs: [ObjectReference<XCBuildConfiguration>] = project.configs.map { config in
|
||||
var buildSettings = project.getTargetBuildSettings(target: target, config: config)
|
||||
|
||||
// automatically set INFOPLIST_FILE path
|
||||
if !spec.targetHasBuildSetting("INFOPLIST_FILE", basePath: spec.basePath, target: target, config: config) {
|
||||
if !project.targetHasBuildSetting("INFOPLIST_FILE", basePath: project.basePath, target: target, config: config) {
|
||||
if searchForPlist {
|
||||
plistPath = getInfoPlist(target.sources)
|
||||
searchForPlist = false
|
||||
}
|
||||
if let plistPath = plistPath {
|
||||
buildSettings["INFOPLIST_FILE"] = plistPath.byRemovingBase(path: spec.basePath)
|
||||
buildSettings["INFOPLIST_FILE"] = plistPath.byRemovingBase(path: project.basePath)
|
||||
}
|
||||
}
|
||||
|
||||
// automatically calculate bundle id
|
||||
if let bundleIdPrefix = spec.options.bundleIdPrefix,
|
||||
!spec.targetHasBuildSetting("PRODUCT_BUNDLE_IDENTIFIER", basePath: spec.basePath, target: target, config: config) {
|
||||
if let bundleIdPrefix = project.options.bundleIdPrefix,
|
||||
!project.targetHasBuildSetting("PRODUCT_BUNDLE_IDENTIFIER", basePath: project.basePath, target: target, config: config) {
|
||||
let characterSet = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "-.")).inverted
|
||||
let escapedTargetName = target.name
|
||||
.replacingOccurrences(of: "_", with: "-")
|
||||
@@ -339,10 +339,10 @@ public class PBXProjGenerator {
|
||||
|
||||
// automatically set test target name
|
||||
if target.type == .uiTestBundle,
|
||||
!spec.targetHasBuildSetting("TEST_TARGET_NAME", basePath: spec.basePath, target: target, config: config) {
|
||||
!project.targetHasBuildSetting("TEST_TARGET_NAME", basePath: project.basePath, target: target, config: config) {
|
||||
for dependency in target.dependencies {
|
||||
if dependency.type == .target,
|
||||
let dependencyTarget = spec.getTarget(dependency.reference),
|
||||
let dependencyTarget = project.getTarget(dependency.reference),
|
||||
dependencyTarget.type == .application {
|
||||
buildSettings["TEST_TARGET_NAME"] = dependencyTarget.name
|
||||
break
|
||||
@@ -367,7 +367,7 @@ public class PBXProjGenerator {
|
||||
|
||||
var baseConfigurationReference: String?
|
||||
if let configPath = target.configFiles[config.name] {
|
||||
baseConfigurationReference = sourceGenerator.getContainedFileReference(path: spec.basePath + configPath)
|
||||
baseConfigurationReference = sourceGenerator.getContainedFileReference(path: project.basePath + configPath)
|
||||
}
|
||||
let buildConfig = XCBuildConfiguration(
|
||||
name: config.name,
|
||||
@@ -395,13 +395,13 @@ public class PBXProjGenerator {
|
||||
switch dependency.type {
|
||||
case .target:
|
||||
let dependencyTargetName = dependency.reference
|
||||
guard let dependencyTarget = spec.getTarget(dependencyTargetName) else { continue }
|
||||
guard let dependencyTarget = project.getTarget(dependencyTargetName) else { continue }
|
||||
let dependencyFileReference = targetFileReferences[dependencyTargetName]!
|
||||
|
||||
let targetProxy = createObject(
|
||||
id: target.name,
|
||||
PBXContainerItemProxy(
|
||||
containerPortal: proj.rootObject,
|
||||
containerPortal: pbxProj.rootObject,
|
||||
remoteGlobalIDString: targetObjects[dependencyTargetName]!.reference,
|
||||
proxyType: .nativeTarget,
|
||||
remoteInfo: dependencyTargetName
|
||||
@@ -454,13 +454,13 @@ public class PBXProjGenerator {
|
||||
if dependency.implicit {
|
||||
fileReference = sourceGenerator.getFileReference(
|
||||
path: Path(dependency.reference),
|
||||
inPath: spec.basePath,
|
||||
inPath: project.basePath,
|
||||
sourceTree: .buildProductsDir
|
||||
)
|
||||
} else {
|
||||
fileReference = sourceGenerator.getFileReference(
|
||||
path: Path(dependency.reference),
|
||||
inPath: spec.basePath
|
||||
inPath: project.basePath
|
||||
)
|
||||
}
|
||||
|
||||
@@ -528,7 +528,7 @@ public class PBXProjGenerator {
|
||||
let shellScript: String
|
||||
switch buildScript.script {
|
||||
case let .path(path):
|
||||
shellScript = try (spec.basePath + path).read()
|
||||
shellScript = try (project.basePath + path).read()
|
||||
case let .script(script):
|
||||
shellScript = script
|
||||
}
|
||||
@@ -630,7 +630,7 @@ 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 carthageExecutable = spec.options.carthageExecutablePath ?? "carthage"
|
||||
let carthageExecutable = project.options.carthageExecutablePath ?? "carthage"
|
||||
let carthageScript = createObject(
|
||||
id: "Carthage" + target.name,
|
||||
PBXShellScriptBuildPhase(
|
||||
@@ -663,7 +663,7 @@ public class PBXProjGenerator {
|
||||
func getInfoPlist(_ sources: [TargetSource]) -> Path? {
|
||||
return sources
|
||||
.lazy
|
||||
.map { self.spec.basePath + $0.path }
|
||||
.map { self.project.basePath + $0.path }
|
||||
.flatMap { (path) -> Path? in
|
||||
if path.isFile {
|
||||
return path.lastComponent == "Info.plist" ? path : nil
|
||||
@@ -698,7 +698,7 @@ public class PBXProjGenerator {
|
||||
if visitedTargets[targetName] == true {
|
||||
return []
|
||||
}
|
||||
if let target = spec.getTarget(targetName) {
|
||||
if let target = project.getTarget(targetName) {
|
||||
frameworks += getAllCarthageDependencies(target: target, visitedTargets: visitedTargets)
|
||||
}
|
||||
default: break
|
||||
|
||||
@@ -7,23 +7,23 @@ import Yams
|
||||
|
||||
public class ProjectGenerator {
|
||||
|
||||
let spec: Project
|
||||
let project: Project
|
||||
|
||||
public init(spec: Project) {
|
||||
self.spec = spec
|
||||
public init(project: Project) {
|
||||
self.project = project
|
||||
}
|
||||
|
||||
var defaultDebugConfig: Config {
|
||||
return spec.configs.first { $0.type == .debug }!
|
||||
return project.configs.first { $0.type == .debug }!
|
||||
}
|
||||
|
||||
var defaultReleaseConfig: Config {
|
||||
return spec.configs.first { $0.type == .release }!
|
||||
return project.configs.first { $0.type == .release }!
|
||||
}
|
||||
|
||||
public func generateProject() throws -> XcodeProj {
|
||||
try spec.validate()
|
||||
let pbxProjGenerator = PBXProjGenerator(spec: spec)
|
||||
public func generateXcodeProject() throws -> XcodeProj {
|
||||
try project.validate()
|
||||
let pbxProjGenerator = PBXProjGenerator(project: project)
|
||||
let pbxProject = try pbxProjGenerator.generate()
|
||||
let workspace = try generateWorkspace()
|
||||
let sharedData = try generateSharedData(pbxProject: pbxProject)
|
||||
@@ -41,9 +41,9 @@ public class ProjectGenerator {
|
||||
func getBuildEntry(_ buildTarget: Scheme.BuildTarget) -> XCScheme.BuildAction.Entry {
|
||||
|
||||
let targetReference = pbxProject.objects.targets(named: buildTarget.target).first!
|
||||
let target = spec.getTarget(buildTarget.target)!
|
||||
let target = project.getTarget(buildTarget.target)!
|
||||
let buildableReference = XCScheme.BuildableReference(
|
||||
referencedContainer: "container:\(spec.name).xcodeproj",
|
||||
referencedContainer: "container:\(project.name).xcodeproj",
|
||||
blueprintIdentifier: targetReference.reference,
|
||||
buildableName: target.filename,
|
||||
blueprintName: buildTarget.target
|
||||
@@ -136,8 +136,8 @@ public class ProjectGenerator {
|
||||
|
||||
return XCScheme(
|
||||
name: scheme.name,
|
||||
lastUpgradeVersion: spec.xcodeVersion,
|
||||
version: spec.schemeVersion,
|
||||
lastUpgradeVersion: project.xcodeVersion,
|
||||
version: project.schemeVersion,
|
||||
buildAction: buildAction,
|
||||
testAction: testAction,
|
||||
launchAction: launchAction,
|
||||
@@ -150,19 +150,19 @@ public class ProjectGenerator {
|
||||
func generateSharedData(pbxProject: PBXProj) throws -> XCSharedData {
|
||||
var xcschemes: [XCScheme] = []
|
||||
|
||||
for scheme in spec.schemes {
|
||||
for scheme in project.schemes {
|
||||
let xcscheme = try generateScheme(scheme, pbxProject: pbxProject)
|
||||
xcschemes.append(xcscheme)
|
||||
}
|
||||
|
||||
for target in spec.targets {
|
||||
for target in project.targets {
|
||||
if let targetScheme = target.scheme {
|
||||
|
||||
if targetScheme.configVariants.isEmpty {
|
||||
let schemeName = target.name
|
||||
|
||||
let debugConfig = spec.configs.first { $0.type == .debug }!
|
||||
let releaseConfig = spec.configs.first { $0.type == .release }!
|
||||
let debugConfig = project.configs.first { $0.type == .debug }!
|
||||
let releaseConfig = project.configs.first { $0.type == .release }!
|
||||
|
||||
let scheme = Scheme(
|
||||
name: schemeName,
|
||||
@@ -178,9 +178,9 @@ public class ProjectGenerator {
|
||||
|
||||
let schemeName = "\(target.name) \(configVariant)"
|
||||
|
||||
let debugConfig = spec.configs
|
||||
let debugConfig = project.configs
|
||||
.first { $0.type == .debug && $0.name.contains(configVariant) }!
|
||||
let releaseConfig = spec.configs
|
||||
let releaseConfig = project.configs
|
||||
.first { $0.type == .release && $0.name.contains(configVariant) }!
|
||||
|
||||
let scheme = Scheme(
|
||||
|
||||
@@ -17,7 +17,7 @@ class SourceGenerator {
|
||||
private var groupsByPath: [Path: ObjectReference<PBXGroup>] = [:]
|
||||
private var variantGroupsByPath: [Path: ObjectReference<PBXVariantGroup>] = [:]
|
||||
|
||||
private let spec: Project
|
||||
private let project: Project
|
||||
var addObjectClosure: (String, PBXObject) -> String
|
||||
var targetSourceExcludePaths: Set<Path> = []
|
||||
var defaultExcludedFiles = [
|
||||
@@ -28,8 +28,8 @@ class SourceGenerator {
|
||||
|
||||
private(set) var knownRegions: Set<String> = []
|
||||
|
||||
init(spec: Project, addObjectClosure: @escaping (String, PBXObject) -> String) {
|
||||
self.spec = spec
|
||||
init(project: Project, addObjectClosure: @escaping (String, PBXObject) -> String) {
|
||||
self.project = project
|
||||
self.addObjectClosure = addObjectClosure
|
||||
}
|
||||
|
||||
@@ -43,12 +43,12 @@ class SourceGenerator {
|
||||
}
|
||||
|
||||
func getAllSourceFiles(sources: [TargetSource]) throws -> [SourceFile] {
|
||||
return try sources.flatMap { try getSourceFiles(targetSource: $0, path: spec.basePath + $0.path) }
|
||||
return try sources.flatMap { try getSourceFiles(targetSource: $0, path: project.basePath + $0.path) }
|
||||
}
|
||||
|
||||
// get groups without build files. Use for Project.fileGroups
|
||||
func getFileGroups(path: String) throws {
|
||||
let fullPath = spec.basePath + path
|
||||
let fullPath = project.basePath + path
|
||||
_ = try getSourceFiles(targetSource: TargetSource(path: path), path: fullPath)
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class SourceGenerator {
|
||||
}
|
||||
|
||||
func getContainedFileReference(path: Path) -> String {
|
||||
let createIntermediateGroups = spec.options.createIntermediateGroups
|
||||
let createIntermediateGroups = project.options.createIntermediateGroups
|
||||
|
||||
let parentPath = path.parent()
|
||||
let fileReference = getFileReference(path: path, inPath: parentPath)
|
||||
@@ -122,7 +122,7 @@ class SourceGenerator {
|
||||
.sorted()
|
||||
.map { path in
|
||||
createObject(
|
||||
id: path.byRemovingBase(path: spec.basePath).string,
|
||||
id: path.byRemovingBase(path: project.basePath).string,
|
||||
PBXFileReference(
|
||||
sourceTree: .group,
|
||||
lastKnownFileType: "wrapper.xcdatamodel",
|
||||
@@ -141,7 +141,7 @@ class SourceGenerator {
|
||||
return versionGroup
|
||||
} else {
|
||||
let fileReference = createObject(
|
||||
id: path.byRemovingBase(path: spec.basePath).string,
|
||||
id: path.byRemovingBase(path: project.basePath).string,
|
||||
PBXFileReference(
|
||||
sourceTree: sourceTree,
|
||||
name: fileReferenceName,
|
||||
@@ -182,18 +182,18 @@ class SourceGenerator {
|
||||
groupReference = cachedGroup
|
||||
} else {
|
||||
|
||||
// lives outside the spec base path
|
||||
let isOutOfBasePath = !path.absolute().string.contains(spec.basePath.absolute().string)
|
||||
// lives outside the project base path
|
||||
let isOutOfBasePath = !path.absolute().string.contains(project.basePath.absolute().string)
|
||||
|
||||
// has no valid parent paths
|
||||
let isRootPath = isOutOfBasePath || path.parent() == spec.basePath
|
||||
let isRootPath = isOutOfBasePath || path.parent() == project.basePath
|
||||
|
||||
// is a top level group in the project
|
||||
let isTopLevelGroup = (isBaseGroup && !createIntermediateGroups) || isRootPath
|
||||
|
||||
let groupName = name ?? path.lastComponent
|
||||
let groupPath = isTopLevelGroup ?
|
||||
path.byRemovingBase(path: spec.basePath).string :
|
||||
path.byRemovingBase(path: project.basePath).string :
|
||||
path.lastComponent
|
||||
let group = PBXGroup(
|
||||
children: children,
|
||||
@@ -201,7 +201,7 @@ class SourceGenerator {
|
||||
name: groupName != groupPath ? groupName : nil,
|
||||
path: groupPath
|
||||
)
|
||||
groupReference = createObject(id: path.byRemovingBase(path: spec.basePath).string, group)
|
||||
groupReference = createObject(id: path.byRemovingBase(path: project.basePath).string, group)
|
||||
groupsByPath[path] = groupReference
|
||||
|
||||
if isTopLevelGroup {
|
||||
@@ -222,7 +222,7 @@ class SourceGenerator {
|
||||
sourceTree: .group,
|
||||
name: path.lastComponent
|
||||
)
|
||||
variantGroup = createObject(id: path.byRemovingBase(path: spec.basePath).string, group)
|
||||
variantGroup = createObject(id: path.byRemovingBase(path: project.basePath).string, group)
|
||||
variantGroupsByPath[path] = variantGroup
|
||||
}
|
||||
return variantGroup
|
||||
@@ -230,7 +230,7 @@ class SourceGenerator {
|
||||
|
||||
/// Collects all the excluded paths within the targetSource
|
||||
private func getSourceExcludes(targetSource: TargetSource) -> Set<Path> {
|
||||
let rootSourcePath = spec.basePath + targetSource.path
|
||||
let rootSourcePath = project.basePath + targetSource.path
|
||||
|
||||
return Set(
|
||||
targetSource.excludes.map {
|
||||
@@ -316,7 +316,7 @@ class SourceGenerator {
|
||||
return localisedDirectories.first { $0.lastComponent == "\(languageId).lproj" }
|
||||
}
|
||||
return findLocalisedDirectory(by: "Base") ??
|
||||
findLocalisedDirectory(by: NSLocale.canonicalLanguageIdentifier(from: spec.options.developmentLanguage ?? "en"))
|
||||
findLocalisedDirectory(by: NSLocale.canonicalLanguageIdentifier(from: project.options.developmentLanguage ?? "en"))
|
||||
}()
|
||||
|
||||
knownRegions.formUnion(localisedDirectories.map { $0.lastComponentWithoutExtension })
|
||||
@@ -385,10 +385,10 @@ class SourceGenerator {
|
||||
let group = getGroup(
|
||||
path: path,
|
||||
mergingChildren: groupChildren,
|
||||
createIntermediateGroups: spec.options.createIntermediateGroups,
|
||||
createIntermediateGroups: project.options.createIntermediateGroups,
|
||||
isBaseGroup: isBaseGroup
|
||||
)
|
||||
if spec.options.createIntermediateGroups {
|
||||
if project.options.createIntermediateGroups {
|
||||
createIntermediaGroups(for: group.reference, at: path)
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ class SourceGenerator {
|
||||
targetSourceExcludePaths = getSourceExcludes(targetSource: targetSource)
|
||||
|
||||
let type = targetSource.type ?? (path.isFile || path.extension != nil ? .file : .group)
|
||||
let createIntermediateGroups = spec.options.createIntermediateGroups
|
||||
let createIntermediateGroups = project.options.createIntermediateGroups
|
||||
|
||||
var sourceFiles: [SourceFile] = []
|
||||
let sourceReference: String
|
||||
@@ -413,13 +413,13 @@ class SourceGenerator {
|
||||
let folderPath = Path(targetSource.path)
|
||||
let fileReference = getFileReference(
|
||||
path: folderPath,
|
||||
inPath: spec.basePath,
|
||||
inPath: project.basePath,
|
||||
name: targetSource.name ?? folderPath.lastComponent,
|
||||
sourceTree: .sourceRoot,
|
||||
lastKnownFileType: "folder"
|
||||
)
|
||||
|
||||
if !createIntermediateGroups || path.parent() == spec.basePath {
|
||||
if !createIntermediateGroups || path.parent() == project.basePath {
|
||||
rootGroups.insert(fileReference)
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ class SourceGenerator {
|
||||
|
||||
let sourceFile = generateSourceFile(targetSource: targetSource, path: path)
|
||||
|
||||
if parentPath == spec.basePath {
|
||||
if parentPath == project.basePath {
|
||||
sourcePath = path
|
||||
sourceReference = fileReference
|
||||
rootGroups.insert(fileReference)
|
||||
@@ -473,7 +473,7 @@ class SourceGenerator {
|
||||
private func createIntermediaGroups(for groupReference: String, at path: Path) {
|
||||
|
||||
let parentPath = path.parent()
|
||||
guard parentPath != spec.basePath && path.string.contains(spec.basePath.string) else {
|
||||
guard parentPath != project.basePath && path.string.contains(project.basePath.string) else {
|
||||
// we've reached the top or are out of the root directory
|
||||
return
|
||||
}
|
||||
|
||||
Vendored
BIN
Binary file not shown.
File renamed without changes.
@@ -6,14 +6,14 @@ import xcproj
|
||||
|
||||
let fixturePath = Path(#file).parent().parent() + "Fixtures"
|
||||
|
||||
func generate(specPath: Path, projectPath: Path) throws -> XcodeProj {
|
||||
let spec = try Project(path: specPath)
|
||||
let generator = ProjectGenerator(spec: spec)
|
||||
let project = try generator.generateProject()
|
||||
func generateXcodeProject(specPath: Path, projectPath: Path) throws -> XcodeProj {
|
||||
let project = try Project(path: specPath)
|
||||
let generator = ProjectGenerator(project: project)
|
||||
let xcodeProject = try generator.generateXcodeProject()
|
||||
let oldProject = try XcodeProj(path: projectPath)
|
||||
let pbxProjPath = projectPath + XcodeProj.pbxprojPath(projectPath)
|
||||
let oldProjectString: String = try pbxProjPath.read()
|
||||
try project.write(path: projectPath, override: true)
|
||||
try xcodeProject.write(path: projectPath, override: true)
|
||||
let newProjectString: String = try pbxProjPath.read()
|
||||
|
||||
let newProject = try XcodeProj(path: projectPath)
|
||||
@@ -32,21 +32,21 @@ func generate(specPath: Path, projectPath: Path) throws -> XcodeProj {
|
||||
func fixtureTests() {
|
||||
|
||||
describe("Test Project") {
|
||||
var project: XcodeProj?
|
||||
var xcodeProject: XcodeProj?
|
||||
|
||||
$0.it("generates") {
|
||||
project = try generate(specPath: fixturePath + "TestProject/spec.yml", projectPath: fixturePath + "TestProject/Project.xcodeproj")
|
||||
xcodeProject = try generateXcodeProject(specPath: fixturePath + "TestProject/project.yml", projectPath: fixturePath + "TestProject/Project.xcodeproj")
|
||||
}
|
||||
|
||||
$0.it("generates variant group") {
|
||||
guard let project = project else { return }
|
||||
guard let xcodeProject = xcodeProject else { return }
|
||||
|
||||
func getFileReferences(_ path: String) -> [ObjectReference<PBXFileReference>] {
|
||||
return project.pbxproj.objects.fileReferences.objectReferences.filter { $0.object.path == path }
|
||||
return xcodeProject.pbxproj.objects.fileReferences.objectReferences.filter { $0.object.path == path }
|
||||
}
|
||||
|
||||
func getVariableGroups(_ name: String?) -> [PBXVariantGroup] {
|
||||
return project.pbxproj.objects.variantGroups.referenceValues.filter { $0.name == name }
|
||||
return xcodeProject.pbxproj.objects.variantGroups.referenceValues.filter { $0.name == name }
|
||||
}
|
||||
|
||||
let resourceName = "LocalizedStoryboard.storyboard"
|
||||
@@ -69,9 +69,9 @@ func fixtureTests() {
|
||||
}
|
||||
|
||||
$0.it("generates scheme execution actions") {
|
||||
guard let project = project else { return }
|
||||
guard let xcodeProject = xcodeProject else { return }
|
||||
|
||||
let frameworkScheme = project.sharedData?.schemes.first { $0.name == "Framework" }
|
||||
let frameworkScheme = xcodeProject.sharedData?.schemes.first { $0.name == "Framework" }
|
||||
try expect(frameworkScheme?.buildAction?.preActions.first?.scriptText) == "echo Starting Framework Build"
|
||||
try expect(frameworkScheme?.buildAction?.preActions.first?.title) == "Run Script"
|
||||
try expect(frameworkScheme?.buildAction?.preActions.first?.environmentBuildable?.blueprintName) == "Framework_iOS"
|
||||
|
||||
@@ -7,15 +7,15 @@ import Yams
|
||||
|
||||
func projectGeneratorTests() {
|
||||
|
||||
func getProject(_ spec: Project) throws -> XcodeProj {
|
||||
let generator = ProjectGenerator(spec: spec)
|
||||
return try generator.generateProject()
|
||||
func getXcodeProject(_ project: Project) throws -> XcodeProj {
|
||||
let generator = ProjectGenerator(project: project)
|
||||
return try generator.generateXcodeProject()
|
||||
}
|
||||
|
||||
func getPbxProj(_ spec: Project) throws -> PBXProj {
|
||||
let project = try getProject(spec).pbxproj
|
||||
try project.validate()
|
||||
return project
|
||||
func getPbxProj(_ project: Project) throws -> PBXProj {
|
||||
let xcodeProject = try getXcodeProject(project).pbxproj
|
||||
try xcodeProject.validate()
|
||||
return xcodeProject
|
||||
}
|
||||
|
||||
describe("Project Generator") {
|
||||
@@ -49,13 +49,13 @@ func projectGeneratorTests() {
|
||||
|
||||
$0.it("generates bundle id") {
|
||||
let options = SpecOptions(bundleIdPrefix: "com.test")
|
||||
let spec = Project(basePath: "", name: "test", targets: [framework], options: options)
|
||||
let project = try getProject(spec)
|
||||
guard let target = project.pbxproj.objects.nativeTargets.first?.value,
|
||||
let project = Project(basePath: "", name: "test", targets: [framework], options: options)
|
||||
let pbxProj = try getPbxProj(project)
|
||||
guard let target = pbxProj.objects.nativeTargets.first?.value,
|
||||
let buildConfigList = target.buildConfigurationList,
|
||||
let buildConfigs = project.pbxproj.objects.configurationLists.getReference(buildConfigList),
|
||||
let buildConfigs = pbxProj.objects.configurationLists.getReference(buildConfigList),
|
||||
let buildConfigReference = buildConfigs.buildConfigurations.first,
|
||||
let buildConfig = project.pbxproj.objects.buildConfigurations.getReference(buildConfigReference) else {
|
||||
let buildConfig = pbxProj.objects.buildConfigurations.getReference(buildConfigReference) else {
|
||||
throw failure("Build Config not found")
|
||||
}
|
||||
try expect(buildConfig.buildSettings["PRODUCT_BUNDLE_IDENTIFIER"] as? String) == "com.test.MyFramework"
|
||||
@@ -63,17 +63,17 @@ func projectGeneratorTests() {
|
||||
|
||||
$0.it("clears setting presets") {
|
||||
let options = SpecOptions(settingPresets: .none)
|
||||
let spec = Project(basePath: "", name: "test", targets: [framework], options: options)
|
||||
let project = try getProject(spec)
|
||||
let allSettings = project.pbxproj.objects.buildConfigurations.referenceValues.reduce([:]) { $0.merged($1.buildSettings) }.keys.sorted()
|
||||
let project = Project(basePath: "", name: "test", targets: [framework], options: options)
|
||||
let pbxProj = try getPbxProj(project)
|
||||
let allSettings = pbxProj.objects.buildConfigurations.referenceValues.reduce([:]) { $0.merged($1.buildSettings) }.keys.sorted()
|
||||
try expect(allSettings) == ["SETTING_2"]
|
||||
}
|
||||
|
||||
$0.it("generates development language") {
|
||||
let options = SpecOptions(developmentLanguage: "de")
|
||||
let spec = Project(basePath: "", name: "test", options: options)
|
||||
let project = try getProject(spec)
|
||||
guard let pbxProject = project.pbxproj.objects.projects.first?.value else {
|
||||
let project = Project(basePath: "", name: "test", options: options)
|
||||
let pbxProj = try getPbxProj(project)
|
||||
guard let pbxProject = pbxProj.objects.projects.first?.value else {
|
||||
throw failure("Could't find PBXProject")
|
||||
}
|
||||
try expect(pbxProject.developmentRegion) == "de"
|
||||
@@ -99,8 +99,8 @@ func projectGeneratorTests() {
|
||||
|
||||
$0.it("uses the default configuration name") {
|
||||
let options = SpecOptions(defaultConfig: "Bconfig")
|
||||
let spec = Project(basePath: "", name: "test", configs: [Config(name: "Aconfig"), Config(name: "Bconfig")], targets: [framework], options: options)
|
||||
let pbxProject = try getPbxProj(spec)
|
||||
let project = Project(basePath: "", name: "test", configs: [Config(name: "Aconfig"), Config(name: "Bconfig")], targets: [framework], options: options)
|
||||
let pbxProject = try getPbxProj(project)
|
||||
|
||||
guard let projectConfigListReference = pbxProject.objects.projects.values.first?.buildConfigurationList,
|
||||
let defaultConfigurationName = pbxProject.objects.configurationLists[projectConfigListReference]?.defaultConfigurationName
|
||||
@@ -115,47 +115,47 @@ func projectGeneratorTests() {
|
||||
$0.describe("Config") {
|
||||
|
||||
$0.it("generates config defaults") {
|
||||
let spec = Project(basePath: "", name: "test")
|
||||
let project = try getProject(spec)
|
||||
let configs = project.pbxproj.objects.buildConfigurations.referenceValues
|
||||
let project = Project(basePath: "", name: "test")
|
||||
let pbxProj = try getPbxProj(project)
|
||||
let configs = pbxProj.objects.buildConfigurations.referenceValues
|
||||
try expect(configs.count) == 2
|
||||
try expect(configs).contains(name: "Debug")
|
||||
try expect(configs).contains(name: "Release")
|
||||
}
|
||||
|
||||
$0.it("generates configs") {
|
||||
let spec = Project(
|
||||
let project = Project(
|
||||
basePath: "",
|
||||
name: "test",
|
||||
configs: [Config(name: "config1"), Config(name: "config2")]
|
||||
)
|
||||
let project = try getProject(spec)
|
||||
let configs = project.pbxproj.objects.buildConfigurations.referenceValues
|
||||
let pbxProj = try getPbxProj(project)
|
||||
let configs = pbxProj.objects.buildConfigurations.referenceValues
|
||||
try expect(configs.count) == 2
|
||||
try expect(configs).contains(name: "config1")
|
||||
try expect(configs).contains(name: "config2")
|
||||
}
|
||||
|
||||
$0.it("clears config settings when missing type") {
|
||||
let spec = Project(
|
||||
let project = Project(
|
||||
basePath: "",
|
||||
name: "test",
|
||||
configs: [Config(name: "config")]
|
||||
)
|
||||
let project = try getProject(spec)
|
||||
guard let config = project.pbxproj.objects.buildConfigurations.first?.value else {
|
||||
let pbxProj = try getPbxProj(project)
|
||||
guard let config = pbxProj.objects.buildConfigurations.first?.value else {
|
||||
throw failure("configuration not found")
|
||||
}
|
||||
try expect(config.buildSettings.isEmpty).to.beTrue()
|
||||
}
|
||||
|
||||
$0.it("merges settings") {
|
||||
let spec = try Project(path: fixturePath + "settings_test.yml")
|
||||
guard let config = spec.getConfig("config1") else { throw failure("Couldn't find config1") }
|
||||
let debugProjectSettings = spec.getProjectBuildSettings(config: config)
|
||||
let project = try Project(path: fixturePath + "settings_test.yml")
|
||||
guard let config = project.getConfig("config1") else { throw failure("Couldn't find config1") }
|
||||
let debugProjectSettings = project.getProjectBuildSettings(config: config)
|
||||
|
||||
guard let target = spec.getTarget("Target") else { throw failure("Couldn't find Target") }
|
||||
let targetDebugSettings = spec.getTargetBuildSettings(target: target, config: config)
|
||||
guard let target = project.getTarget("Target") else { throw failure("Couldn't find Target") }
|
||||
let targetDebugSettings = project.getTargetBuildSettings(target: target, config: config)
|
||||
|
||||
var buildSettings = BuildSettings()
|
||||
buildSettings += SettingsPresetFile.base.getBuildSettings()
|
||||
@@ -178,7 +178,7 @@ func projectGeneratorTests() {
|
||||
}
|
||||
|
||||
$0.it("applies partial config settings") {
|
||||
let spec = Project(
|
||||
let project = Project(
|
||||
basePath: "",
|
||||
name: "test",
|
||||
configs: [
|
||||
@@ -188,7 +188,7 @@ func projectGeneratorTests() {
|
||||
settings: Settings(configSettings: ["staging": ["SETTING1": "VALUE1"], "debug": ["SETTING2": "VALUE2"]])
|
||||
)
|
||||
|
||||
var buildSettings = spec.getProjectBuildSettings(config: spec.configs.first!)
|
||||
var buildSettings = project.getProjectBuildSettings(config: project.configs.first!)
|
||||
try expect(buildSettings["SETTING1"] as? String) == "VALUE1"
|
||||
try expect(buildSettings["SETTING2"] as? String) == "VALUE2"
|
||||
}
|
||||
@@ -196,10 +196,10 @@ func projectGeneratorTests() {
|
||||
|
||||
$0.describe("Targets") {
|
||||
|
||||
let spec = Project(basePath: "", name: "test", targets: targets)
|
||||
let project = Project(basePath: "", name: "test", targets: targets)
|
||||
|
||||
$0.it("generates targets") {
|
||||
let pbxProject = try getPbxProj(spec)
|
||||
let pbxProject = try getPbxProj(project)
|
||||
let nativeTargets = pbxProject.objects.nativeTargets.referenceValues
|
||||
try expect(nativeTargets.count) == 3
|
||||
try expect(nativeTargets.contains { $0.name == application.name }).beTrue()
|
||||
@@ -214,8 +214,8 @@ func projectGeneratorTests() {
|
||||
|
||||
var testTargetWithAttributes = uiTest
|
||||
testTargetWithAttributes.settings.buildSettings["CODE_SIGN_STYLE"] = "Manual"
|
||||
var spec = Project(basePath: "", name: "test", targets: [appTargetWithAttributes, framework, testTargetWithAttributes])
|
||||
let pbxProject = try getPbxProj(spec)
|
||||
var project = Project(basePath: "", name: "test", targets: [appTargetWithAttributes, framework, testTargetWithAttributes])
|
||||
let pbxProject = try getPbxProj(project)
|
||||
|
||||
guard let targetAttributes = pbxProject.objects.projects.referenceValues.first?.attributes["TargetAttributes"] as? [String: [String: Any]] else {
|
||||
throw failure("Couldn't find Project TargetAttributes")
|
||||
@@ -237,9 +237,9 @@ func projectGeneratorTests() {
|
||||
|
||||
$0.it("generates platform version") {
|
||||
let target = Target(name: "Target", type: .application, platform: .watchOS, deploymentTarget: "2.0")
|
||||
let spec = Project(basePath: "", name: "", targets: [target], options: .init(deploymentTarget: DeploymentTarget(iOS: "10.0", watchOS: "3.0")))
|
||||
let project = Project(basePath: "", name: "", targets: [target], options: .init(deploymentTarget: DeploymentTarget(iOS: "10.0", watchOS: "3.0")))
|
||||
|
||||
let pbxProject = try getPbxProj(spec)
|
||||
let pbxProject = try getPbxProj(project)
|
||||
|
||||
guard let projectConfigListReference = pbxProject.objects.projects.values.first?.buildConfigurationList,
|
||||
let projectConfigReference = pbxProject.objects.configurationLists[projectConfigListReference]?.buildConfigurations.first,
|
||||
@@ -265,7 +265,7 @@ func projectGeneratorTests() {
|
||||
}
|
||||
|
||||
$0.it("generates dependencies") {
|
||||
let pbxProject = try getPbxProj(spec)
|
||||
let pbxProject = try getPbxProj(project)
|
||||
|
||||
let nativeTargets = pbxProject.objects.nativeTargets.objectReferences
|
||||
let dependencies = pbxProject.objects.targetDependencies.objectReferences
|
||||
@@ -275,7 +275,7 @@ func projectGeneratorTests() {
|
||||
}
|
||||
|
||||
$0.it("generates run scripts") {
|
||||
var scriptSpec = spec
|
||||
var scriptSpec = project
|
||||
scriptSpec.targets[0].prebuildScripts = [BuildScript(script: .script("script1"))]
|
||||
scriptSpec.targets[0].postbuildScripts = [BuildScript(script: .script("script2"))]
|
||||
let pbxProject = try getPbxProj(scriptSpec)
|
||||
@@ -310,13 +310,13 @@ func projectGeneratorTests() {
|
||||
platform: .iOS,
|
||||
dependencies: [Dependency(type: .target, reference: "target1")]
|
||||
)
|
||||
let spec = Project(
|
||||
let project = Project(
|
||||
basePath: "",
|
||||
name: "test",
|
||||
targets: [target1, target2]
|
||||
)
|
||||
|
||||
_ = try getPbxProj(spec)
|
||||
_ = try getPbxProj(project)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,18 +329,18 @@ func projectGeneratorTests() {
|
||||
name: "MyScheme",
|
||||
build: Scheme.Build(targets: [buildTarget], preActions: [preAction])
|
||||
)
|
||||
let spec = Project(
|
||||
let project = Project(
|
||||
basePath: "",
|
||||
name: "test",
|
||||
targets: [application, framework],
|
||||
schemes: [scheme]
|
||||
)
|
||||
let project = try getProject(spec)
|
||||
guard let target = project.pbxproj.objects.nativeTargets.objectReferences
|
||||
let xcodeProject = try getXcodeProject(project)
|
||||
guard let target = xcodeProject.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 {
|
||||
guard let xcscheme = xcodeProject.sharedData?.schemes.first else {
|
||||
throw failure("Scheme not found")
|
||||
}
|
||||
try expect(scheme.name) == "MyScheme"
|
||||
@@ -388,20 +388,20 @@ func projectGeneratorTests() {
|
||||
test: Scheme.Test(config: "Debug"),
|
||||
profile: Scheme.Profile(config: "Debug")
|
||||
)
|
||||
let spec = Project(
|
||||
let project = Project(
|
||||
basePath: "",
|
||||
name: "test",
|
||||
targets: [application, framework],
|
||||
schemes: [scheme]
|
||||
)
|
||||
let project = try getProject(spec)
|
||||
let xcodeProject = try getXcodeProject(project)
|
||||
|
||||
guard let target = project.pbxproj.objects.nativeTargets.objectReferences
|
||||
guard let target = xcodeProject.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 {
|
||||
guard let xcscheme = xcodeProject.sharedData?.schemes.first else {
|
||||
throw failure("Scheme not found")
|
||||
}
|
||||
|
||||
@@ -421,16 +421,16 @@ func projectGeneratorTests() {
|
||||
Config(name: "Production Release", type: .release),
|
||||
]
|
||||
|
||||
let spec = Project(basePath: "", name: "test", configs: configs, targets: [target, framework])
|
||||
let project = try getProject(spec)
|
||||
let project = Project(basePath: "", name: "test", configs: configs, targets: [target, framework])
|
||||
let xcodeProject = try getXcodeProject(project)
|
||||
|
||||
try expect(project.sharedData?.schemes.count) == 2
|
||||
try expect(xcodeProject.sharedData?.schemes.count) == 2
|
||||
|
||||
guard let nativeTarget = project.pbxproj.objects.nativeTargets.objectReferences
|
||||
guard let nativeTarget = xcodeProject.pbxproj.objects.nativeTargets.objectReferences
|
||||
.first(where: { $0.object.name == application.name }) else {
|
||||
throw failure("Target not found")
|
||||
}
|
||||
guard let xcscheme = project.sharedData?.schemes
|
||||
guard let xcscheme = xcodeProject.sharedData?.schemes
|
||||
.first(where: { $0.name == "\(target.name) Test" }) else {
|
||||
throw failure("Scheme not found")
|
||||
}
|
||||
@@ -451,12 +451,12 @@ func projectGeneratorTests() {
|
||||
var target = application
|
||||
target.scheme = TargetScheme(environmentVariables: variables)
|
||||
|
||||
let spec = Project(basePath: "", name: "test", targets: [target, framework])
|
||||
let project = try getProject(spec)
|
||||
let project = Project(basePath: "", name: "test", targets: [target, framework])
|
||||
let xcodeProject = try getXcodeProject(project)
|
||||
|
||||
try expect(project.sharedData?.schemes.count) == 1
|
||||
try expect(xcodeProject.sharedData?.schemes.count) == 1
|
||||
|
||||
guard let xcscheme = project.sharedData?.schemes.first else {
|
||||
guard let xcscheme = xcodeProject.sharedData?.schemes.first else {
|
||||
throw failure("Scheme not found")
|
||||
}
|
||||
|
||||
@@ -472,12 +472,12 @@ func projectGeneratorTests() {
|
||||
postActions: [.init(name: "Run2", script: "post", settingsTarget: "MyApp")]
|
||||
)
|
||||
|
||||
let spec = ProjectSpec(basePath: "", name: "test", targets: [target, framework])
|
||||
let project = try getProject(spec)
|
||||
let project = Project(basePath: "", name: "test", targets: [target, framework])
|
||||
let xcodeProject = try getXcodeProject(project)
|
||||
|
||||
try expect(project.sharedData?.schemes.count) == 1
|
||||
try expect(xcodeProject.sharedData?.schemes.count) == 1
|
||||
|
||||
guard let xcscheme = project.sharedData?.schemes.first else {
|
||||
guard let xcscheme = xcodeProject.sharedData?.schemes.first else {
|
||||
throw failure("Scheme not found")
|
||||
}
|
||||
|
||||
@@ -548,11 +548,11 @@ func projectGeneratorTests() {
|
||||
try createDirectories(directories)
|
||||
|
||||
let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["Sources"])
|
||||
let spec = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
|
||||
let project = try getPbxProj(spec)
|
||||
try project.expectFile(paths: ["Sources", "A", "a.swift"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["Sources", "A", "B", "b.swift"], buildPhase: .sources)
|
||||
let pbxProj = try getPbxProj(project)
|
||||
try pbxProj.expectFile(paths: ["Sources", "A", "a.swift"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["Sources", "A", "B", "b.swift"], buildPhase: .sources)
|
||||
}
|
||||
|
||||
$0.it("generates core data models") {
|
||||
@@ -564,13 +564,13 @@ func projectGeneratorTests() {
|
||||
try createDirectories(directories)
|
||||
|
||||
let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["Sources"])
|
||||
let spec = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
|
||||
let project = try getPbxProj(spec)
|
||||
guard let fileReference = project.objects.fileReferences.first(where: { $0.value.nameOrPath == "model.xcdatamodel" }) else {
|
||||
let pbxProj = try getPbxProj(project)
|
||||
guard let fileReference = pbxProj.objects.fileReferences.first(where: { $0.value.nameOrPath == "model.xcdatamodel" }) else {
|
||||
throw failure("Couldn't find model file reference")
|
||||
}
|
||||
guard let versionGroup = project.objects.versionGroups.values.first else {
|
||||
guard let versionGroup = pbxProj.objects.versionGroups.values.first else {
|
||||
throw failure("Couldn't find version group")
|
||||
}
|
||||
try expect(versionGroup.currentVersion) == fileReference.key
|
||||
@@ -592,17 +592,17 @@ func projectGeneratorTests() {
|
||||
try createDirectories(directories)
|
||||
|
||||
let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["Sources"])
|
||||
let spec = Project(
|
||||
let project = Project(
|
||||
basePath: directoryPath,
|
||||
name: "Test",
|
||||
targets: [target],
|
||||
fileGroups: ["Sources"]
|
||||
)
|
||||
|
||||
let project = try getPbxProj(spec)
|
||||
try project.expectFile(paths: ["Sources", "a.swift"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["Sources", "a", "a.swift"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["Sources", "a", "a", "a.swift"], buildPhase: .sources)
|
||||
let pbxProj = try getPbxProj(project)
|
||||
try pbxProj.expectFile(paths: ["Sources", "a.swift"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["Sources", "a", "a.swift"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["Sources", "a", "a", "a.swift"], buildPhase: .sources)
|
||||
}
|
||||
|
||||
$0.it("renames sources") {
|
||||
@@ -618,11 +618,11 @@ func projectGeneratorTests() {
|
||||
TargetSource(path: "Sources", name: "NewSource"),
|
||||
TargetSource(path: "OtherSource/b.swift", name: "c.swift"),
|
||||
])
|
||||
let spec = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
|
||||
let project = try getPbxProj(spec)
|
||||
try project.expectFile(paths: ["Sources", "a.swift"], names: ["NewSource", "a.swift"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["OtherSource", "b.swift"], names: ["OtherSource", "c.swift"], buildPhase: .sources)
|
||||
let pbxProj = try getPbxProj(project)
|
||||
try pbxProj.expectFile(paths: ["Sources", "a.swift"], names: ["NewSource", "a.swift"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["OtherSource", "b.swift"], names: ["OtherSource", "c.swift"], buildPhase: .sources)
|
||||
}
|
||||
|
||||
$0.it("excludes sources") {
|
||||
@@ -681,28 +681,28 @@ func projectGeneratorTests() {
|
||||
]
|
||||
|
||||
let target = Target(name: "Test", type: .application, platform: .iOS, sources: [TargetSource(path: "Sources", excludes: excludes)])
|
||||
let spec = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
|
||||
let project = try getPbxProj(spec)
|
||||
try project.expectFile(paths: ["Sources", "A", "a.swift"])
|
||||
try project.expectFile(paths: ["Sources", "D", "d.h"])
|
||||
try project.expectFile(paths: ["Sources", "D", "d.m"])
|
||||
try project.expectFile(paths: ["Sources", "E", "e.jpg"])
|
||||
try project.expectFile(paths: ["Sources", "E", "e.m"])
|
||||
try project.expectFile(paths: ["Sources", "E", "e.h"])
|
||||
try project.expectFile(paths: ["Sources", "types", "a.swift"])
|
||||
try project.expectFile(paths: ["Sources", "numbers", "file1.a"])
|
||||
try project.expectFile(paths: ["Sources", "numbers", "file4.a"])
|
||||
try project.expectFileMissing(paths: ["Sources", "B", "b.swift"])
|
||||
try project.expectFileMissing(paths: ["Sources", "E", "F", "f.swift"])
|
||||
try project.expectFileMissing(paths: ["Sources", "G", "H", "h.swift"])
|
||||
try project.expectFileMissing(paths: ["Sources", "types", "a.h"])
|
||||
try project.expectFileMissing(paths: ["Sources", "types", "a.x"])
|
||||
try project.expectFileMissing(paths: ["Sources", "numbers", "file2.a"])
|
||||
try project.expectFileMissing(paths: ["Sources", "numbers", "file3.a"])
|
||||
try project.expectFileMissing(paths: ["Sources", "partial", "file_part"])
|
||||
try project.expectFileMissing(paths: ["Sources", "a.ignored"])
|
||||
try project.expectFileMissing(paths: ["Sources", "ignore.file"])
|
||||
let pbxProj = try getPbxProj(project)
|
||||
try pbxProj.expectFile(paths: ["Sources", "A", "a.swift"])
|
||||
try pbxProj.expectFile(paths: ["Sources", "D", "d.h"])
|
||||
try pbxProj.expectFile(paths: ["Sources", "D", "d.m"])
|
||||
try pbxProj.expectFile(paths: ["Sources", "E", "e.jpg"])
|
||||
try pbxProj.expectFile(paths: ["Sources", "E", "e.m"])
|
||||
try pbxProj.expectFile(paths: ["Sources", "E", "e.h"])
|
||||
try pbxProj.expectFile(paths: ["Sources", "types", "a.swift"])
|
||||
try pbxProj.expectFile(paths: ["Sources", "numbers", "file1.a"])
|
||||
try pbxProj.expectFile(paths: ["Sources", "numbers", "file4.a"])
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "B", "b.swift"])
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "E", "F", "f.swift"])
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "G", "H", "h.swift"])
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "types", "a.h"])
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "types", "a.x"])
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "numbers", "file2.a"])
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "numbers", "file3.a"])
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "partial", "file_part"])
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "a.ignored"])
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "ignore.file"])
|
||||
}
|
||||
|
||||
$0.it("generates file sources") {
|
||||
@@ -723,13 +723,13 @@ func projectGeneratorTests() {
|
||||
"Sources/A/Assets.xcassets",
|
||||
"Sources/A/B/c.jpg",
|
||||
])
|
||||
let spec = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
|
||||
let project = try getPbxProj(spec)
|
||||
try project.expectFile(paths: ["Sources/A", "a.swift"], names: ["A", "a.swift"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["Sources/A/B", "b.swift"], names: ["B", "b.swift"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["Sources/A/B", "c.jpg"], names: ["B", "c.jpg"], buildPhase: .resources)
|
||||
try project.expectFile(paths: ["Sources/A", "Assets.xcassets"], names: ["A", "Assets.xcassets"], buildPhase: .resources)
|
||||
let pbxProj = try getPbxProj(project)
|
||||
try pbxProj.expectFile(paths: ["Sources/A", "a.swift"], names: ["A", "a.swift"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["Sources/A/B", "b.swift"], names: ["B", "b.swift"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["Sources/A/B", "c.jpg"], names: ["B", "c.jpg"], buildPhase: .resources)
|
||||
try pbxProj.expectFile(paths: ["Sources/A", "Assets.xcassets"], names: ["A", "Assets.xcassets"], buildPhase: .resources)
|
||||
}
|
||||
|
||||
$0.it("generates shared sources") {
|
||||
@@ -745,9 +745,9 @@ func projectGeneratorTests() {
|
||||
|
||||
let target1 = Target(name: "Test1", type: .framework, platform: .iOS, sources: ["Sources"])
|
||||
let target2 = Target(name: "Test2", type: .framework, platform: .tvOS, sources: ["Sources"])
|
||||
let spec = Project(basePath: directoryPath, name: "Test", targets: [target1, target2])
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target1, target2])
|
||||
|
||||
_ = try getPbxProj(spec)
|
||||
_ = try getPbxProj(project)
|
||||
// TODO: check there are build files for both targets
|
||||
}
|
||||
|
||||
@@ -772,12 +772,12 @@ func projectGeneratorTests() {
|
||||
"../OtherDirectory/C/D/e.swift",
|
||||
])
|
||||
let options = SpecOptions(createIntermediateGroups: true)
|
||||
let spec = Project(basePath: directoryPath, name: "Test", targets: [target], options: options)
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target], options: options)
|
||||
|
||||
let project = try getPbxProj(spec)
|
||||
try project.expectFile(paths: ["Sources", "A", "b.swift"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["Sources", "F", "G", "h.swift"], buildPhase: .sources)
|
||||
try project.expectFile(paths: [(outOfRootPath + "C/D").string, "e.swift"], names: ["D", "e.swift"], buildPhase: .sources)
|
||||
let pbxProj = try getPbxProj(project)
|
||||
try pbxProj.expectFile(paths: ["Sources", "A", "b.swift"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["Sources", "F", "G", "h.swift"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: [(outOfRootPath + "C/D").string, "e.swift"], names: ["D", "e.swift"], buildPhase: .sources)
|
||||
}
|
||||
|
||||
$0.it("generates folder references") {
|
||||
@@ -792,11 +792,11 @@ func projectGeneratorTests() {
|
||||
let target = Target(name: "Test", type: .application, platform: .iOS, sources: [
|
||||
TargetSource(path: "Sources/A", type: .folder),
|
||||
])
|
||||
let spec = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
|
||||
let project = try getPbxProj(spec)
|
||||
try project.expectFile(paths: ["Sources/A"], names: ["A"], buildPhase: .resources)
|
||||
try project.expectFileMissing(paths: ["Sources", "A", "a.swift"])
|
||||
let pbxProj = try getPbxProj(project)
|
||||
try pbxProj.expectFile(paths: ["Sources/A"], names: ["A"], buildPhase: .resources)
|
||||
try pbxProj.expectFileMissing(paths: ["Sources", "A", "a.swift"])
|
||||
}
|
||||
|
||||
$0.it("adds files to correct build phase") {
|
||||
@@ -842,44 +842,44 @@ func projectGeneratorTests() {
|
||||
TargetSource(path: "B", buildPhase: .none),
|
||||
TargetSource(path: "C", buildPhase: nil),
|
||||
])
|
||||
let spec = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
|
||||
let project = try getPbxProj(spec)
|
||||
try project.expectFile(paths: ["A", "file.swift"], buildPhase: .resources)
|
||||
try project.expectFile(paths: ["A", "file.xcassets"], buildPhase: .resources)
|
||||
try project.expectFile(paths: ["A", "file.h"], buildPhase: .resources)
|
||||
try project.expectFile(paths: ["A", "Info.plist"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["A", "file.xcconfig"], buildPhase: .resources)
|
||||
let pbxProj = try getPbxProj(project)
|
||||
try pbxProj.expectFile(paths: ["A", "file.swift"], buildPhase: .resources)
|
||||
try pbxProj.expectFile(paths: ["A", "file.xcassets"], buildPhase: .resources)
|
||||
try pbxProj.expectFile(paths: ["A", "file.h"], buildPhase: .resources)
|
||||
try pbxProj.expectFile(paths: ["A", "Info.plist"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["A", "file.xcconfig"], buildPhase: .resources)
|
||||
|
||||
try project.expectFile(paths: ["B", "file.swift"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["B", "file.xcassets"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["B", "file.h"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["B", "Info.plist"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["B", "file.xcconfig"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["B", "file.swift"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["B", "file.xcassets"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["B", "file.h"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["B", "Info.plist"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["B", "file.xcconfig"], buildPhase: .none)
|
||||
|
||||
try project.expectFile(paths: ["C", "file.swift"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["C", "file.m"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["C", "file.mm"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["C", "file.cpp"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["C", "file.c"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["C", "file.S"], buildPhase: .sources)
|
||||
try project.expectFile(paths: ["C", "file.h"], buildPhase: .headers)
|
||||
try project.expectFile(paths: ["C", "file.hh"], buildPhase: .headers)
|
||||
try project.expectFile(paths: ["C", "file.hpp"], buildPhase: .headers)
|
||||
try project.expectFile(paths: ["C", "file.ipp"], buildPhase: .headers)
|
||||
try project.expectFile(paths: ["C", "file.tpp"], buildPhase: .headers)
|
||||
try project.expectFile(paths: ["C", "file.hxx"], buildPhase: .headers)
|
||||
try project.expectFile(paths: ["C", "file.def"], buildPhase: .headers)
|
||||
try project.expectFile(paths: ["C", "file.xcconfig"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["C", "file.entitlements"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["C", "file.gpx"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["C", "file.apns"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["C", "file.xcconfig"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["C", "file.xcconfig"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["C", "file.xcconfig"], buildPhase: .none)
|
||||
try project.expectFile(paths: ["C", "file.xcassets"], buildPhase: .resources)
|
||||
try project.expectFile(paths: ["C", "file.123"], buildPhase: .resources)
|
||||
try project.expectFile(paths: ["C", "Info.plist"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["C", "file.swift"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["C", "file.m"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["C", "file.mm"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["C", "file.cpp"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["C", "file.c"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["C", "file.S"], buildPhase: .sources)
|
||||
try pbxProj.expectFile(paths: ["C", "file.h"], buildPhase: .headers)
|
||||
try pbxProj.expectFile(paths: ["C", "file.hh"], buildPhase: .headers)
|
||||
try pbxProj.expectFile(paths: ["C", "file.hpp"], buildPhase: .headers)
|
||||
try pbxProj.expectFile(paths: ["C", "file.ipp"], buildPhase: .headers)
|
||||
try pbxProj.expectFile(paths: ["C", "file.tpp"], buildPhase: .headers)
|
||||
try pbxProj.expectFile(paths: ["C", "file.hxx"], buildPhase: .headers)
|
||||
try pbxProj.expectFile(paths: ["C", "file.def"], buildPhase: .headers)
|
||||
try pbxProj.expectFile(paths: ["C", "file.xcconfig"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["C", "file.entitlements"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["C", "file.gpx"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["C", "file.apns"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["C", "file.xcconfig"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["C", "file.xcconfig"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["C", "file.xcconfig"], buildPhase: .none)
|
||||
try pbxProj.expectFile(paths: ["C", "file.xcassets"], buildPhase: .resources)
|
||||
try pbxProj.expectFile(paths: ["C", "file.123"], buildPhase: .resources)
|
||||
try pbxProj.expectFile(paths: ["C", "Info.plist"], buildPhase: .none)
|
||||
}
|
||||
|
||||
$0.it("duplicate TargetSource is included once in sources build phase") {
|
||||
@@ -894,12 +894,12 @@ func projectGeneratorTests() {
|
||||
"Sources/A/a.swift",
|
||||
"Sources/A/a.swift",
|
||||
])
|
||||
let spec = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
let project = Project(basePath: directoryPath, name: "Test", targets: [target])
|
||||
|
||||
let project = try getPbxProj(spec)
|
||||
try project.expectFile(paths: ["Sources/A", "a.swift"], names: ["A", "a.swift"], buildPhase: .sources)
|
||||
let pbxProj = try getPbxProj(project)
|
||||
try pbxProj.expectFile(paths: ["Sources/A", "a.swift"], names: ["A", "a.swift"], buildPhase: .sources)
|
||||
|
||||
let sourcesBuildPhase = project.objects.buildPhases
|
||||
let sourcesBuildPhase = pbxProj.objects.buildPhases
|
||||
.first(where: { $0.1.buildPhase == BuildPhase.sources })!
|
||||
.value
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@ func projectSpecTests() {
|
||||
settings: Settings(buildSettings: ["SETTING_2": "VALUE"])
|
||||
)
|
||||
|
||||
func expectValidationError(_ spec: Project, _ expectedError: SpecValidationError.ValidationError) throws {
|
||||
func expectValidationError(_ project: Project, _ expectedError: SpecValidationError.ValidationError) throws {
|
||||
do {
|
||||
try spec.validate()
|
||||
try project.validate()
|
||||
} catch let error as SpecValidationError {
|
||||
if !error.errors
|
||||
.contains(where: { $0.description == expectedError.description }) {
|
||||
@@ -80,41 +80,41 @@ func projectSpecTests() {
|
||||
|
||||
$0.describe("Validation") {
|
||||
|
||||
let baseSpec = Project(basePath: "", name: "", configs: [Config(name: "invalid")])
|
||||
let baseProject = Project(basePath: "", name: "", configs: [Config(name: "invalid")])
|
||||
let invalidSettings = Settings(
|
||||
configSettings: ["invalidConfig": [:]],
|
||||
groups: ["invalidSettingGroup"]
|
||||
)
|
||||
$0.it("fails with invalid project") {
|
||||
var spec = baseSpec
|
||||
spec.settings = invalidSettings
|
||||
spec.configFiles = ["invalidConfig": "invalidConfigFile"]
|
||||
spec.fileGroups = ["invalidFileGroup"]
|
||||
spec.settingGroups = ["settingGroup1": Settings(
|
||||
var project = baseProject
|
||||
project.settings = invalidSettings
|
||||
project.configFiles = ["invalidConfig": "invalidConfigFile"]
|
||||
project.fileGroups = ["invalidFileGroup"]
|
||||
project.settingGroups = ["settingGroup1": Settings(
|
||||
configSettings: ["invalidSettingGroupConfig": [:]],
|
||||
groups: ["invalidSettingGroupSettingGroup"]
|
||||
)]
|
||||
|
||||
try expectValidationError(spec, .invalidConfigFileConfig("invalidConfig"))
|
||||
try expectValidationError(spec, .invalidBuildSettingConfig("invalidConfig"))
|
||||
try expectValidationError(spec, .invalidConfigFile(configFile: "invalidConfigFile", config: "invalidConfig"))
|
||||
try expectValidationError(spec, .invalidSettingsGroup("invalidSettingGroup"))
|
||||
try expectValidationError(spec, .invalidFileGroup("invalidFileGroup"))
|
||||
try expectValidationError(spec, .invalidSettingsGroup("invalidSettingGroupSettingGroup"))
|
||||
try expectValidationError(spec, .invalidBuildSettingConfig("invalidSettingGroupConfig"))
|
||||
try expectValidationError(project, .invalidConfigFileConfig("invalidConfig"))
|
||||
try expectValidationError(project, .invalidBuildSettingConfig("invalidConfig"))
|
||||
try expectValidationError(project, .invalidConfigFile(configFile: "invalidConfigFile", config: "invalidConfig"))
|
||||
try expectValidationError(project, .invalidSettingsGroup("invalidSettingGroup"))
|
||||
try expectValidationError(project, .invalidFileGroup("invalidFileGroup"))
|
||||
try expectValidationError(project, .invalidSettingsGroup("invalidSettingGroupSettingGroup"))
|
||||
try expectValidationError(project, .invalidBuildSettingConfig("invalidSettingGroupConfig"))
|
||||
}
|
||||
|
||||
$0.it("allows non-existent configurations") {
|
||||
var spec = baseSpec
|
||||
spec.options = SpecOptions(disabledValidations: [.missingConfigs])
|
||||
var project = baseProject
|
||||
project.options = SpecOptions(disabledValidations: [.missingConfigs])
|
||||
let configPath = fixturePath + "test.xcconfig"
|
||||
spec.configFiles = ["missingConfiguration": configPath.string]
|
||||
try spec.validate()
|
||||
project.configFiles = ["missingConfiguration": configPath.string]
|
||||
try project.validate()
|
||||
}
|
||||
|
||||
$0.it("fails with invalid target") {
|
||||
var spec = baseSpec
|
||||
spec.targets = [Target(
|
||||
var project = baseProject
|
||||
project.targets = [Target(
|
||||
name: "target1",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
@@ -127,51 +127,51 @@ func projectSpecTests() {
|
||||
scheme: TargetScheme(testTargets: ["invalidTarget"])
|
||||
)]
|
||||
|
||||
try expectValidationError(spec, .invalidTargetDependency(target: "target1", dependency: "invalidDependency"))
|
||||
try expectValidationError(spec, .invalidTargetConfigFile(target: "target1", configFile: "invalidConfigFile", config: "invalidConfig"))
|
||||
try expectValidationError(spec, .invalidTargetSchemeTest(target: "target1", testTarget: "invalidTarget"))
|
||||
try expectValidationError(spec, .invalidTargetSource(target: "target1", source: "invalidSource"))
|
||||
try expectValidationError(spec, .invalidBuildSettingConfig("invalidConfig"))
|
||||
try expectValidationError(spec, .invalidSettingsGroup("invalidSettingGroup"))
|
||||
try expectValidationError(spec, .invalidBuildScriptPath(target: "target1", name: "prebuildScript1", path: "invalidPrebuildScript"))
|
||||
try expectValidationError(spec, .invalidBuildScriptPath(target: "target1", name: nil, path: "invalidPostbuildScript"))
|
||||
try expectValidationError(project, .invalidTargetDependency(target: "target1", dependency: "invalidDependency"))
|
||||
try expectValidationError(project, .invalidTargetConfigFile(target: "target1", configFile: "invalidConfigFile", config: "invalidConfig"))
|
||||
try expectValidationError(project, .invalidTargetSchemeTest(target: "target1", testTarget: "invalidTarget"))
|
||||
try expectValidationError(project, .invalidTargetSource(target: "target1", source: "invalidSource"))
|
||||
try expectValidationError(project, .invalidBuildSettingConfig("invalidConfig"))
|
||||
try expectValidationError(project, .invalidSettingsGroup("invalidSettingGroup"))
|
||||
try expectValidationError(project, .invalidBuildScriptPath(target: "target1", name: "prebuildScript1", path: "invalidPrebuildScript"))
|
||||
try expectValidationError(project, .invalidBuildScriptPath(target: "target1", name: nil, path: "invalidPostbuildScript"))
|
||||
|
||||
try expectValidationError(spec, .missingConfigForTargetScheme(target: "target1", configType: .debug))
|
||||
try expectValidationError(spec, .missingConfigForTargetScheme(target: "target1", configType: .release))
|
||||
try expectValidationError(project, .missingConfigForTargetScheme(target: "target1", configType: .debug))
|
||||
try expectValidationError(project, .missingConfigForTargetScheme(target: "target1", configType: .release))
|
||||
|
||||
spec.targets[0].scheme?.configVariants = ["invalidVariant"]
|
||||
try expectValidationError(spec, .invalidTargetSchemeConfigVariant(target: "target1", configVariant: "invalidVariant", configType: .debug))
|
||||
project.targets[0].scheme?.configVariants = ["invalidVariant"]
|
||||
try expectValidationError(project, .invalidTargetSchemeConfigVariant(target: "target1", configVariant: "invalidVariant", configType: .debug))
|
||||
}
|
||||
|
||||
$0.it("fails with invalid scheme") {
|
||||
var spec = baseSpec
|
||||
spec.schemes = [Scheme(
|
||||
var project = baseProject
|
||||
project.schemes = [Scheme(
|
||||
name: "scheme1",
|
||||
build: .init(targets: [.init(target: "invalidTarget")]),
|
||||
run: .init(config: "debugInvalid"),
|
||||
archive: .init(config: "releaseInvalid")
|
||||
)]
|
||||
|
||||
try expectValidationError(spec, .invalidSchemeTarget(scheme: "scheme1", target: "invalidTarget"))
|
||||
try expectValidationError(spec, .invalidSchemeConfig(scheme: "scheme1", config: "debugInvalid"))
|
||||
try expectValidationError(spec, .invalidSchemeConfig(scheme: "scheme1", config: "releaseInvalid"))
|
||||
try expectValidationError(project, .invalidSchemeTarget(scheme: "scheme1", target: "invalidTarget"))
|
||||
try expectValidationError(project, .invalidSchemeConfig(scheme: "scheme1", config: "debugInvalid"))
|
||||
try expectValidationError(project, .invalidSchemeConfig(scheme: "scheme1", config: "releaseInvalid"))
|
||||
}
|
||||
|
||||
$0.it("allows missing optional file") {
|
||||
var spec = baseSpec
|
||||
spec.targets = [Target(
|
||||
var project = baseProject
|
||||
project.targets = [Target(
|
||||
name: "target1",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
sources: [.init(path: "generated.swift", optional: true)]
|
||||
)]
|
||||
try spec.validate()
|
||||
try project.validate()
|
||||
}
|
||||
|
||||
$0.it("validates missing default configurations") {
|
||||
var spec = baseSpec
|
||||
spec.options = SpecOptions(defaultConfig: "foo")
|
||||
try expectValidationError(spec, .missingDefaultConfig(configName: "foo"))
|
||||
var project = baseProject
|
||||
project.options = SpecOptions(defaultConfig: "foo")
|
||||
try expectValidationError(project, .missingDefaultConfig(configName: "foo"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,20 +5,20 @@ import Spectre
|
||||
import XcodeGenKit
|
||||
import xcproj
|
||||
|
||||
func specLoadingTests() {
|
||||
func projectLoadingTests() {
|
||||
|
||||
@discardableResult
|
||||
func getProjectSpec(_ spec: [String: Any]) throws -> Project {
|
||||
var specDictionary: [String: Any] = ["name": "test"]
|
||||
for (key, value) in spec {
|
||||
specDictionary[key] = value
|
||||
func getProjectSpec(_ project: [String: Any]) throws -> Project {
|
||||
var projectDictionary: [String: Any] = ["name": "test"]
|
||||
for (key, value) in project {
|
||||
projectDictionary[key] = value
|
||||
}
|
||||
return try Project(basePath: "", jsonDictionary: specDictionary)
|
||||
return try Project(basePath: "", jsonDictionary: projectDictionary)
|
||||
}
|
||||
|
||||
func expectSpecError(_ spec: [String: Any], _ expectedError: SpecParsingError) throws {
|
||||
func expectSpecError(_ project: [String: Any], _ expectedError: SpecParsingError) throws {
|
||||
try expectError(expectedError) {
|
||||
try getProjectSpec(spec)
|
||||
try getProjectSpec(project)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,15 +34,15 @@ func specLoadingTests() {
|
||||
describe("Spec Loader") {
|
||||
$0.it("merges includes") {
|
||||
let path = fixturePath + "include_test.yml"
|
||||
let spec = try Project(path: path)
|
||||
let project = try Project(path: path)
|
||||
|
||||
try expect(spec.name) == "NewName"
|
||||
try expect(spec.settingGroups) == [
|
||||
try expect(project.name) == "NewName"
|
||||
try expect(project.settingGroups) == [
|
||||
"test": Settings(dictionary: ["MY_SETTING1": "NEW VALUE", "MY_SETTING2": "VALUE2", "MY_SETTING3": "VALUE3"]),
|
||||
"new": Settings(dictionary: ["MY_SETTING": "VALUE"]),
|
||||
"toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]),
|
||||
]
|
||||
try expect(spec.targets) == [
|
||||
try expect(project.targets) == [
|
||||
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"]),
|
||||
Target(name: "NewTarget", type: .application, platform: .iOS),
|
||||
]
|
||||
@@ -88,15 +88,15 @@ func specLoadingTests() {
|
||||
describe("Spec Loader JSON") {
|
||||
$0.it("merges includes") {
|
||||
let path = fixturePath + "include_test.json"
|
||||
let spec = try Project(path: path)
|
||||
let project = try Project(path: path)
|
||||
|
||||
try expect(spec.name) == "NewName"
|
||||
try expect(spec.settingGroups) == [
|
||||
try expect(project.name) == "NewName"
|
||||
try expect(project.settingGroups) == [
|
||||
"test": Settings(dictionary: ["MY_SETTING1": "NEW VALUE", "MY_SETTING2": "VALUE2", "MY_SETTING3": "VALUE3"]),
|
||||
"new": Settings(dictionary: ["MY_SETTING": "VALUE"]),
|
||||
"toReplace": Settings(dictionary: ["MY_SETTING2": "VALUE2"]),
|
||||
]
|
||||
try expect(spec.targets) == [
|
||||
try expect(project.targets) == [
|
||||
Target(name: "IncludedTargetNew", type: .application, platform: .tvOS, sources: ["NewSource"]),
|
||||
Target(name: "NewTarget", type: .application, platform: .iOS),
|
||||
]
|
||||
@@ -178,7 +178,7 @@ func specLoadingTests() {
|
||||
"settings": ["SETTING": "value_$platform"],
|
||||
]
|
||||
|
||||
let spec = try getProjectSpec(["targets": ["Framework": targetDictionary]])
|
||||
let project = try getProjectSpec(["targets": ["Framework": targetDictionary]])
|
||||
var target_iOS = Target(name: "Framework_iOS", type: .framework, platform: .iOS)
|
||||
var target_tvOS = Target(name: "Framework_tvOS", type: .framework, platform: .tvOS)
|
||||
|
||||
@@ -187,8 +187,8 @@ func specLoadingTests() {
|
||||
target_iOS.settings = ["PRODUCT_NAME": "Framework", "SETTING": "value_iOS"]
|
||||
target_tvOS.settings = ["PRODUCT_NAME": "Framework", "SETTING": "value_tvOS"]
|
||||
|
||||
try expect(spec.targets.count) == 2
|
||||
try expect(spec.targets) == [target_iOS, target_tvOS]
|
||||
try expect(project.targets.count) == 2
|
||||
try expect(project.targets) == [target_iOS, target_tvOS]
|
||||
}
|
||||
|
||||
$0.it("parses target schemes") {
|
||||
@@ -320,7 +320,7 @@ func specLoadingTests() {
|
||||
}
|
||||
|
||||
$0.it("parses settings") {
|
||||
let spec = try Project(path: fixturePath + "settings_test.yml")
|
||||
let project = try Project(path: fixturePath + "settings_test.yml")
|
||||
let buildSettings: BuildSettings = ["SETTING": "value"]
|
||||
let configSettings: [String: Settings] = ["config1": Settings(buildSettings: ["SETTING1": "value"])]
|
||||
let groups = ["preset1"]
|
||||
@@ -334,15 +334,15 @@ func specLoadingTests() {
|
||||
let preset7 = Settings(buildSettings: buildSettings, configSettings: ["config1": Settings(buildSettings: buildSettings, groups: groups)])
|
||||
let preset8 = Settings(buildSettings: [:], configSettings: ["config1": Settings(configSettings: configSettings)])
|
||||
|
||||
try expect(spec.settingGroups.count) == 8
|
||||
try expect(spec.settingGroups["preset1"]) == preset1
|
||||
try expect(spec.settingGroups["preset2"]) == preset2
|
||||
try expect(spec.settingGroups["preset3"]) == preset3
|
||||
try expect(spec.settingGroups["preset4"]) == preset4
|
||||
try expect(spec.settingGroups["preset5"]) == preset5
|
||||
try expect(spec.settingGroups["preset6"]) == preset6
|
||||
try expect(spec.settingGroups["preset7"]) == preset7
|
||||
try expect(spec.settingGroups["preset8"]) == preset8
|
||||
try expect(project.settingGroups.count) == 8
|
||||
try expect(project.settingGroups["preset1"]) == preset1
|
||||
try expect(project.settingGroups["preset2"]) == preset2
|
||||
try expect(project.settingGroups["preset3"]) == preset3
|
||||
try expect(project.settingGroups["preset4"]) == preset4
|
||||
try expect(project.settingGroups["preset5"]) == preset5
|
||||
try expect(project.settingGroups["preset6"]) == preset6
|
||||
try expect(project.settingGroups["preset7"]) == preset7
|
||||
try expect(project.settingGroups["preset8"]) == preset8
|
||||
}
|
||||
|
||||
$0.it("parses run scripts") {
|
||||
|
||||
@@ -5,7 +5,7 @@ class XCodeGenKitTests: XCTestCase {
|
||||
|
||||
func testXcodeGenKit() {
|
||||
projectGeneratorTests()
|
||||
specLoadingTests()
|
||||
projectLoadingTests()
|
||||
fixtureTests()
|
||||
projectSpecTests()
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user