mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2024-09-20 09:08:46 +03:00
commit
701df1c915
@ -19,6 +19,7 @@ Required properties are marked with checkbox. Some of the YAML examples don't sh
|
||||
- [Config Files](#config-files)
|
||||
- [Settings](#settings)
|
||||
- [Build Script](#build-script)
|
||||
- [Build Rule](#build-rule)
|
||||
- [Dependency](#dependency)
|
||||
- [Target Scheme](#target-scheme)
|
||||
- [Legacy Target](#legacy-target)
|
||||
@ -160,9 +161,10 @@ Settings are merged in the following order: groups, base, configs.
|
||||
- [ ] **settings**: **[Settings](#settings)** - Target specific build settings. Default platform and product type settings will be applied first before any custom settings defined here. Other context dependant settings will be set automatically as well:
|
||||
- `INFOPLIST_FILE`: If it doesn't exist your sources will be searched for `Info.plist` files and the first one found will be used for this setting
|
||||
- `FRAMEWORK_SEARCH_PATHS`: If carthage dependencies are used, the platform build path will be added to this setting
|
||||
- [ ] **dependencies**: **[[Dependency](#dependency)]** - Dependencies for the target
|
||||
- [ ] **prebuildScripts**: **[[Build Script](#build-script)]** - Build scripts that run *before* any other build phases
|
||||
- [ ] **postbuildScripts**: **[[Build Script](#build-script)]** - Build scripts that run *after* any other build phases
|
||||
- [ ] **dependencies**: **[[Dependency](#dependency)]** - Dependencies for the target
|
||||
- [ ] **buildRules**: **[[Build Rule](#build-rule)]** - Custom build rules
|
||||
- [ ] **scheme**: **[Target Scheme](#target-scheme)** - Generated scheme with tests or config variants
|
||||
- [ ] **legacy**: **[Legacy Target](#legacy-target)** - When present, opt-in to make an Xcode "External Build System" legacy target instead.
|
||||
- [ ] **attributes**: **[String: Any]** - This sets values in the project `TargetAttributes`. It is merged with `attributes` from the project and anything automatically added by XcodeGen, with any duplicate values being override by values specified here. This is for advanced use only. Properties that are already set include:
|
||||
@ -374,6 +376,17 @@ targets:
|
||||
othercommand
|
||||
```
|
||||
|
||||
### Build Rule
|
||||
|
||||
- [ ] **filePattern**: **String** - A glob pattern for the files that will have the build rule run on them. This or `fileType` must be defined
|
||||
- [ ] **fileType**: **String** - A file type determined by Xcode. The available types can be seen by hovering your mouse of the `Process` dropdown in the Xcode interface. For example `sourcecode.swift` or `file.xib`. This or `filePattern` must be defined.
|
||||
- [ ] **script**: **String** - The script that will be run on each file. This or `compilerSpec` must be defined.
|
||||
- [ ] **compilerSpec**: **String**: A reference to a built in apple tool to run on each file. This is for advanced use and the the values for this must be checked. This or `script` must be defined.
|
||||
- [ ] **name**: **String** - The name of a build rule. Defaults to `Build Rule`
|
||||
- [ ] **outputFiles**: **[String]** - The list of output files
|
||||
- [ ] **outputFilesCompilerFlags**: **[String]** - The list of compiler flags to apply to the output files
|
||||
|
||||
|
||||
### Target Scheme
|
||||
|
||||
This is a convenience used to automatically generate schemes for a target based on different configs or included tests. If you want more control check out the top level [Scheme](#scheme).
|
||||
|
82
Sources/ProjectSpec/BuildRule.swift
Normal file
82
Sources/ProjectSpec/BuildRule.swift
Normal file
@ -0,0 +1,82 @@
|
||||
import Foundation
|
||||
import JSONUtilities
|
||||
|
||||
public struct BuildRule: Equatable {
|
||||
|
||||
public static let scriptCompilerSpec = "com.apple.compilers.proxy.script"
|
||||
public static let filePatternFileType = "pattern.proxy"
|
||||
|
||||
public enum FileType: Equatable {
|
||||
case type(String)
|
||||
case pattern(String)
|
||||
|
||||
public var fileType: String {
|
||||
switch self {
|
||||
case .type(let fileType): return fileType
|
||||
case .pattern: return BuildRule.filePatternFileType
|
||||
}
|
||||
}
|
||||
|
||||
public var pattern: String? {
|
||||
switch self {
|
||||
case .type: return nil
|
||||
case .pattern(let pattern): return pattern
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Action: Equatable {
|
||||
case compilerSpec(String)
|
||||
case script(String)
|
||||
|
||||
public var compilerSpec: String {
|
||||
switch self {
|
||||
case .compilerSpec(let compilerSpec): return compilerSpec
|
||||
case .script: return BuildRule.scriptCompilerSpec
|
||||
}
|
||||
}
|
||||
|
||||
public var script: String? {
|
||||
switch self {
|
||||
case .compilerSpec: return nil
|
||||
case .script(let script): return script
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var fileType: FileType
|
||||
public var action: Action
|
||||
public var outputFiles: [String]
|
||||
public var outputFilesCompilerFlags: [String]
|
||||
public var name: String?
|
||||
|
||||
public init(fileType: FileType, action: Action, name: String? = nil, outputFiles: [String] = [], outputFilesCompilerFlags: [String] = []) {
|
||||
self.fileType = fileType
|
||||
self.action = action
|
||||
self.name = name
|
||||
self.outputFiles = outputFiles
|
||||
self.outputFilesCompilerFlags = outputFilesCompilerFlags
|
||||
}
|
||||
}
|
||||
|
||||
extension BuildRule: JSONObjectConvertible {
|
||||
|
||||
public init(jsonDictionary: JSONDictionary) throws {
|
||||
|
||||
if let fileType: String = jsonDictionary.json(atKeyPath: "fileType") {
|
||||
self.fileType = .type(fileType)
|
||||
} else {
|
||||
self.fileType = .pattern(try jsonDictionary.json(atKeyPath: "filePattern"))
|
||||
}
|
||||
|
||||
if let compilerSpec: String = jsonDictionary.json(atKeyPath: "compilerSpec") {
|
||||
self.action = .compilerSpec(compilerSpec)
|
||||
} else {
|
||||
self.action = .script(try jsonDictionary.json(atKeyPath: "script"))
|
||||
}
|
||||
|
||||
outputFiles = jsonDictionary.json(atKeyPath: "outputFiles") ?? []
|
||||
outputFilesCompilerFlags = jsonDictionary.json(atKeyPath: "outputFilesCompilerFlags") ?? []
|
||||
name = jsonDictionary.json(atKeyPath: "name")
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ public struct Target {
|
||||
public var dependencies: [Dependency]
|
||||
public var prebuildScripts: [BuildScript]
|
||||
public var postbuildScripts: [BuildScript]
|
||||
public var buildRules: [BuildRule]
|
||||
public var configFiles: [String: String]
|
||||
public var scheme: TargetScheme?
|
||||
public var legacy: LegacyTarget?
|
||||
@ -60,6 +61,7 @@ public struct Target {
|
||||
dependencies: [Dependency] = [],
|
||||
prebuildScripts: [BuildScript] = [],
|
||||
postbuildScripts: [BuildScript] = [],
|
||||
buildRules: [BuildRule] = [],
|
||||
scheme: TargetScheme? = nil,
|
||||
legacy: LegacyTarget? = nil,
|
||||
attributes: [String: Any] = [:]
|
||||
@ -74,6 +76,7 @@ public struct Target {
|
||||
self.dependencies = dependencies
|
||||
self.prebuildScripts = prebuildScripts
|
||||
self.postbuildScripts = postbuildScripts
|
||||
self.buildRules = buildRules
|
||||
self.scheme = scheme
|
||||
self.legacy = legacy
|
||||
self.attributes = attributes
|
||||
@ -168,6 +171,7 @@ extension Target: Equatable {
|
||||
lhs.dependencies == rhs.dependencies &&
|
||||
lhs.prebuildScripts == rhs.prebuildScripts &&
|
||||
lhs.postbuildScripts == rhs.postbuildScripts &&
|
||||
lhs.buildRules == rhs.buildRules &&
|
||||
lhs.scheme == rhs.scheme &&
|
||||
lhs.legacy == rhs.legacy &&
|
||||
NSDictionary(dictionary: lhs.attributes).isEqual(to: rhs.attributes)
|
||||
@ -275,6 +279,7 @@ extension Target: NamedJSONDictionaryConvertible {
|
||||
}
|
||||
prebuildScripts = jsonDictionary.json(atKeyPath: "prebuildScripts") ?? []
|
||||
postbuildScripts = jsonDictionary.json(atKeyPath: "postbuildScripts") ?? []
|
||||
buildRules = jsonDictionary.json(atKeyPath: "buildRules") ?? []
|
||||
scheme = jsonDictionary.json(atKeyPath: "scheme")
|
||||
legacy = jsonDictionary.json(atKeyPath: "legacy")
|
||||
attributes = jsonDictionary.json(atKeyPath: "attributes") ?? [:]
|
||||
|
@ -643,6 +643,20 @@ public class PBXProjGenerator {
|
||||
buildPhases.append(carthageScript.reference)
|
||||
}
|
||||
|
||||
let buildRules = target.buildRules.map { buildRule in
|
||||
createObject(id: "\(target.name)-\(buildRule.action)-\(buildRule.fileType)",
|
||||
PBXBuildRule(
|
||||
compilerSpec: buildRule.action.compilerSpec,
|
||||
fileType: buildRule.fileType.fileType,
|
||||
isEditable: true,
|
||||
filePatterns: buildRule.fileType.pattern,
|
||||
name: buildRule.name ?? "Build Rule",
|
||||
outputFiles: buildRule.outputFiles,
|
||||
outputFilesCompilerFlags: buildRule.outputFilesCompilerFlags,
|
||||
script: buildRule.action.script
|
||||
)).reference
|
||||
}
|
||||
|
||||
try target.postbuildScripts.forEach(generateBuildScript)
|
||||
|
||||
let targetObject = targetObjects[target.name]!.object
|
||||
@ -652,6 +666,7 @@ public class PBXProjGenerator {
|
||||
targetObject.buildPhases = buildPhases
|
||||
targetObject.dependencies = dependencies
|
||||
targetObject.productName = target.name
|
||||
targetObject.buildRules = buildRules
|
||||
targetObject.productReference = fileReference
|
||||
if !target.isLegacy {
|
||||
targetObject.productType = target.type
|
||||
|
@ -63,6 +63,37 @@
|
||||
BF_940936137577 = {isa = PBXBuildFile; fileRef = FR_123503999387 /* App_iOS_UITests.xctest */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXBuildRule section */
|
||||
BR_808703807095 /* PBXBuildRule */ = {
|
||||
isa = PBXBuildRule;
|
||||
compilerSpec = "com.apple.build-tasks.copy-plist-file";
|
||||
filePatterns = "*.plist";
|
||||
fileType = pattern.proxy;
|
||||
isEditable = 1;
|
||||
name = "Build Rule";
|
||||
outputFiles = (
|
||||
);
|
||||
outputFilesCompilerFlags = (
|
||||
);
|
||||
};
|
||||
BR_855671637991 /* PBXBuildRule */ = {
|
||||
isa = PBXBuildRule;
|
||||
compilerSpec = com.apple.compilers.proxy.script;
|
||||
fileType = sourcecode.swift;
|
||||
isEditable = 1;
|
||||
name = "My Rule";
|
||||
outputFiles = (
|
||||
file.swift,
|
||||
file2.swift,
|
||||
);
|
||||
outputFilesCompilerFlags = (
|
||||
"--zee",
|
||||
"--bee",
|
||||
);
|
||||
script = "# comment";
|
||||
};
|
||||
/* End PBXBuildRule section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
CIP_12350399938 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
@ -665,6 +696,8 @@
|
||||
SSBP_8706434794 /* MyScript */,
|
||||
);
|
||||
buildRules = (
|
||||
BR_855671637991 /* PBXBuildRule */,
|
||||
BR_808703807095 /* PBXBuildRule */,
|
||||
);
|
||||
dependencies = (
|
||||
TD_354342487294 /* PBXTargetDependency */,
|
||||
|
@ -67,6 +67,14 @@ targets:
|
||||
- name: MyScript
|
||||
script: |
|
||||
echo "You ran a script!"
|
||||
buildRules:
|
||||
- name: My Rule
|
||||
fileType: sourcecode.swift
|
||||
script: "# comment"
|
||||
outputFiles: [file.swift, file2.swift]
|
||||
outputFilesCompilerFlags: [--zee, --bee]
|
||||
- filePattern: "*.plist"
|
||||
compilerSpec: com.apple.build-tasks.copy-plist-file
|
||||
|
||||
App_watchOS:
|
||||
type: application.watchapp2
|
||||
|
@ -364,6 +364,32 @@ func projectLoadingTests() {
|
||||
try expect(parsedTarget.postbuildScripts) == expectedScripts
|
||||
}
|
||||
|
||||
$0.it("parses build rules") {
|
||||
var target = validTarget
|
||||
let buildRules: [[String: Any]] = [
|
||||
[
|
||||
"name": "My Rule",
|
||||
"script": "my script",
|
||||
"filePattern": "*.swift",
|
||||
"outputFiles": ["file1", "file2"],
|
||||
"outputFilesCompilerFlags": ["-a","-b"]
|
||||
],
|
||||
[
|
||||
"compilerSpec": "apple.tool",
|
||||
"fileType": "sourcecode.swift",
|
||||
]
|
||||
]
|
||||
target["buildRules"] = buildRules
|
||||
|
||||
let expectedBuildRules = [
|
||||
BuildRule(fileType: .pattern("*.swift"), action: .script("my script"), name: "My Rule", outputFiles: ["file1", "file2"], outputFilesCompilerFlags: ["-a","-b"]),
|
||||
BuildRule(fileType: .type("sourcecode.swift"), action: .compilerSpec("apple.tool")),
|
||||
]
|
||||
|
||||
let parsedTarget = try Target(name: "test", jsonDictionary: target)
|
||||
try expect(parsedTarget.buildRules) == expectedBuildRules
|
||||
}
|
||||
|
||||
$0.it("parses options") {
|
||||
let options = SpecOptions(
|
||||
carthageBuildPath: "../Carthage/Build",
|
||||
|
Loading…
Reference in New Issue
Block a user