Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for customizing attributes on a target source file #583

Merged
merged 6 commits into from
Jun 14, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Docs/ProjectSpec.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ A source can be provided via a string (the path) or an object of the form:
- `public`
- `private`
- `project`
- [ ] **attributes**: **[String]** - Additional settings attributes for the file reference.
min marked this conversation as resolved.
Show resolved Hide resolved

```yaml
targets:
Expand Down
6 changes: 5 additions & 1 deletion Sources/ProjectSpec/TargetSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public struct TargetSource: Equatable {
public var buildPhase: BuildPhase?
public var headerVisibility: HeaderVisibility?
public var createIntermediateGroups: Bool?
public var attributes: [String]

public enum HeaderVisibility: String {
case `public`
Expand Down Expand Up @@ -126,7 +127,8 @@ public struct TargetSource: Equatable {
optional: Bool = false,
buildPhase: BuildPhase? = nil,
headerVisibility: HeaderVisibility? = nil,
createIntermediateGroups: Bool? = nil
createIntermediateGroups: Bool? = nil,
attributes: [String] = []
) {
self.path = path
self.name = name
Expand All @@ -137,6 +139,7 @@ public struct TargetSource: Equatable {
self.buildPhase = buildPhase
self.headerVisibility = headerVisibility
self.createIntermediateGroups = createIntermediateGroups
self.attributes = attributes
}
}

Expand Down Expand Up @@ -178,6 +181,7 @@ extension TargetSource: JSONObjectConvertible {
}

createIntermediateGroups = jsonDictionary.json(atKeyPath: "createIntermediateGroups")
attributes = jsonDictionary.json(atKeyPath: "attributes") ?? []
}
}

Expand Down
7 changes: 6 additions & 1 deletion Sources/XcodeGenKit/SourceGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class SourceGenerator {
func generateSourceFile(targetType: PBXProductType, targetSource: TargetSource, path: Path, buildPhase: TargetSource.BuildPhase? = nil) -> SourceFile {
let fileReference = fileReferencesByPath[path.string.lowercased()]!
var settings: [String: Any] = [:]
var attributes: [String] = targetSource.attributes
var chosenBuildPhase: TargetSource.BuildPhase?

let headerVisibility = targetSource.headerVisibility ?? .public
Expand Down Expand Up @@ -80,13 +81,17 @@ class SourceGenerator {
if chosenBuildPhase == .headers {
if headerVisibility != .project {
// Xcode doesn't write the default of project
settings["ATTRIBUTES"] = [headerVisibility.settingName]
attributes.append(headerVisibility.settingName)
}
}
if chosenBuildPhase == .sources && targetSource.compilerFlags.count > 0 {
settings["COMPILER_FLAGS"] = targetSource.compilerFlags.joined(separator: " ")
}

if !attributes.isEmpty {
settings["ATTRIBUTES"] = attributes
}

let buildFile = PBXBuildFile(file: fileReference, settings: settings.isEmpty ? nil : settings)
return SourceFile(
path: path,
Expand Down
32 changes: 32 additions & 0 deletions Tests/XcodeGenKitTests/SourceGeneratorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,38 @@ class SourceGeneratorTests: XCTestCase {
try pbxProj.expectFile(paths: ["../OtherDirectory", "Outside", "a.swift"], names: ["OtherDirectory", "Outside", "a.swift"], buildPhase: .sources)
try pbxProj.expectFile(paths: ["../OtherDirectory", "Outside", "Outside2", "b.swift"], names: ["OtherDirectory", "Outside", "Outside2", "b.swift"], buildPhase: .sources)
}

$0.it("correctly adds target source attributes") {
let directories = """
A:
- Intent.intentdefinition
"""
try createDirectories(directories)

let definition: String = "Intent.intentdefinition"

let target = Target(name: "Test", type: .framework, platform: .iOS, sources: [
TargetSource(path: "A/\(definition)", buildPhase: .sources, attributes: ["no_codegen"])
])
let project = Project(basePath: directoryPath, name: "Test", targets: [target])

let pbxProj = try project.generatePbxProj()

let fileReference = pbxProj.getFileReference(
paths: ["A", definition],
names: ["A", definition]
)
guard let buildFile = pbxProj.buildFiles
.first(where: { $0.file == fileReference }) else {
throw failure("Cant find build file")
}

try pbxProj.expectFile(paths: ["A", definition], buildPhase: .sources)

if (buildFile.settings! as NSDictionary) != (["ATTRIBUTES": ["no_codegen"]] as NSDictionary) {
throw failure("File does not contain no_codegen attribute")
}
}
}
}
}
Expand Down