99*/
1010
1111import Foundation
12+ import SymbolKit
1213
1314extension DocumentationContext {
1415
@@ -160,11 +161,79 @@ extension DocumentationContext.InputsProvider {
160161 }
161162}
162163
164+ // MARK: Create without catalog
165+
166+ extension DocumentationContext . InputsProvider {
167+ /// Creates a collection of documentation inputs from the symbol graph files and other command line options.
168+ ///
169+ /// - Parameter options: Options to configure how the provider creates the documentation inputs.
170+ /// - Returns: Inputs that categorize the files of the given catalog.
171+ package func makeInputsFromSymbolGraphs( options: Options ) throws -> DocumentationContext . Inputs ? {
172+ guard !options. additionalSymbolGraphFiles. isEmpty else {
173+ return nil
174+ }
175+
176+ // Find all the unique module names from the symbol graph files and generate a top level module page for each of them.
177+ var moduleNames = Set < String > ( )
178+ for url in options. additionalSymbolGraphFiles {
179+ let data = try fileManager. contents ( of: url)
180+ let container = try JSONDecoder ( ) . decode ( SymbolGraphModuleContainer . self, from: data)
181+ moduleNames. insert ( container. module. name)
182+ }
183+ let derivedDisplayName = moduleNames. count == 1 ? moduleNames. first : nil
184+
185+ let info = try DocumentationContext . Inputs. Info ( bundleDiscoveryOptions: options, derivedDisplayName: derivedDisplayName)
186+
187+ var topLevelPages : [ URL ] = [ ]
188+ if moduleNames. count == 1 , let moduleName = moduleNames. first, moduleName != info. displayName {
189+ let tempURL = fileManager. uniqueTemporaryDirectory ( )
190+ try ? fileManager. createDirectory ( at: tempURL, withIntermediateDirectories: true , attributes: nil )
191+
192+ let url = tempURL. appendingPathComponent ( " \( moduleName) .md " )
193+ topLevelPages. append ( url)
194+ try fileManager. createFile (
195+ at: url,
196+ contents: Data ( """
197+ # `` \( moduleName) ``
198+
199+ @Metadata {
200+ @DisplayName( " \( info. displayName) " )
201+ }
202+ """ . utf8) ,
203+ options: . atomic
204+ )
205+ }
206+
207+ return DocumentationBundle (
208+ info: info,
209+ symbolGraphURLs: options. additionalSymbolGraphFiles,
210+ markupURLs: topLevelPages,
211+ miscResourceURLs: [ ]
212+ )
213+ }
214+ }
215+
216+ /// A wrapper type that decodes only the module in the symbol graph.
217+ private struct SymbolGraphModuleContainer : Decodable {
218+ /// The decoded symbol graph module.
219+ let module : SymbolGraph . Module
220+
221+ typealias CodingKeys = SymbolGraph . CodingKeys
222+
223+ public init ( from decoder: Decoder ) throws {
224+ let container = try decoder. container ( keyedBy: CodingKeys . self)
225+
226+ self . module = try container. decode ( SymbolGraph . Module. self, forKey: . module)
227+ }
228+ }
229+
163230// MARK: Discover and create
164231
165232extension DocumentationContext . InputsProvider {
166233 /// Traverses the file system from the given starting point to find a documentation catalog and creates a collection of documentation inputs from that catalog.
167234 ///
235+ /// If the provider can't find a catalog, it will try to create documentation inputs from the option's symbol graph files.
236+ ///
168237 /// - Parameters:
169238 /// - startingPoint: The top of the directory hierarchy that the provider traverses to find a documentation catalog.
170239 /// - allowArbitraryCatalogDirectories: Whether to treat the starting point as a documentation catalog if the provider doesn't find an actual catalog on the file system.
@@ -176,8 +245,10 @@ extension DocumentationContext.InputsProvider {
176245 allowArbitraryCatalogDirectories: Bool = false ,
177246 options: Options
178247 ) throws -> DocumentationContext . Inputs ? {
179- try findCatalog ( startingPoint: startingPoint, allowArbitraryCatalogDirectories: allowArbitraryCatalogDirectories) . map {
180- try makeInputs ( contentOf: $0, options: options)
248+ if let catalogURL = try findCatalog ( startingPoint: startingPoint, allowArbitraryCatalogDirectories: allowArbitraryCatalogDirectories) {
249+ try makeInputs ( contentOf: catalogURL, options: options)
250+ } else {
251+ try makeInputsFromSymbolGraphs ( options: options)
181252 }
182253 }
183254}
0 commit comments