commit ef402f6e36bb9a7904c6b65e5fd43c1ee590e787 Author: Yonas Kolb Date: Wed Jul 19 14:55:01 2017 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5268c345 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +/.build +/Packages +XcodeGen.xcodeproj diff --git a/Package.pins b/Package.pins new file mode 100644 index 00000000..52dd7f69 --- /dev/null +++ b/Package.pins @@ -0,0 +1,66 @@ +{ + "autoPin": true, + "pins": [ + { + "package": "AEXML", + "reason": null, + "repositoryURL": "https://github.com/tadija/AEXML.git", + "version": "4.1.0" + }, + { + "package": "Commander", + "reason": null, + "repositoryURL": "https://github.com/kylef/Commander.git", + "version": "0.6.1" + }, + { + "package": "CryptoSwift", + "reason": null, + "repositoryURL": "https://github.com/krzyzanowskim/CryptoSwift.git", + "version": "0.6.9" + }, + { + "package": "JSONUtilities", + "reason": null, + "repositoryURL": "https://github.com/yonaskolb/JSONUtilities.git", + "version": "3.3.5" + }, + { + "package": "PathKit", + "reason": null, + "repositoryURL": "https://github.com/kylef/PathKit.git", + "version": "0.8.0" + }, + { + "package": "Rainbow", + "reason": null, + "repositoryURL": "https://github.com/onevcat/Rainbow", + "version": "2.0.1" + }, + { + "package": "Spectre", + "reason": null, + "repositoryURL": "https://github.com/kylef/Spectre.git", + "version": "0.7.2" + }, + { + "package": "Unbox", + "reason": null, + "repositoryURL": "https://github.com/JohnSundell/Unbox", + "version": "2.4.0" + }, + { + "package": "Yams", + "reason": null, + "repositoryURL": "https://github.com/jpsim/Yams.git", + "version": "0.2.0" + }, + { + "package": "xcodeproj", + "reason": null, + "repositoryURL": "https://github.com/yonaskolb/xcodeproj.git", + "version": "0.0.4" + } + ], + "version": 1 +} \ No newline at end of file diff --git a/Package.swift b/Package.swift new file mode 100644 index 00000000..129f10b4 --- /dev/null +++ b/Package.swift @@ -0,0 +1,20 @@ +// swift-tools-version:3.1 + +import PackageDescription + +let package = Package( + name: "XcodeGen", + targets: [ + Target(name: "XcodeGen", dependencies: ["XcodeGenKit"]), + Target(name: "XcodeGenKit"), + ], + dependencies: [ + .Package(url: "https://github.com/kylef/PathKit.git", majorVersion: 0, minor: 8), + .Package(url: "https://github.com/kylef/Commander.git", majorVersion: 0, minor: 6), + .Package(url: "https://github.com/jpsim/Yams.git", majorVersion: 0, minor: 2), + .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/yonaskolb/xcodeproj.git", majorVersion: 0, minor: 0), + ] +) diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift new file mode 100644 index 00000000..7eac25c8 --- /dev/null +++ b/Sources/XcodeGen/main.swift @@ -0,0 +1,40 @@ +// +// main.swift +// SwiftySwagger +// +// Created by Yonas Kolb on 17/09/2016. +// Copyright © 2016 Yonas Kolb. All rights reserved. +// + +import Foundation +import PathKit +import Commander +import XcodeGenKit + +func generate(spec: String) { + let specPath = Path("~/Developer/XcodeGen/test_spec.yml").normalize() + + let spec: Spec + do { + spec = try Spec(path: specPath) + print(spec) + print("") + + } catch { + print("Parsing spec failed: \(error)") + return + } + + do { + try Generator.generate(spec: spec, path: Path("~/Developer/XcodeGen/test_project.xcodeproj").normalize()) + print("Generated Xcode Project") + } catch { + print("Generation failed: \(error)") + } +} + + +command( + Option("spec", "", flag: "p", description: "The path to the spec file"), + generate) + .run() diff --git a/Sources/XcodeGenKit/Decoding.swift b/Sources/XcodeGenKit/Decoding.swift new file mode 100644 index 00000000..eefc4c1e --- /dev/null +++ b/Sources/XcodeGenKit/Decoding.swift @@ -0,0 +1,31 @@ +// +// Decoding.swift +// XcodeGen +// +// Created by Yonas Kolb on 19/5/17. +// +// + +import Foundation +import JSONUtilities + +extension Dictionary where Key: JSONKey { + + public func json(atKeyPath keyPath: KeyPath, invalidItemBehaviour: InvalidItemBehaviour = .remove) throws -> [T] { + guard let dictionary = json(atKeyPath: keyPath) as JSONDictionary? else { + return [] + } + var items: [T] = [] + for (key, _) in dictionary { + let jsonDictionary: JSONDictionary = try dictionary.json(atKeyPath: .key(key)) + let item = try T(name: key, jsonDictionary: jsonDictionary) + items.append(item) + } + return items + } +} + +public protocol NamedJSONObjectConvertible { + + init(name: String, jsonDictionary: JSONDictionary) throws +} diff --git a/Sources/XcodeGenKit/Generator.swift b/Sources/XcodeGenKit/Generator.swift new file mode 100644 index 00000000..f2de1208 --- /dev/null +++ b/Sources/XcodeGenKit/Generator.swift @@ -0,0 +1,80 @@ +// +// Generator.swift +// XcodeGen +// +// Created by Yonas Kolb on 19/5/17. +// +// + +import Foundation +import PathKit +import xcodeproj +import xcodeprojprotocols + +public struct Generator { + + public static func generate(spec: Spec, path: Path) throws { + + let workspaceReferences: [XCWorkspace.Data.FileRef] = [XCWorkspace.Data.FileRef.project(path: path)] + let workspaceData = XCWorkspace.Data(path: path, references: workspaceReferences) + let workspace = XCWorkspace(path: path + "project.xcworkspace", data: workspaceData) + + + var objects: [PBXObject] = [] + var ids = 0 + + func id() -> String { + ids += 1 + return "OBJECT_\(ids)" + } + + for target in spec.targets { + let sourcePaths: [Path] = target.sources.reduce([]) { paths, source in +// $0 + spec.path.parent().glob($1) + let sourcePaths = try! (spec.path.parent() + source).recursiveChildren().filter { $0.isFile } + return paths + sourcePaths + } + let fileReferences = sourcePaths.map { PBXFileReference(reference: id(), sourceTree: .group, path: $0.lastComponent) } + let buildFiles = fileReferences.map { PBXBuildFile(reference: id(), fileRef: $0.reference) } + let buildPhase = PBXSourcesBuildPhase(reference: id(), files: Set(buildFiles.map { $0.reference })) + let buildPhases = [buildPhase] + + let nativeTarget = PBXNativeTarget(reference: "OBJECT_\(objects.count)", buildConfigurationList: "234", buildPhases: buildPhases.map{ $0.reference }, buildRules: [], dependencies: [], name: target.name) + + objects += buildFiles.map { .pbxBuildFile($0) } + objects += fileReferences.map { .pbxFileReference($0) } + objects += buildPhases.map { .pbxSourcesBuildPhase($0) } + + objects.append(.pbxNativeTarget(nativeTarget)) + } + + let pbxProject = PBXProj(path: path + "project.pbxproj", name: "Generated_Project", archiveVersion: 1, objectVersion: 46, rootObject: "12345", objects: objects) + + let schemes: [XCScheme] = spec.schemes.map { schemeSpec in +// let buildEntries: [XCScheme.BuildAction.Entry] = schemeSpec.build.entries.map { build in +// let buildableReference: XCScheme.BuildableReference? = nil +// return XCScheme.BuildAction.Entry(buildableReference: buildableReference!, buildFor: build.buildTypes) +// } + let buildAction = XCScheme.BuildAction(buildActionEntries: [], parallelizeBuild: true, buildImplicitDependencies: true) + + return XCScheme(path: path, lastUpgradeVersion: nil, version: nil, buildAction: buildAction, testAction: nil, launchAction: nil, profileAction: nil, analyzeAction: nil, archiveAction: nil) + } + + let sharedData = XCSharedData(path: path, schemes: schemes) + let project = XcodeProj(path: path, workspace: workspace, pbxproj: pbxProject, sharedData: sharedData) + + try project.write(override: true) + } +} + +extension XcodeProj: Writable { + + public func write(override: Bool) throws { + if override && path.exists { + try path.delete() + } + + try path.mkpath() + try pbxproj.write(override: override) + } +} diff --git a/Sources/XcodeGenKit/Scheme.swift b/Sources/XcodeGenKit/Scheme.swift new file mode 100644 index 00000000..85afd97b --- /dev/null +++ b/Sources/XcodeGenKit/Scheme.swift @@ -0,0 +1,58 @@ +// +// Scheme.swift +// XcodeGen +// +// Created by Yonas Kolb on 19/5/17. +// +// + +import Foundation +import xcodeproj +import JSONUtilities + +public struct SchemeSpec { + + public var name: String + public var build: Build + + public struct Build { + public var entries: [BuildEntry] + } + + public struct BuildEntry { + public var target: String + public var buildTypes: [XCScheme.BuildAction.Entry.BuildFor] + } +} + +extension SchemeSpec: NamedJSONObjectConvertible { + + public init(name: String, jsonDictionary: JSONDictionary) throws { + self.name = name + build = try jsonDictionary.json(atKeyPath: "build") + } +} + +extension SchemeSpec.Build: JSONObjectConvertible { + + public init(jsonDictionary: JSONDictionary) throws { + entries = try jsonDictionary.json(atKeyPath: "targets") + } +} + +extension SchemeSpec.BuildEntry: NamedJSONObjectConvertible { + + public init(name: String, jsonDictionary: JSONDictionary) throws { + target = name + buildTypes = jsonDictionary.json(atKeyPath: "buildTypes") ?? [.running, .testing, .archiving, .analyzing] + } +} + +extension XCScheme.BuildAction.Entry.BuildFor: JSONPrimitiveConvertible { + + public typealias JSONType = String + + public static func from(jsonValue: String) -> XCScheme.BuildAction.Entry.BuildFor? { + return .testing + } +} diff --git a/Sources/XcodeGenKit/Spec.swift b/Sources/XcodeGenKit/Spec.swift new file mode 100644 index 00000000..d588d126 --- /dev/null +++ b/Sources/XcodeGenKit/Spec.swift @@ -0,0 +1,129 @@ +// +// Spec.swift +// XcodeGen +// +// Created by Yonas Kolb on 19/5/17. +// +// + +import Foundation + + +import JSONUtilities +import PathKit +import Yams + +extension Spec { + + public init(path: Path) throws { + var url = URL(string: path.string)! + if url.scheme == nil { + url = URL(fileURLWithPath: path.string) + } + + let data = try Data(contentsOf: url) + let string = String(data: data, encoding: .utf8)! + + try self.init(path: path, string: string) + } + + public init(path: Path, string: String) throws { + let yaml = try Yams.load(yaml: string) + let json = yaml as! JSONDictionary + + try self.init(path: path, jsonDictionary: json) + } + + public init(path: Path, jsonDictionary: JSONDictionary) throws { + self.path = path + settingGroups = try jsonDictionary.json(atKeyPath: "settingGroups") + configs = try jsonDictionary.json(atKeyPath: "configs") + targets = try jsonDictionary.json(atKeyPath: "targets") + schemes = try jsonDictionary.json(atKeyPath: "schemes") + } +} + + +public struct Spec { + + public var settingGroups: [BuildSettingGroup] + public var configs: [Config] + public var targets: [TargetSpec] + public var schemes: [SchemeSpec] + public var path: Path +} + +public struct TargetSpec { + public var name: String + public var type: String + public var localizedSource: String? + public var sources: [String] + public var sourceExludes: [String] + public var dependancies: [Dependancy] + public var prebuildScripts: [String] + public var postbuildScripts: [String] +} + +extension TargetSpec: NamedJSONObjectConvertible { + + public init(name: String, jsonDictionary: JSONDictionary) throws { + self.name = name + type = try jsonDictionary.json(atKeyPath: "type") + sources = jsonDictionary.json(atKeyPath: "sources") ?? [] + sourceExludes = jsonDictionary.json(atKeyPath: "sourceExludes") ?? [] + dependancies = jsonDictionary.json(atKeyPath: "dependancies") ?? [] + prebuildScripts = jsonDictionary.json(atKeyPath: "prebuildScripts") ?? [] + postbuildScripts = jsonDictionary.json(atKeyPath: "postbuildScripts") ?? [] + } +} + + +public struct Dependancy { + + public var path: String + public var type: DependancyType + + public enum DependancyType: String { + case target + case system + } +} + +extension Dependancy: JSONObjectConvertible { + + public init(jsonDictionary: JSONDictionary) throws { + path = try jsonDictionary.json(atKeyPath: "path") + type = try jsonDictionary.json(atKeyPath: "type") + } +} + +public struct Config { + public var name: String + public var buildSettingGroups: [BuildSettingGroup] + public var settings: [String: String] +} + +extension Config: NamedJSONObjectConvertible { + + public init(name: String, jsonDictionary: JSONDictionary) throws { + self.name = name + buildSettingGroups = try jsonDictionary.json(atKeyPath: "settingGroups") + settings = jsonDictionary.json(atKeyPath: "settings") ?? [:] + } +} + +public struct BuildSettingGroup { + public var name: String + public var buildSettings: [String: String] +} + +extension BuildSettingGroup: NamedJSONObjectConvertible { + + public init(name: String, jsonDictionary: JSONDictionary) throws { + self.name = name + buildSettings = [:] + for (key, value) in jsonDictionary { + buildSettings[key] = String(describing: value) + } + } +} diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift new file mode 100644 index 00000000..c8b7556f --- /dev/null +++ b/Tests/LinuxMain.swift @@ -0,0 +1,6 @@ +import XCTest +@testable import XcodeGenTests + +XCTMain([ + testCase(XcodeGenTests.allTests), +]) diff --git a/Tests/XcodeGenTests/XcodeGenTests.swift b/Tests/XcodeGenTests/XcodeGenTests.swift new file mode 100644 index 00000000..60a3d908 --- /dev/null +++ b/Tests/XcodeGenTests/XcodeGenTests.swift @@ -0,0 +1,15 @@ +import XCTest +@testable import XcodeGen + +class XcodeGenTests: XCTestCase { + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + XCTAssertEqual(XcodeGen().text, "Hello, World!") + } + + + static var allTests = [ + ("testExample", testExample), + ] +} diff --git a/setting_groups/general_debug.yml b/setting_groups/general_debug.yml new file mode 100644 index 00000000..65fce49f --- /dev/null +++ b/setting_groups/general_debug.yml @@ -0,0 +1,42 @@ +--- +ALWAYS_SEARCH_USER_PATHS: 'NO' +CLANG_ANALYZER_NONNULL: 'YES' +CLANG_CXX_LANGUAGE_STANDARD: gnu++0x +CLANG_CXX_LIBRARY: libc++ +CLANG_ENABLE_MODULES: 'YES' +CLANG_ENABLE_OBJC_ARC: 'YES' +CLANG_WARN_BOOL_CONVERSION: 'YES' +CLANG_WARN_CONSTANT_CONVERSION: 'YES' +CLANG_WARN_DIRECT_OBJC_ISA_USAGE: YES_ERROR +CLANG_WARN_DOCUMENTATION_COMMENTS: 'YES' +CLANG_WARN_EMPTY_BODY: 'YES' +CLANG_WARN_ENUM_CONVERSION: 'YES' +CLANG_WARN_INFINITE_RECURSION: 'YES' +CLANG_WARN_INT_CONVERSION: 'YES' +CLANG_WARN_OBJC_ROOT_CLASS: YES_ERROR +CLANG_WARN_SUSPICIOUS_MOVES: 'YES' +CLANG_WARN_UNREACHABLE_CODE: 'YES' +CLANG_WARN__DUPLICATE_METHOD_MATCH: 'YES' +COPY_PHASE_STRIP: 'NO' +DEBUG_INFORMATION_FORMAT: dwarf +ENABLE_STRICT_OBJC_MSGSEND: 'YES' +ENABLE_TESTABILITY: 'YES' +GCC_C_LANGUAGE_STANDARD: gnu99 +GCC_DYNAMIC_NO_PIC: 'NO' +GCC_NO_COMMON_BLOCKS: 'YES' +GCC_OPTIMIZATION_LEVEL: '0' +GCC_PREPROCESSOR_DEFINITIONS: +- DEBUG=1 +- "$(inherited)" +GCC_WARN_64_TO_32_BIT_CONVERSION: 'YES' +GCC_WARN_ABOUT_RETURN_TYPE: YES_ERROR +GCC_WARN_UNDECLARED_SELECTOR: 'YES' +GCC_WARN_UNINITIALIZED_AUTOS: YES_AGGRESSIVE +GCC_WARN_UNUSED_FUNCTION: 'YES' +GCC_WARN_UNUSED_VARIABLE: 'YES' +ONLY_ACTIVE_ARCH: 'YES' +SWIFT_ACTIVE_COMPILATION_CONDITIONS: DEBUG +SWIFT_OPTIMIZATION_LEVEL: "-Onone" +CODE_SIGN_IDENTITY[sdk=iphoneos*]: iPhone Developer +CODE_SIGN_IDENTITY: "-" +CLANG_WARN_SUSPICIOUS_MOVE: "YES" diff --git a/setting_groups/general_release.yml b/setting_groups/general_release.yml new file mode 100644 index 00000000..37241650 --- /dev/null +++ b/setting_groups/general_release.yml @@ -0,0 +1,36 @@ +--- +ALWAYS_SEARCH_USER_PATHS: 'NO' +CLANG_ANALYZER_NONNULL: 'YES' +CLANG_CXX_LANGUAGE_STANDARD: gnu++0x +CLANG_CXX_LIBRARY: libc++ +CLANG_ENABLE_MODULES: 'YES' +CLANG_ENABLE_OBJC_ARC: 'YES' +CLANG_WARN_BOOL_CONVERSION: 'YES' +CLANG_WARN_CONSTANT_CONVERSION: 'YES' +CLANG_WARN_DIRECT_OBJC_ISA_USAGE: YES_ERROR +CLANG_WARN_DOCUMENTATION_COMMENTS: 'YES' +CLANG_WARN_EMPTY_BODY: 'YES' +CLANG_WARN_ENUM_CONVERSION: 'YES' +CLANG_WARN_INFINITE_RECURSION: 'YES' +CLANG_WARN_INT_CONVERSION: 'YES' +CLANG_WARN_OBJC_ROOT_CLASS: YES_ERROR +CLANG_WARN_SUSPICIOUS_MOVES: 'YES' +CLANG_WARN_UNREACHABLE_CODE: 'YES' +CLANG_WARN__DUPLICATE_METHOD_MATCH: 'YES' +COPY_PHASE_STRIP: 'NO' +DEBUG_INFORMATION_FORMAT: dwarf-with-dsym +ENABLE_NS_ASSERTIONS: 'NO' +ENABLE_STRICT_OBJC_MSGSEND: 'YES' +GCC_C_LANGUAGE_STANDARD: gnu99 +GCC_NO_COMMON_BLOCKS: 'YES' +GCC_WARN_64_TO_32_BIT_CONVERSION: 'YES' +GCC_WARN_ABOUT_RETURN_TYPE: YES_ERROR +GCC_WARN_UNDECLARED_SELECTOR: 'YES' +GCC_WARN_UNINITIALIZED_AUTOS: YES_AGGRESSIVE +GCC_WARN_UNUSED_FUNCTION: 'YES' +GCC_WARN_UNUSED_VARIABLE: 'YES' +SWIFT_OPTIMIZATION_LEVEL: "-Owholemodule" +VALIDATE_PRODUCT: 'YES' +CODE_SIGN_IDENTITY[sdk=iphoneos*]: iPhone Developer +CODE_SIGN_IDENTITY: "-" +CLANG_WARN_SUSPICIOUS_MOVE: "YES" diff --git a/setting_groups/ios_debug.yml b/setting_groups/ios_debug.yml new file mode 100644 index 00000000..84fa54f0 --- /dev/null +++ b/setting_groups/ios_debug.yml @@ -0,0 +1,3 @@ +--- +MTL_ENABLE_DEBUG_INFO: 'YES' +IPHONEOS_DEPLOYMENT_TARGET: '10.2' diff --git a/setting_groups/ios_release.yml b/setting_groups/ios_release.yml new file mode 100644 index 00000000..75c3c2e4 --- /dev/null +++ b/setting_groups/ios_release.yml @@ -0,0 +1,3 @@ +--- +MTL_ENABLE_DEBUG_INFO: 'NO' +IPHONEOS_DEPLOYMENT_TARGET: '10.2' diff --git a/test_project.xcodeproj/project.pbxproj b/test_project.xcodeproj/project.pbxproj new file mode 100644 index 00000000..ecf672b6 --- /dev/null +++ b/test_project.xcodeproj/project.pbxproj @@ -0,0 +1,62 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = ( + ); + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + OBJECT_10 /* .DS_Store in Sources */ = {isa = PBXBuildFile; fileRef = OBJECT_3 /* .DS_Store */; }; + OBJECT_11 /* Decoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJECT_4 /* Decoding.swift */; }; + OBJECT_12 /* Generator.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJECT_5 /* Generator.swift */; }; + OBJECT_13 /* Scheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJECT_6 /* Scheme.swift */; }; + OBJECT_14 /* Spec.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJECT_7 /* Spec.swift */; }; + OBJECT_8 /* .DS_Store in Sources */ = {isa = PBXBuildFile; fileRef = OBJECT_1 /* .DS_Store */; }; + OBJECT_9 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJECT_2 /* main.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + OBJECT_1 /* .DS_Store */ = {isa = PBXFileReference; path = .DS_Store; sourceTree = ""; }; + OBJECT_2 /* main.swift */ = {isa = PBXFileReference; path = main.swift; sourceTree = ""; }; + OBJECT_3 /* .DS_Store */ = {isa = PBXFileReference; path = .DS_Store; sourceTree = ""; }; + OBJECT_4 /* Decoding.swift */ = {isa = PBXFileReference; path = Decoding.swift; sourceTree = ""; }; + OBJECT_5 /* Generator.swift */ = {isa = PBXFileReference; path = Generator.swift; sourceTree = ""; }; + OBJECT_6 /* Scheme.swift */ = {isa = PBXFileReference; path = Scheme.swift; sourceTree = ""; }; + OBJECT_7 /* Spec.swift */ = {isa = PBXFileReference; path = Spec.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXNativeTarget section */ + OBJECT_0 /* Axis iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 234 /* Build configuration list for PBXNativeTarget "Axis iOS" */; + buildPhases = ( + OBJECT_15 /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Axis iOS; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXSourcesBuildPhase section */ + OBJECT_15 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + OBJECT_13 /* Scheme.swift in Sources */, + OBJECT_8 /* .DS_Store in Sources */, + OBJECT_9 /* main.swift in Sources */, + OBJECT_12 /* Generator.swift in Sources */, + OBJECT_10 /* .DS_Store in Sources */, + OBJECT_11 /* Decoding.swift in Sources */, + OBJECT_14 /* Spec.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + }; + rootObject = 12345 /* Project object */; +} diff --git a/test_spec.yml b/test_spec.yml new file mode 100644 index 00000000..de241ee7 --- /dev/null +++ b/test_spec.yml @@ -0,0 +1,20 @@ +settingGroups: + test: + CLANG_ENABLE_MODULES: 'YES' +configs: + Staging Test: + settingGroups: + - debug + - test + settings: +targets: + Axis iOS: + type: application + sources: + - Sources +schemes: + iOS Test: + build: + targets: + Axis iOS: + archive: true