Skip to content

Commit 7f7f636

Browse files
committed
Add flag to enable combined documentation support
This flag allows the targets to link to each other and creates an additional combined archive. rdar://116698361
1 parent 043ba3b commit 7f7f636

File tree

4 files changed

+76
-2
lines changed

4 files changed

+76
-2
lines changed

Plugins/Swift-DocC Convert/SwiftDocCConvert.swift

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import PackagePlugin
3030
}
3131

3232
let verbose = argumentExtractor.extractFlag(named: "verbose") > 0
33+
let isCombinedDocumentationEnabled = argumentExtractor.extractFlag(named: PluginFlag.enableCombinedDocumentationSupportFlagName) > 0
3334

3435
// Parse the given command-line arguments
3536
let parsedArguments = ParsedArguments(argumentExtractor.remainingArguments)
@@ -100,14 +101,22 @@ import PackagePlugin
100101
// arguments to pass to `docc`. ParsedArguments will merge the flags provided
101102
// by the user with default fallback values for required flags that were not
102103
// provided.
103-
let doccArguments = parsedArguments.doccArguments(
104+
var doccArguments = parsedArguments.doccArguments(
104105
action: .convert,
105106
targetKind: target.kind == .executable ? .executable : .library,
106107
doccCatalogPath: target.doccCatalogPath,
107108
targetName: target.name,
108109
symbolGraphDirectoryPath: symbolGraphs.unifiedSymbolGraphsDirectory.path,
109110
outputPath: doccArchiveOutputPath
110111
)
112+
if isCombinedDocumentationEnabled {
113+
doccArguments.append(CommandLineOption.enableExternalLinkSupport.defaultName)
114+
115+
for taskDependency in task.dependencies {
116+
let dependencyArchivePath = taskDependency.target.doccArchiveOutputPath(in: context)
117+
doccArguments.append(contentsOf: [CommandLineOption.externalLinkDependency.defaultName, dependencyArchivePath])
118+
}
119+
}
111120

112121
if verbose {
113122
let arguments = doccArguments.joined(separator: " ")
@@ -171,9 +180,31 @@ import PackagePlugin
171180
queue.addOperations(operations, waitUntilFinished: true)
172181

173182
if documentationArchives.count > 1 {
183+
documentationArchives = documentationArchives.sorted(by: { $0.lastPathComponent < $1.lastPathComponent })
184+
185+
if isCombinedDocumentationEnabled {
186+
// Merge the archives into a combined archive
187+
let combinedArchiveName = "Combined \(context.package.displayName) Documentation.doccarchive"
188+
let combinedArchiveOutput = URL(fileURLWithPath: context.pluginWorkDirectory.appending(combinedArchiveName).string)
189+
190+
var mergeCommandArguments = ["merge"]
191+
mergeCommandArguments.append(contentsOf: documentationArchives.map(\.standardizedFileURL.path))
192+
mergeCommandArguments.append(contentsOf: ["--output-path", combinedArchiveOutput.path])
193+
194+
// Remove the combined archive if it already exists
195+
try? FileManager.default.removeItem(at: combinedArchiveOutput)
196+
197+
// Create a new combined archive
198+
let process = try Process.run(doccExecutableURL, arguments: mergeCommandArguments)
199+
process.waitUntilExit()
200+
201+
// Display the combined archive before the other generated archives
202+
documentationArchives.insert(combinedArchiveOutput, at: 0)
203+
}
204+
174205
print("""
175206
Generated \(documentationArchives.count) DocC archives in '\(context.pluginWorkDirectory.string)':
176-
\(documentationArchives.map(\.lastPathComponent).sorted().joined(separator: "\n "))
207+
\(documentationArchives.map(\.lastPathComponent).joined(separator: "\n "))
177208
""")
178209
}
179210
}

Sources/SwiftDocCPluginUtilities/CommandLineOptions/CommandLineOption.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,15 @@ extension CommandLineOption {
5959
static let fallbackDefaultModuleKind = CommandLineOption(
6060
defaultName: "--fallback-default-module-kind"
6161
)
62+
63+
/// A DocC flag that enables support for linking to other DocC archives and enables
64+
/// other documentation builds to link to the generated DocC archive.
65+
static let enableExternalLinkSupport = CommandLineOption(
66+
defaultName: "--enable-experimental-external-link-support"
67+
)
68+
69+
/// A DocC flag that specifies a dependency DocC archive that the current build can link to.
70+
static let externalLinkDependency = CommandLineOption(
71+
defaultName: "--dependency"
72+
)
6273
}

Sources/SwiftDocCPluginUtilities/HelpInformation.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,17 @@ public enum HelpInformation {
4848
PluginFlag.skipSynthesizedSymbols
4949
]
5050

51+
let doccFeatures = (try? DocCFeatures(doccExecutable: doccExecutableURL)) ?? .init()
52+
5153
// stops 'not mutated' warning for Swift 5.7 and lower
5254
supportedPluginFlags += []
5355

5456
#if swift(>=5.8)
5557
supportedPluginFlags += [PluginFlag.extendedTypes]
5658
#endif
59+
if doccFeatures.contains(.linkDependencies) {
60+
supportedPluginFlags += [PluginFlag.enableCombinedDocumentationSupport]
61+
}
5762

5863
for flag in supportedPluginFlags {
5964
var flagListText = flag.positive.parsedValues.sorted().joined(separator: ", ")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// This source file is part of the Swift.org open source project
2+
//
3+
// Copyright (c) 2024 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See https://swift.org/LICENSE.txt for license information
7+
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
8+
9+
extension PluginFlag {
10+
/// Create a combined DocC archive containing documentation for all built targets.
11+
///
12+
/// - Note: This flag requires that the `docc` executable supports ``Feature/linkDependencies``.
13+
static let enableCombinedDocumentationSupport = PluginFlag(
14+
parsedValues: [
15+
"--\(enableCombinedDocumentationSupportFlagName)"
16+
],
17+
abstract: "Create a combined DocC archive with all generated documentation",
18+
description: """
19+
Experimental feature that allows targets to link to pages in their dependencies and that \
20+
creates an additional "combined" DocC archive containing all the generated documentation.
21+
""",
22+
argumentTransformation: { $0 }
23+
)
24+
25+
static let enableCombinedDocumentationSupportFlagName = "enable-experimental-combined-documentation"
26+
}
27+

0 commit comments

Comments
 (0)