106 lines
2.9 KiB
Swift
106 lines
2.9 KiB
Swift
//
|
|
// SwiftGen
|
|
// Copyright © 2022 SwiftGen
|
|
// MIT Licence
|
|
//
|
|
|
|
import AppKit
|
|
import PathKit
|
|
import Stencil
|
|
import StencilSwiftKit
|
|
import SwiftGenKit
|
|
|
|
extension Config {
|
|
public func runCommands(
|
|
modernSpacing: Bool,
|
|
logLevel: CommandLogLevel,
|
|
logger: (LogLevel, String) -> Void = logMessage
|
|
) throws {
|
|
let errors = commands.parallelCompactMap { cmd, entry -> Swift.Error? in
|
|
do {
|
|
try run(parserCommand: cmd, entry: entry, modernSpacing: modernSpacing, logLevel: logLevel, logger: logger)
|
|
return nil
|
|
} catch {
|
|
return error
|
|
}
|
|
}
|
|
|
|
if errors.count == 1 {
|
|
throw errors[0]
|
|
} else if errors.count > 1 {
|
|
throw Error.multipleErrors(errors)
|
|
}
|
|
}
|
|
|
|
private func run(
|
|
parserCommand: ParserCLI,
|
|
entry: ConfigEntry,
|
|
modernSpacing: Bool,
|
|
logLevel: CommandLogLevel,
|
|
logger: (LogLevel, String) -> Void
|
|
) throws {
|
|
var entry = entry
|
|
|
|
entry.makeRelativeTo(inputDir: inputDir, outputDir: outputDir)
|
|
if logLevel == .verbose {
|
|
for item in entry.commandLine(forCommand: parserCommand.name) {
|
|
logger(.info, " $ \(item)")
|
|
}
|
|
}
|
|
|
|
try entry.checkPaths()
|
|
try entry.run(parserCommand: parserCommand, modernSpacing: modernSpacing, logger: logger)
|
|
}
|
|
}
|
|
|
|
extension ConfigEntry {
|
|
func run(parserCommand: ParserCLI, modernSpacing: Bool, logger: (LogLevel, String) -> Void) throws {
|
|
let context: [String: Any] = try withoutActuallyEscaping(logger) { logger in
|
|
let parser = try parserCommand.parserType.init(options: options) { msg, _, _ in
|
|
logger(.warning, msg)
|
|
}
|
|
let filter = try Filter(
|
|
pattern: self.filter ?? parserCommand.parserType.defaultFilter,
|
|
options: parserCommand.parserType.filterOptions
|
|
)
|
|
|
|
try parser.searchAndParse(paths: inputs, filter: filter)
|
|
return parser.stencilContext()
|
|
}
|
|
|
|
for entryOutput in outputs {
|
|
let templateRealPath = try entryOutput.template.resolvePath(forParser: parserCommand, logger: logger)
|
|
let isBundledTemplate = entryOutput.template.isBundled(forParser: parserCommand)
|
|
let template = try Template.load(from: templateRealPath, modernSpacing: isBundledTemplate || modernSpacing)
|
|
|
|
let enriched = try StencilContext.enrich(context: context, parameters: entryOutput.parameters)
|
|
let rendered = try template.render(enriched)
|
|
let output = OutputDestination.file(entryOutput.output)
|
|
try output.write(content: rendered, onlyIfChanged: true, logger: logger)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Path checks
|
|
|
|
extension ConfigEntry {
|
|
func checkPaths() throws {
|
|
for inputPath in self.inputs {
|
|
guard inputPath.exists else {
|
|
throw Config.Error.pathNotFound(path: inputPath)
|
|
}
|
|
}
|
|
for output in outputs {
|
|
try output.checkPaths()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ConfigEntryOutput {
|
|
func checkPaths() throws {
|
|
guard self.output.parent().exists else {
|
|
throw Config.Error.pathNotFound(path: self.output.parent())
|
|
}
|
|
}
|
|
}
|