11/*
22 This source file is part of the Swift.org open source project
33
4- Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
4+ Copyright (c) 2021-2025 Apple Inc. and the Swift project authors
55 Licensed under Apache License v2.0 with Runtime Library Exception
66
77 See https://swift.org/LICENSE.txt for license information
@@ -15,7 +15,6 @@ import SwiftDocC
1515///
1616/// The render node writer writes the JSON files into a hierarchy of folders and subfolders based on the relative URL for each node.
1717class JSONEncodingRenderNodeWriter {
18- private let renderNodeURLGenerator : NodeURLGenerator
1918 private let targetFolder : URL
2019 private let transformForStaticHostingIndexHTML : URL ?
2120 private let fileManager : any FileManagerProtocol
@@ -27,9 +26,6 @@ class JSONEncodingRenderNodeWriter {
2726 /// - targetFolder: The folder to which the writer object writes the files.
2827 /// - fileManager: The file manager with which the writer object writes data to files.
2928 init ( targetFolder: URL , fileManager: any FileManagerProtocol , transformForStaticHostingIndexHTML: URL ? ) {
30- self . renderNodeURLGenerator = NodeURLGenerator (
31- baseURL: targetFolder. appendingPathComponent ( " data " , isDirectory: true )
32- )
3329 self . targetFolder = targetFolder
3430 self . transformForStaticHostingIndexHTML = transformForStaticHostingIndexHTML
3531 self . fileManager = fileManager
@@ -52,34 +48,11 @@ class JSONEncodingRenderNodeWriter {
5248 lowercased: true
5349 )
5450
55- // The path on disk to write the render node JSON file at.
56- let renderNodeTargetFileURL = renderNodeURLGenerator
57- . urlForReference (
58- renderNode. identifier,
59- fileSafePath: fileSafePath
60- )
61- . appendingPathExtension ( " json " )
62-
63- let renderNodeTargetFolderURL = renderNodeTargetFileURL. deletingLastPathComponent ( )
64-
65- // On Linux sometimes it takes a moment for the directory to be created and that leads to
66- // errors when trying to write files concurrently in the same target location.
67- // We keep an index in `directoryIndex` and create new sub-directories as needed.
68- // When the symbol's directory already exists no code is executed during the lock below
69- // besides the set lookup.
70- try directoryIndex. sync { directoryIndex in
71- let ( insertedRenderNodeTargetFolderURL, _) = directoryIndex. insert ( renderNodeTargetFolderURL)
72- if insertedRenderNodeTargetFolderURL {
73- try fileManager. createDirectory (
74- at: renderNodeTargetFolderURL,
75- withIntermediateDirectories: true ,
76- attributes: nil
77- )
78- }
79- }
80-
81- let data = try renderNode. encodeToJSON ( with: encoder, renderReferenceCache: renderReferenceCache)
82- try fileManager. createFile ( at: renderNodeTargetFileURL, contents: data, options: nil )
51+ try write (
52+ renderNode. encodeToJSON ( with: encoder, renderReferenceCache: renderReferenceCache) ,
53+ // The path on disk to write the render node JSON file at.
54+ toFileSafePath: " data/ \( fileSafePath) .json "
55+ )
8356
8457 guard let indexHTML = transformForStaticHostingIndexHTML else {
8558 return
@@ -115,4 +88,28 @@ class JSONEncodingRenderNodeWriter {
11588 try fileManager. _copyItem ( at: indexHTML, to: htmlTargetFileURL)
11689 }
11790 }
91+
92+ func write( _ data: Data , toFileSafePath fileSafePath: String ) throws {
93+ // The path on disk to write the data at.
94+ let fileURL = targetFolder. appendingPathComponent ( fileSafePath, isDirectory: false )
95+ let containingFolderURL = fileURL. deletingLastPathComponent ( )
96+
97+ // On Linux sometimes it takes a moment for the directory to be created and that leads to
98+ // errors when trying to write files concurrently in the same target location.
99+ // We keep an index in `directoryIndex` and create new sub-directories as needed.
100+ // When the symbol's directory already exists no code is executed during the lock below
101+ // besides the set lookup.
102+ try directoryIndex. sync { directoryIndex in
103+ let ( insertedRenderNodeTargetFolderURL, _) = directoryIndex. insert ( containingFolderURL)
104+ if insertedRenderNodeTargetFolderURL {
105+ try fileManager. createDirectory (
106+ at: containingFolderURL,
107+ withIntermediateDirectories: true ,
108+ attributes: nil
109+ )
110+ }
111+ }
112+
113+ try fileManager. createFile ( at: fileURL, contents: data, options: nil )
114+ }
118115}
0 commit comments