Skip to content

[NFC] LLBuildManifest: add WriteAuxiliary.EntitlementPlist #6975

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

Merged
merged 2 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 10 additions & 0 deletions .swiftpm/xcode/xcshareddata/xcschemes/SwiftPM-Package.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,16 @@
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "LLBuildManifestTests"
BuildableName = "LLBuildManifestTests"
BlueprintName = "LLBuildManifestTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
4 changes: 4 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,10 @@ let package = Package(
name: "BuildTests",
dependencies: ["Build", "PackageModel", "SPMTestSupport"]
),
.testTarget(
name: "LLBuildManifestTests",
dependencies: ["Basics", "LLBuildManifest", "SPMTestSupport"]
),
.testTarget(
name: "WorkspaceTests",
dependencies: ["Workspace", "SPMTestSupport"]
Expand Down
43 changes: 40 additions & 3 deletions Sources/LLBuildManifest/BuildManifest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2014-2021 Apple Inc. and the Swift project authors
// Copyright (c) 2014-2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
Expand All @@ -22,7 +22,37 @@ public protocol AuxiliaryFileType {
}

public enum WriteAuxiliary {
public static let fileTypes: [AuxiliaryFileType.Type] = [LinkFileList.self, SourcesFileList.self, SwiftGetVersion.self, XCTestInfoPlist.self]
public static let fileTypes: [AuxiliaryFileType.Type] = [
EntitlementPlist.self,
LinkFileList.self,
SourcesFileList.self,
SwiftGetVersion.self,
XCTestInfoPlist.self
]

public struct EntitlementPlist: AuxiliaryFileType {
public static let name = "entitlement-plist"

public static func computeInputs(entitlement: String) -> [Node] {
[.virtual(Self.name), .virtual(entitlement)]
}

public static func getFileContents(inputs: [Node]) throws -> String {
guard let entitlementName = inputs.last?.extractedVirtualNodeName else {
throw Error.undefinedEntitlementName
}
let encoder = PropertyListEncoder()
encoder.outputFormat = .xml
let result = try encoder.encode([entitlementName: true])

let contents = String(decoding: result, as: UTF8.self)
return contents
}

private enum Error: Swift.Error {
case undefinedEntitlementName
}
}

public struct LinkFileList: AuxiliaryFileType {
public static let name = "link-file-list"
Expand Down Expand Up @@ -108,7 +138,7 @@ public enum WriteAuxiliary {
}

public static func getFileContents(inputs: [Node]) throws -> String {
guard let principalClass = inputs.last?.name.dropFirst().dropLast() else {
guard let principalClass = inputs.last?.extractedVirtualNodeName else {
throw Error.undefinedPrincipalClass
}

Expand Down Expand Up @@ -206,6 +236,13 @@ public struct BuildManifest {
commands[name] = Command(name: name, tool: tool)
}

public mutating func addEntitlementPlistCommand(entitlement: String, outputPath: AbsolutePath) {
let inputs = WriteAuxiliary.EntitlementPlist.computeInputs(entitlement: entitlement)
let tool = WriteAuxiliaryFile(inputs: inputs, outputFilePath: outputPath)
let name = outputPath.pathString
commands[name] = Command(name: name, tool: tool)
}

public mutating func addWriteLinkFileListCommand(
objects: [AbsolutePath],
linkFileListPath: AbsolutePath
Expand Down
8 changes: 7 additions & 1 deletion Sources/LLBuildManifest/Node.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2014-2019 Apple Inc. and the Swift project authors
// Copyright (c) 2014-2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
Expand Down Expand Up @@ -30,6 +30,12 @@ public struct Node: Hashable, Codable {
self.name = name
self.kind = kind
}

/// Extracts `name` property if this node was constructed as `Node//virtual`.
public var extractedVirtualNodeName: String {
precondition(kind == .virtual)
return String(self.name.dropFirst().dropLast())
}

public static func virtual(_ name: String) -> Node {
precondition(name.first != "<" && name.last != ">", "<> will be inserted automatically")
Expand Down
4 changes: 2 additions & 2 deletions Sources/LLBuildManifest/Tools.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2014-2021 Apple Inc. and the Swift project authors
// Copyright (c) 2014-2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
Expand Down Expand Up @@ -155,7 +155,7 @@ public struct ShellTool: ToolProtocol {
}
}

public struct WriteAuxiliaryFile: ToolProtocol {
public struct WriteAuxiliaryFile: Equatable, ToolProtocol {
public static let name: String = "write-auxiliary-file"

public let inputs: [Node]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,47 @@
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2014-2021 Apple Inc. and the Swift project authors
// Copyright (c) 2014-2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import Basics
import LLBuildManifest
import struct Basics.AbsolutePath
import class Foundation.PropertyListDecoder
@testable import LLBuildManifest
import SPMTestSupport
import class TSCBasic.InMemoryFileSystem
import XCTest

import class TSCBasic.InMemoryFileSystem

// FIXME: This should be in its own test target.
private let testEntitlement = "test-entitlement"

final class LLBuildManifestTests: XCTestCase {
func testEntitlementsPlist() throws {
let FileType = WriteAuxiliary.EntitlementPlist.self
let inputs = FileType.computeInputs(entitlement: testEntitlement)
XCTAssertEqual(inputs, [.virtual(FileType.name), .virtual(testEntitlement)])

let contents = try FileType.getFileContents(inputs: inputs)
let decoder = PropertyListDecoder()
let decodedEntitlements = try decoder.decode([String: Bool].self, from: .init(contents.utf8))
XCTAssertEqual(decodedEntitlements, [testEntitlement: true])

var manifest = BuildManifest()
let outputPath = AbsolutePath("/test.plist")
manifest.addEntitlementPlistCommand(entitlement: testEntitlement, outputPath: outputPath)

let commandName = outputPath.pathString
XCTAssertEqual(manifest.commands.count, 1)

let command = try XCTUnwrap(manifest.commands[commandName]?.tool as? WriteAuxiliaryFile)

XCTAssertEqual(command, .init(inputs: inputs, outputFilePath: outputPath))
}

func testBasics() throws {
var manifest = BuildManifest()

Expand Down