@@ -38,7 +38,11 @@ public struct ConvertAction: Action, RecreatingContext {
38
38
let documentationCoverageOptions : DocumentationCoverageOptions
39
39
let diagnosticLevel : DiagnosticSeverity
40
40
let diagnosticEngine : DiagnosticEngine
41
-
41
+
42
+ let transformForStaticHosting : Bool
43
+ let hostingBasePath : String ?
44
+
45
+
42
46
private( set) var context : DocumentationContext {
43
47
didSet {
44
48
// current platforms?
@@ -88,7 +92,10 @@ public struct ConvertAction: Action, RecreatingContext {
88
92
diagnosticEngine: DiagnosticEngine ? = nil ,
89
93
emitFixits: Bool = false ,
90
94
inheritDocs: Bool = false ,
91
- experimentalEnableCustomTemplates: Bool = false ) throws
95
+ experimentalEnableCustomTemplates: Bool = false ,
96
+ transformForStaticHosting: Bool = false ,
97
+ hostingBasePath: String ? = nil
98
+ ) throws
92
99
{
93
100
self . rootURL = documentationBundleURL
94
101
self . outOfProcessResolver = outOfProcessResolver
@@ -101,7 +108,9 @@ public struct ConvertAction: Action, RecreatingContext {
101
108
self . injectedDataProvider = dataProvider
102
109
self . fileManager = fileManager
103
110
self . documentationCoverageOptions = documentationCoverageOptions
104
-
111
+ self . transformForStaticHosting = transformForStaticHosting
112
+ self . hostingBasePath = hostingBasePath
113
+
105
114
let filterLevel : DiagnosticSeverity
106
115
if analyze {
107
116
filterLevel = . information
@@ -189,7 +198,9 @@ public struct ConvertAction: Action, RecreatingContext {
189
198
diagnosticEngine: DiagnosticEngine ? = nil ,
190
199
emitFixits: Bool = false ,
191
200
inheritDocs: Bool = false ,
192
- experimentalEnableCustomTemplates: Bool = false
201
+ experimentalEnableCustomTemplates: Bool = false ,
202
+ transformForStaticHosting: Bool ,
203
+ hostingBasePath: String ?
193
204
) throws {
194
205
// Note: This public initializer exists separately from the above internal one
195
206
// because the FileManagerProtocol type we use to enable mocking in tests
@@ -217,7 +228,9 @@ public struct ConvertAction: Action, RecreatingContext {
217
228
diagnosticEngine: diagnosticEngine,
218
229
emitFixits: emitFixits,
219
230
inheritDocs: inheritDocs,
220
- experimentalEnableCustomTemplates: experimentalEnableCustomTemplates
231
+ experimentalEnableCustomTemplates: experimentalEnableCustomTemplates,
232
+ transformForStaticHosting: transformForStaticHosting,
233
+ hostingBasePath: hostingBasePath
221
234
)
222
235
}
223
236
@@ -240,7 +253,7 @@ public struct ConvertAction: Action, RecreatingContext {
240
253
mutating func cancel( ) throws {
241
254
/// If the action is not running, there is nothing to cancel
242
255
guard isPerforming. sync ( { $0 } ) == true else { return }
243
-
256
+
244
257
/// If the action is already cancelled throw `cancelPending`.
245
258
if isCancelled. sync ( { $0 } ) == true {
246
259
throw Error . cancelPending
@@ -278,6 +291,28 @@ public struct ConvertAction: Action, RecreatingContext {
278
291
let temporaryFolder = try createTempFolder (
279
292
with: htmlTemplateDirectory)
280
293
294
+ var indexHTMLData : Data ?
295
+
296
+ // The `template-index.html` is a duplicate version of `index.html` with extra template
297
+ // tokens that allow for customizing the base-path.
298
+ // If a base bath is provided we will transform the template using the base path
299
+ // to produce a replacement index.html file.
300
+ // After any required transforming has been done the template file will be removed.
301
+ let templateURL : URL = temporaryFolder. appendingPathComponent ( HTMLTemplate . templateFileName. rawValue)
302
+ if fileManager. fileExists ( atPath: templateURL. path) {
303
+ // If the `transformForStaticHosting` is not set but there is a `hostingBasePath`
304
+ // then transform the index template
305
+ if !transformForStaticHosting,
306
+ let hostingBasePath = hostingBasePath,
307
+ !hostingBasePath. isEmpty {
308
+ indexHTMLData = try StaticHostableTransformer . transformHTMLTemplate ( htmlTemplate: temporaryFolder, hostingBasePath: hostingBasePath)
309
+ let indexURL = temporaryFolder. appendingPathComponent ( HTMLTemplate . indexFileName. rawValue)
310
+ try indexHTMLData!. write ( to: indexURL)
311
+ }
312
+
313
+ try fileManager. removeItem ( at: templateURL)
314
+ }
315
+
281
316
defer {
282
317
try ? fileManager. removeItem ( at: temporaryFolder)
283
318
}
@@ -330,15 +365,26 @@ public struct ConvertAction: Action, RecreatingContext {
330
365
allProblems. append ( contentsOf: indexerProblems)
331
366
}
332
367
368
+ // Process Static Hosting as needed.
369
+ if transformForStaticHosting, let templateDirectory = htmlTemplateDirectory {
370
+ if indexHTMLData == nil {
371
+ indexHTMLData = try StaticHostableTransformer . transformHTMLTemplate ( htmlTemplate: templateDirectory, hostingBasePath: hostingBasePath)
372
+ }
373
+
374
+ let dataProvider = try LocalFileSystemDataProvider ( rootURL: temporaryFolder. appendingPathComponent ( NodeURLGenerator . Path. dataFolderName) )
375
+ let transformer = StaticHostableTransformer ( dataProvider: dataProvider, fileManager: fileManager, outputURL: temporaryFolder, indexHTMLData: indexHTMLData!)
376
+ try transformer. transform ( )
377
+ }
378
+
333
379
// We should generally only replace the current build output if we didn't encounter errors
334
380
// during conversion. However, if the `emitDigest` flag is true,
335
381
// we should replace the current output with our digest of problems.
336
382
if !allProblems. containsErrors || emitDigest {
337
383
try moveOutput ( from: temporaryFolder, to: targetDirectory)
338
384
}
339
-
385
+
340
386
// Log the output size.
341
- benchmark ( add: Benchmark . OutputSize ( dataURL: targetDirectory. appendingPathComponent ( " data " ) ) )
387
+ benchmark ( add: Benchmark . OutputSize ( dataURL: targetDirectory. appendingPathComponent ( NodeURLGenerator . Path . dataFolderName ) ) )
342
388
343
389
if Benchmark . main. isEnabled {
344
390
// Write the benchmark files directly in the target directory.
@@ -363,6 +409,7 @@ public struct ConvertAction: Action, RecreatingContext {
363
409
}
364
410
365
411
func createTempFolder( with templateURL: URL ? ) throws -> URL {
412
+
366
413
let targetURL = URL ( fileURLWithPath: NSTemporaryDirectory ( ) )
367
414
. appendingPathComponent ( ProcessInfo . processInfo. globallyUniqueString)
368
415
0 commit comments