@@ -50,113 +50,123 @@ let exportFile: URL = {
50
50
51
51
52
52
// Find a name for the working directory
53
- let workingDirectory : String = {
53
+ let workingDirectory : URL = {
54
+ let tempDir = URL ( fileURLWithPath: NSTemporaryDirectory ( ) )
54
55
while true {
55
- let directory = " /tmp/Salsa/ \ (UUID ( ) . uuidString) "
56
- if !FileManager. default. fileExists ( atPath: directory) {
56
+ let directory = tempDir . appendingPathComponent ( UUID ( ) . uuidString, isDirectory : true )
57
+ if !FileManager. default. fileExists ( atPath: directory. path ) {
57
58
return directory
58
59
}
59
60
}
60
61
} ( )
61
62
63
+ func cleanupWorkingDirectory( ) {
64
+ try ? FileManager . default. removeItem ( at: workingDirectory)
65
+ }
66
+
67
+ func exit( withMessage message: String ) -> Never {
68
+ cleanupWorkingDirectory ( )
69
+ fatalError ( message)
70
+ }
71
+
62
72
// Create the working directory
63
73
do {
64
- try FileManager . default. createDirectory ( atPath : workingDirectory, withIntermediateDirectories: true , attributes: nil )
74
+ try FileManager . default. createDirectory ( at : workingDirectory, withIntermediateDirectories: true , attributes: nil )
65
75
} catch {
66
- fatalError ( " Failed to create directory: \( workingDirectory) " )
76
+ exit ( withMessage : " Failed to create directory: \( workingDirectory. path ) " )
67
77
}
68
78
69
79
// Clone images into the working directory
70
80
do {
71
- try FileManager . default. copyItem ( atPath : imagesDirectory. path , toPath : " \( workingDirectory) / images" )
81
+ try FileManager . default. copyItem ( at : imagesDirectory, to : workingDirectory. appendingPathComponent ( " images " , isDirectory : true ) )
72
82
} catch {
73
- fatalError ( " Failed to clone images directory: \( imagesDirectory) " )
83
+ exit ( withMessage : " Failed to clone images directory: \( imagesDirectory. path ) " )
74
84
}
75
85
76
86
// Read in the input file
77
87
let json = parseJsonFile ( at: filePath. path)
78
88
guard let document = Document ( json: json) else {
79
- fatalError ( " Failed to parse \( filePath. lastPathComponent) " )
89
+ exit ( withMessage : " Failed to parse \( filePath. lastPathComponent) " )
80
90
}
81
91
82
92
// Create /pages/ directory
83
- let pagesPath = " \( workingDirectory) / pages/ "
93
+ let pagesDirectory = workingDirectory. appendingPathComponent ( " pages " , isDirectory : true )
84
94
do {
85
- try FileManager . default. createDirectory ( atPath : pagesPath , withIntermediateDirectories: true , attributes: nil )
95
+ try FileManager . default. createDirectory ( at : pagesDirectory , withIntermediateDirectories: true , attributes: nil )
86
96
} catch {
87
- fatalError ( " Failed to create directory: \( pagesPath ) " )
97
+ exit ( withMessage : " Failed to create directory: \( pagesDirectory . path ) " )
88
98
}
89
99
90
100
// Configure identifiers for shared objects
91
101
IdentifierStore . configure ( with: document)
92
102
93
103
// Convert pages to json and save them to disk
94
104
document. pages. enumerated ( ) . forEach { index, page in
95
- guard let pageID = IdentifierStore . identifier ( forPageNamed: page. name) else { fatalError ( " Failed to create page \( index + 1 ) " ) }
105
+ guard let pageID = IdentifierStore . identifier ( forPageNamed: page. name) else { exit ( withMessage : " Failed to create page \( index + 1 ) " ) }
96
106
do {
97
- let url = NSURL . fileURL ( withPath : " \( workingDirectory ) /pages/ \( pageID) .json " )
98
- guard let pageJsonString = page. simplified ( ) . toSketchJson ( ) . toJsonString ( ) else { fatalError ( " Failed to parse page \( index + 1 ) " ) }
107
+ let url = pagesDirectory . appendingPathComponent ( " \( pageID) .json " )
108
+ guard let pageJsonString = page. simplified ( ) . toSketchJson ( ) . toJsonString ( ) else { exit ( withMessage : " Failed to parse page \( index + 1 ) " ) }
99
109
try pageJsonString. write ( to: url, atomically: false , encoding: String . Encoding. utf8)
100
110
} catch {
101
- fatalError ( " Failed to save page \( index + 1 ) " )
111
+ exit ( withMessage : " Failed to save page \( index + 1 ) " )
102
112
}
103
113
}
104
114
105
115
// Create document.json
106
- guard let documentJson = document. toSketchJson ( pageIds: document. pages. reversed ( ) . flatMap { IdentifierStore . identifier ( forPageNamed: $0. name) } ) . toJsonString ( ) else {
107
- fatalError ( " Failed to convert document to json " )
116
+ guard let documentJson = document. toSketchJson ( pageIds: document. pages. reversed ( ) . compactMap { IdentifierStore . identifier ( forPageNamed: $0. name) } ) . toJsonString ( ) else {
117
+ exit ( withMessage : " Failed to convert document to json " )
108
118
}
109
119
110
120
// Save document.json to disk
111
121
do {
112
- let url = NSURL . fileURL ( withPath : " \( workingDirectory ) / document.json" )
122
+ let url = workingDirectory . appendingPathComponent ( " document.json " )
113
123
try documentJson. write ( to: url, atomically: false , encoding: String . Encoding. utf8)
114
124
} catch {
115
- fatalError ( " Failed to save document.json to disk " )
125
+ exit ( withMessage : " Failed to save document.json to disk " )
116
126
}
117
127
118
128
// Create meta.json
119
129
guard let metaData = makeMetaData ( ) . toJsonString ( ) else {
120
- fatalError ( " Failed to generate meta.json " )
130
+ exit ( withMessage : " Failed to generate meta.json " )
121
131
}
122
132
123
133
// Save meta.json to disk
124
134
do {
125
- let url = NSURL . fileURL ( withPath : " \( workingDirectory ) / meta.json" )
135
+ let url = workingDirectory . appendingPathComponent ( " meta.json " )
126
136
try metaData. write ( to: url, atomically: false , encoding: String . Encoding. utf8)
127
137
} catch {
128
- fatalError ( " Failed to save meta.json " )
138
+ exit ( withMessage : " Failed to save meta.json " )
129
139
}
130
140
131
141
// Sketch requires that this file exists but it doesn't need to contain anything
132
142
// Its used to recover your position and state in the document on subsequent launches
133
143
do {
134
- let url = NSURL . fileURL ( withPath : " \( workingDirectory ) / user.json" )
144
+ let url = workingDirectory . appendingPathComponent ( " user.json " )
135
145
try [ String: Any] ( ) . toJsonString ( ) !. write ( to: url, atomically: false , encoding: String . Encoding. utf8)
136
146
} catch {
137
- fatalError ( " Failed to save user.json " )
147
+ exit ( withMessage : " Failed to save user.json " )
138
148
}
139
149
140
150
141
- let exportDirectory = exportFile. deletingLastPathComponent ( ) . path
151
+ let exportDirectory = exportFile. deletingLastPathComponent ( )
142
152
let exportFileName = exportFile. lastPathComponent
143
153
144
154
// Create the export directory if it doesn't exist
145
- if !FileManager. default. fileExists ( atPath: exportDirectory) {
155
+ if !FileManager. default. fileExists ( atPath: exportDirectory. path ) {
146
156
do {
147
- try FileManager . default. createDirectory ( atPath : exportDirectory, withIntermediateDirectories: true , attributes: nil )
157
+ try FileManager . default. createDirectory ( at : exportDirectory, withIntermediateDirectories: true , attributes: nil )
148
158
} catch {
149
- fatalError ( " Failed to create directory: \( exportDirectory) " )
159
+ exit ( withMessage : " Failed to create directory: \( exportDirectory. path ) " )
150
160
}
151
161
}
152
162
153
163
// Swift doesn't come with zipping utilities. Instead of adding one as a dependency we just use bash to zip our exported files into a sketch file
154
- guard bash ( command: " zip " , arguments: [ " -r " , " \( exportDirectory) / \( exportFileName) " , " ./ " ] , directory: workingDirectory) . returnCode == 0 else {
155
- fatalError ( " Failed to create zipped .sketch file. Do you have zip installed? " )
164
+ guard bash ( command: " zip " , arguments: [ " -r " , " \( exportDirectory. path ) / \( exportFileName) " , " ./ " ] , directory: workingDirectory. path ) . returnCode == 0 else {
165
+ exit ( withMessage : " Failed to create zipped .sketch file. Do you have zip installed? " )
156
166
}
157
167
158
168
// Clean up our working directory
159
- try ? FileManager . default . removeItem ( atPath : workingDirectory )
169
+ cleanupWorkingDirectory ( )
160
170
161
171
print ( " (☞゚ヮ゚)☞ Generated \( exportFile. path) ☜(゚ヮ゚☜) " )
162
172
0 commit comments