@@ -38,8 +38,6 @@ public final class PreviewAction: AsyncAction {
38
38
static var allowConcurrentPreviews = false
39
39
40
40
private let printHTMLTemplatePath : Bool
41
-
42
- var logHandle = LogHandle . standardOutput
43
41
44
42
let port : Int
45
43
@@ -89,17 +87,17 @@ public final class PreviewAction: AsyncAction {
89
87
///
90
88
/// - Parameter logHandle: The file handle that the convert and preview actions will print debug messages to.
91
89
public func perform( logHandle: inout LogHandle ) async throws -> ActionResult {
92
- self . logHandle = logHandle
90
+ self . logHandle. sync { $0 = logHandle }
93
91
94
92
if let rootURL = convertAction. rootURL {
95
- print ( " Input: \( rootURL. path) " , to : & self . logHandle )
93
+ print ( " Input: \( rootURL. path) " )
96
94
}
97
95
// TODO: This never did output human readable string; rdar://74324255
98
96
// print("Input: \(convertAction.documentationCoverageOptions)", to: &self.logHandle)
99
97
100
98
// In case a developer is using a custom template log its path.
101
99
if printHTMLTemplatePath, let htmlTemplateDirectory = convertAction. htmlTemplateDirectory {
102
- print ( " Template: \( htmlTemplateDirectory. path) " , to : & self . logHandle )
100
+ print ( " Template: \( htmlTemplateDirectory. path) " )
103
101
}
104
102
105
103
let previewResult = try await preview ( )
@@ -124,15 +122,16 @@ public final class PreviewAction: AsyncAction {
124
122
let previewResult : ActionResult
125
123
// Preview the output and monitor the source bundle for changes.
126
124
do {
127
- print ( String ( repeating: " = " , count: 40 ) , to : & logHandle )
125
+ print ( String ( repeating: " = " , count: 40 ) )
128
126
if let previewURL = URL ( string: " http://localhost: \( port) " ) {
129
- print ( " Starting Local Preview Server " , to : & logHandle )
127
+ print ( " Starting Local Preview Server " )
130
128
printPreviewAddresses ( base: previewURL)
131
- print ( String ( repeating: " = " , count: 40 ) , to : & logHandle )
129
+ print ( String ( repeating: " = " , count: 40 ) )
132
130
}
133
131
134
132
let to : PreviewServer . Bind = bindServerToSocketPath. map { . socket( path: $0) } ?? . localhost( port: port)
135
- servers [ serverIdentifier] = try PreviewServer ( contentURL: convertAction. targetDirectory, bindTo: to, logHandle: & logHandle)
133
+ var logHandleCopy = logHandle. sync { $0 }
134
+ servers [ serverIdentifier] = try PreviewServer ( contentURL: convertAction. targetDirectory, bindTo: to, logHandle: & logHandleCopy)
136
135
137
136
// When the user stops docc - stop the preview server first before exiting.
138
137
trapSignals ( )
@@ -159,7 +158,8 @@ public final class PreviewAction: AsyncAction {
159
158
160
159
func convert( ) async throws -> ActionResult {
161
160
convertAction = try createConvertAction ( )
162
- let ( result, context) = try await convertAction. perform ( logHandle: & logHandle)
161
+ var logHandleCopy = logHandle. sync { $0 }
162
+ let ( result, context) = try await convertAction. perform ( logHandle: & logHandleCopy)
163
163
164
164
previewPaths = try context. previewPaths ( )
165
165
return result
@@ -168,15 +168,23 @@ public final class PreviewAction: AsyncAction {
168
168
private func printPreviewAddresses( base: URL ) {
169
169
// If the preview paths are empty, just print the base.
170
170
let firstPath = previewPaths. first ?? " "
171
- print ( " \t Address: \( base. appendingPathComponent ( firstPath) . absoluteString) " , to : & logHandle )
171
+ print ( " \t Address: \( base. appendingPathComponent ( firstPath) . absoluteString) " )
172
172
173
173
let spacing = String ( repeating: " " , count: " Address: " . count)
174
174
for previewPath in previewPaths. dropFirst ( ) {
175
- print ( " \t \( spacing) \( base. appendingPathComponent ( previewPath) . absoluteString) " , to : & logHandle )
175
+ print ( " \t \( spacing) \( base. appendingPathComponent ( previewPath) . absoluteString) " )
176
176
}
177
177
}
178
178
179
- var monitoredConvertTask : Task < Void , Never > ?
179
+ private var logHandle : Synchronized < LogHandle > = . init( . none)
180
+
181
+ fileprivate func print( _ string: String , terminator: String = " \n " ) {
182
+ logHandle. sync { logHandle in
183
+ Swift . print ( string, terminator: terminator, to: & logHandle)
184
+ }
185
+ }
186
+
187
+ fileprivate var monitoredConvertTask : Task < Void , Never > ?
180
188
}
181
189
182
190
// Monitoring a source folder: Asynchronous output reading and file system events are supported only on macOS.
@@ -192,38 +200,27 @@ extension PreviewAction {
192
200
}
193
201
194
202
monitor = try DirectoryMonitor ( root: rootURL) { _, _ in
195
- print ( " Source bundle was modified, converting... " , terminator: " " , to : & self . logHandle )
203
+ self . print ( " Source bundle was modified, converting... " , terminator: " " )
196
204
self . monitoredConvertTask? . cancel ( )
197
205
self . monitoredConvertTask = Task {
198
- defer {
199
- // Reload the directory contents and start to monitor for changes.
200
- do {
201
- try monitor. restart ( )
202
- } catch {
203
- // The file watching system API has thrown, stop watching.
204
- print ( " Watching for changes has failed. To continue preview with watching restart docc. " , to: & self . logHandle)
205
- print ( error. localizedDescription, to: & self . logHandle)
206
- }
207
- }
208
-
209
206
do {
210
207
let result = try await self . convert ( )
211
208
if result. didEncounterError {
212
209
throw ErrorsEncountered ( )
213
210
}
214
- print ( " Done. " , to : & self . logHandle )
211
+ self . print ( " Done. " )
215
212
} catch DocumentationContext . ContextError . registrationDisabled {
216
213
// The context cancelled loading the bundles and threw to yield execution early.
217
- print ( " \n Conversion cancelled... " , to : & self . logHandle )
214
+ self . print ( " \n Conversion cancelled... " )
218
215
} catch is CancellationError {
219
- print ( " \n Conversion cancelled... " , to : & self . logHandle )
216
+ self . print ( " \n Conversion cancelled... " )
220
217
} catch {
221
- print ( " \n \( error. localizedDescription) \n Compilation failed " , to : & self . logHandle )
218
+ self . print ( " \n \( error. localizedDescription) \n Compilation failed " )
222
219
}
223
220
}
224
221
}
225
222
try monitor. start ( )
226
- print ( " Monitoring \( rootURL. path) for changes... " , to : & self . logHandle )
223
+ self . print ( " Monitoring \( rootURL. path) for changes... " )
227
224
}
228
225
}
229
226
#endif // !os(Linux) && !os(Android)
0 commit comments