|
1 | 1 | import FigmaExportCore |
2 | 2 | import Foundation |
| 3 | +import Logging |
3 | 4 |
|
4 | 5 | /// SVG to XML converter |
5 | 6 | final class VectorDrawableConverter { |
| 7 | + private static let notSupportedWarning = "is not supported" |
| 8 | + private let logger = Logger(label: "com.redmadrobot.figma-export.vector-drawable-converter") |
| 9 | + |
6 | 10 | /// Converts SVG files to XML |
| 11 | + /// In case unsupported XML-Tags are reported, the converting command will be executed for each file for better logging. |
7 | 12 | /// - Parameter inputDirectoryUrl: Url to directory with SVG files |
8 | 13 | func convert(inputDirectoryUrl: URL) throws { |
9 | | - let enumerator = FileManager.default.enumerator(at: inputDirectoryUrl, includingPropertiesForKeys: nil) |
10 | | - |
11 | | - while let file = enumerator?.nextObject() as? URL { |
12 | | - guard file.pathExtension == "svg" else { return } |
13 | | - let task = Process() |
14 | | - task.executableURL = URL(fileURLWithPath: "/usr/local/bin/vd-tool") |
15 | | - task.arguments = ["-c", "-in", file.path, "-out", inputDirectoryUrl.path] |
16 | | - |
17 | | - do { |
18 | | - try task.run() |
19 | | - } catch { |
20 | | - task.executableURL = URL(fileURLWithPath: "./vd-tool/bin/vd-tool") |
21 | | - try task.run() |
| 14 | + let errorPipe = Pipe() |
| 15 | + let outputPipe = Pipe() |
| 16 | + let directoryTaskArguments = ["-c", "-in", inputDirectoryUrl.path] |
| 17 | + |
| 18 | + try runVdTool(with: directoryTaskArguments, errorPipe: errorPipe, outputPipe: outputPipe) |
| 19 | + |
| 20 | + let errorData = errorPipe.fileHandleForReading.readDataToEndOfFile() |
| 21 | + let error = String(decoding: errorData, as: UTF8.self) |
| 22 | + |
| 23 | + let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile() |
| 24 | + let outputString = String(decoding: outputData, as: UTF8.self) |
| 25 | + // Only log last line out standard output |
| 26 | + outputString.lastLine.flatMap { logger.info("\($0)") } |
| 27 | + |
| 28 | + if error.contains(Self.notSupportedWarning) { |
| 29 | + logger.warning("vd-tool reported unsupported xml tags. Executing vd-tool for each file...") |
| 30 | + let enumerator = FileManager.default.enumerator(at: inputDirectoryUrl, includingPropertiesForKeys: nil) |
| 31 | + while let file = enumerator?.nextObject() as? URL { |
| 32 | + guard file.pathExtension == "svg" else { continue } |
| 33 | + let fileErrorPipe = Pipe() |
| 34 | + let fileTaskArguments = ["-c", "-in", file.path, "-out", inputDirectoryUrl.path] |
| 35 | + logger.info("Converting file: \(file.path)") |
| 36 | + try runVdTool(with: fileTaskArguments, errorPipe: fileErrorPipe) |
| 37 | + |
| 38 | + let fileErrorData = fileErrorPipe.fileHandleForReading.readDataToEndOfFile() |
| 39 | + let fileError = String(decoding: fileErrorData, as: UTF8.self) |
| 40 | + |
| 41 | + if fileError.contains(Self.notSupportedWarning) { |
| 42 | + logger.warning("Error in file: \(file.path)\n\(fileError)") |
| 43 | + } |
22 | 44 | } |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | + private func runVdTool(with arguments: [String], errorPipe: Pipe?, outputPipe: Pipe? = nil) throws { |
| 49 | + let task = Process() |
| 50 | + task.executableURL = URL(fileURLWithPath: "/usr/local/bin/vd-tool") |
| 51 | + task.arguments = arguments |
23 | 52 |
|
24 | | - task.waitUntilExit() |
| 53 | + task.standardOutput = outputPipe |
| 54 | + task.standardError = errorPipe |
| 55 | + |
| 56 | + do { |
| 57 | + try task.run() |
| 58 | + } catch { |
| 59 | + task.executableURL = URL(fileURLWithPath: "./vd-tool/bin/vd-tool") |
| 60 | + try task.run() |
25 | 61 | } |
| 62 | + |
| 63 | + task.waitUntilExit() |
| 64 | + } |
| 65 | +} |
| 66 | + |
| 67 | +private extension String { |
| 68 | + var lastLine: String? { |
| 69 | + split { $0 == "\n" }.compactMap(String.init).last |
26 | 70 | } |
27 | 71 | } |
0 commit comments