Skip to content
Open
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
34 changes: 27 additions & 7 deletions Plugins/Swift-DocC Convert/SwiftDocCConvert.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,18 @@ import PackagePlugin

let intermediateArchivesDirectory = URL(fileURLWithPath: context.pluginWorkDirectory.appending("intermediates").string)
try? FileManager.default.createDirectory(at: intermediateArchivesDirectory, withIntermediateDirectories: true)


// An inner function that configures the process running docc executable with the given
// process and environment values.
func configureDoccProcess(arguments: [String], environment: [String: String]) -> Process {
let process = Process()
process.executableURL = doccExecutableURL
process.arguments = arguments
process.environment = ProcessInfo.processInfo.environment
.merging(environment) { _, new in new }
return process
}

// An inner function that defines the work to build documentation for a given target.
func performBuildTask(_ task: DocumentationBuildGraph<SourceModuleDocumentationBuildGraphTarget>.Task) throws -> URL? {
let target = task.target
Expand Down Expand Up @@ -128,16 +139,20 @@ import PackagePlugin
dependencyArchivePaths: dependencyArchivePaths
)

let doccEnvironment = parsedArguments.doccEnvironment()

if verbose {
let arguments = doccArguments.joined(separator: " ")
print("docc invocation: '\(doccExecutableURL.path) \(arguments)'")
print("add'l environment: '\(doccEnvironment)'")
}

print("Building documentation for '\(target.name)'...")
let conversionStartTime = DispatchTime.now()

// Run `docc convert` with the generated arguments and wait until the process completes
let process = try Process.run(doccExecutableURL, arguments: doccArguments)
let process = configureDoccProcess(arguments: doccArguments, environment: doccEnvironment)
try process.run()
process.waitUntilExit()

// Check whether the `docc convert` invocation was successful.
Expand Down Expand Up @@ -221,14 +236,19 @@ import PackagePlugin

// Remove the combined archive if it already exists
try? FileManager.default.removeItem(at: combinedArchiveOutput)


let remainingArguments = mergeCommandArguments.remainingArguments
let doccEnvironment = parsedArguments.doccEnvironment()

if verbose {
let arguments = mergeCommandArguments.remainingArguments.joined(separator: " ")
let arguments = remainingArguments.joined(separator: " ")
print("docc invocation: '\(doccExecutableURL.path) \(arguments)'")
print("add'l environment: '\(doccEnvironment)'")
}

// Create a new combined archive
let process = try Process.run(doccExecutableURL, arguments: mergeCommandArguments.remainingArguments)
let process = configureDoccProcess(arguments: remainingArguments, environment: doccEnvironment)
try process.run()
process.waitUntilExit()

print("""
Expand Down
12 changes: 8 additions & 4 deletions Plugins/Swift-DocC Preview/SwiftDocCPreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,22 @@ import PackagePlugin
symbolGraphDirectoryPath: symbolGraphs.unifiedSymbolGraphsDirectory.path,
outputPath: parsedArguments.outputDirectory?.path ?? target.doccArchiveOutputPath(in: context)
)


let doccEnvironment = parsedArguments.doccEnvironment()

if verbose {
let arguments = doccArguments.joined(separator: " ")
print("docc invocation: '\(doccExecutableURL.path) \(arguments)'")
print("add'l environment: '\(doccEnvironment)'")
}

// Configure the `docc preview` process with the generated arguments
// Configure the `docc preview` process with the generated arguments and environment.
let previewProcess = Process()
previewProcess.executableURL = doccExecutableURL
previewProcess.arguments = doccArguments


previewProcess.environment = ProcessInfo.processInfo.environment
.merging(doccEnvironment) { _, new in new }

func stopPreviewProcess() {
#if canImport(Darwin)
previewProcess.interrupt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import Foundation
struct ParsedPluginArguments {
var enableCombinedDocumentation: Bool
var disableLMDBIndex: Bool
var jsonPrettyPrint: Bool
var verbose: Bool
var help: Bool

/// Creates a new plugin arguments container by extracting the known plugin values from a command line argument list.
init(extractingFrom arguments: inout CommandLineArguments) {
enableCombinedDocumentation = arguments.extractFlag(.enableCombinedDocumentation) ?? false
disableLMDBIndex = arguments.extractFlag(.disableLMDBIndex) ?? false
jsonPrettyPrint = arguments.extractFlag(.jsonPrettyPrint) ?? false
verbose = arguments.extractFlag(.verbose) ?? false
help = arguments.extract(Self.help).last ?? false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ extension DocumentedArgument {
"""
)

/// A plugin feature flag to enable pretty-printed and sorted JSON output.
static let jsonPrettyPrint = Self(
flag: .init(preferred: "--json-prettyprint"),
abstract: "Pretty-print the JSON output of the documentation archive.",
discussion: """
Formats the JSON files in the documentation archive with spacing, indentation, and sorted \
keys for a deterministic output.
"""
)

/// A plugin feature flag to enable verbose logging.
static let verbose = Self(
flag: .init(preferred: "--verbose"),
Expand Down
1 change: 1 addition & 0 deletions Sources/SwiftDocCPluginUtilities/HelpInformation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public enum HelpInformation {

var supportedPluginFlags = [
DocumentedArgument.disableLMDBIndex,
DocumentedArgument.jsonPrettyPrint,
DocumentedArgument.verbose,
]

Expand Down
14 changes: 14 additions & 0 deletions Sources/SwiftDocCPluginUtilities/ParsedArguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@ struct ParsedArguments {

return [action.rawValue] + arguments.remainingArguments
}


/// Returns the enviroment values that should be set in the `docc` process.
///
/// The returned dictionary contains settings for the `docc` executable that are configured
/// through the process environment, instead of command-line arguments. Merge the values in the
/// dictionary to the process environment running the `docc` executable.
func doccEnvironment() -> [String: String] {
var environment: [String: String] = [:]
if pluginArguments.jsonPrettyPrint {
environment["DOCC_JSON_PRETTYPRINT"] = "YES"
}
return environment
}
}

enum DocCArguments {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ final class HelpInformationTests: XCTestCase {
--disable-indexing, --no-indexing
Disable indexing for the produced DocC archive.
Produces a DocC archive that is best-suited for hosting online but incompatible with Xcode.
--json-prettyprint Pretty-print the JSON output of the documentation archive.
Formats the JSON files in the documentation archive with spacing, indentation, and sorted keys for a deterministic output.
--verbose Increase verbosity to include informational output.

SYMBOL GRAPH OPTIONS:
Expand Down Expand Up @@ -187,6 +189,8 @@ final class HelpInformationTests: XCTestCase {
--disable-indexing, --no-indexing
Disable indexing for the produced DocC archive.
Produces a DocC archive that is best-suited for hosting online but incompatible with Xcode.
--json-prettyprint Pretty-print the JSON output of the documentation archive.
Formats the JSON files in the documentation archive with spacing, indentation, and sorted keys for a deterministic output.
--verbose Increase verbosity to include informational output.

SYMBOL GRAPH OPTIONS:
Expand Down
43 changes: 42 additions & 1 deletion Tests/SwiftDocCPluginUtilitiesTests/ParsedArgumentsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ final class ParsedArgumentsTests: XCTestCase {
"--output-path", "/my/output-path"
]
)

XCTAssertEqual(arguments.doccEnvironment(), [:])
}

func testDocCArgumentsForOneArgument() {
Expand Down Expand Up @@ -444,7 +446,46 @@ final class ParsedArgumentsTests: XCTestCase {
XCTAssertFalse(doccArguments.contains("--include-extended-types"))
XCTAssertFalse(doccArguments.contains("--experimental-skip-synthesized-symbols"))
}


func testDoccEnvironmentWithJSONPrettyPrint() {
let prettyPrintArguments = ParsedArguments(
["--json-prettyprint"]
)

XCTAssertTrue(prettyPrintArguments.pluginArguments.jsonPrettyPrint)

XCTAssertEqual(
prettyPrintArguments.doccEnvironment(),
["DOCC_JSON_PRETTYPRINT": "YES"]
)

XCTAssertEqual(
prettyPrintArguments.doccArguments(
action: .convert,
targetKind: .library,
doccCatalogPath: "/my/catalog.docc",
targetName: "MyTarget",
symbolGraphDirectoryPath: "/my/symbol-graph",
outputPath: "/my/output-path"
),
[
"convert",
"/my/catalog.docc",
"--emit-lmdb-index",
"--fallback-display-name", "MyTarget",
"--fallback-bundle-identifier", "MyTarget",
"--additional-symbol-graph-dir", "/my/symbol-graph",
"--output-path", "/my/output-path"
]
)


let defaultArguments = ParsedArguments([])

XCTAssertFalse(defaultArguments.pluginArguments.jsonPrettyPrint)
XCTAssertEqual(defaultArguments.doccEnvironment(), [:])
}

func testSymbolGraphArguments() {
do {
let arguments = ParsedArguments(["--include-extended-types", "--experimental-skip-synthesized-symbols", "--symbol-graph-minimum-access-level", "internal"])
Expand Down