Template support for input parameters (#4)
This PR contains the work done to support input parameters for the `create` command of the executable target, and to render content dynamically for the newly-generated project. Reviewed-on: #4 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #4.
This commit is contained in:
@@ -1,16 +1,13 @@
|
||||
enum File: String {
|
||||
case app = "App"
|
||||
case appArguments = "AppArguments"
|
||||
case appBuilder = "AppBuilder"
|
||||
case appOptions = "AppOptions"
|
||||
case appTests = "AppTests"
|
||||
case dockerFile = "DockerFile"
|
||||
case dockerIgnore = "DockerIgnore"
|
||||
case environment = "Environment"
|
||||
case gitIgnore = "GitIgnore"
|
||||
case license = "License"
|
||||
case loggerLevel = "LoggerLevel"
|
||||
case package = "Package"
|
||||
case readme = "Readme"
|
||||
case testArguments = "TestArguments"
|
||||
|
||||
@@ -24,11 +21,9 @@ extension File {
|
||||
|
||||
var fileName: String {
|
||||
switch self {
|
||||
case .app: "App.swift"
|
||||
case .appArguments: "AppArguments.swift"
|
||||
case .appBuilder: "AppBuilder.swift"
|
||||
case .appOptions: "AppOptions.swift"
|
||||
case .appTests: "AppTests.swift"
|
||||
case .dockerFile: "Dockerfile"
|
||||
case .dockerIgnore: ".dockerignore"
|
||||
case .environment: "Environment+Properties.swift"
|
||||
@@ -36,7 +31,6 @@ extension File {
|
||||
case .license: "LICENSE"
|
||||
case .loggerLevel: "LoggerLevel+Conformances.swift"
|
||||
case .readme: "README.md"
|
||||
case .package: "Package.swift"
|
||||
case .testArguments: "TestArguments.swift"
|
||||
}
|
||||
}
|
||||
@@ -47,9 +41,8 @@ extension File {
|
||||
|
||||
var folder: Folder {
|
||||
switch self {
|
||||
case .app, .appOptions: .app
|
||||
case .appOptions: .app
|
||||
case .appArguments, .appBuilder: .libraryPublic
|
||||
case .appTests: .testCasesPublic
|
||||
case .environment, .loggerLevel: .libraryInternal
|
||||
case .testArguments: .testHelpers
|
||||
default: .root
|
||||
@@ -60,9 +53,9 @@ extension File {
|
||||
let basePath = "Resources/Files/Sources"
|
||||
|
||||
return switch self {
|
||||
case .app, .appOptions: "\(basePath)/App"
|
||||
case .appOptions: "\(basePath)/App"
|
||||
case .appArguments, .appBuilder, .environment, .loggerLevel: "\(basePath)/Library"
|
||||
case .appTests, .testArguments: "\(basePath)/Test"
|
||||
case .testArguments: "\(basePath)/Test"
|
||||
default: basePath
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
enum Template: String {
|
||||
case app = "App/App"
|
||||
case appTests = "Test/AppTests"
|
||||
case package = "Package"
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
extension Template {
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
var fileName: String {
|
||||
switch self {
|
||||
case .app: "App.swift"
|
||||
case .appTests: "AppTests.swift"
|
||||
case .package: "Package.swift"
|
||||
}
|
||||
}
|
||||
|
||||
var filePath: String {
|
||||
folder.path + fileName
|
||||
}
|
||||
|
||||
var folder: Folder {
|
||||
switch self {
|
||||
case .app: .app
|
||||
case .appTests: .testCasesPublic
|
||||
default: .root
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - CaseIterable
|
||||
|
||||
extension Template: CaseIterable {}
|
||||
@@ -1,75 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
struct RunProcessTask {
|
||||
|
||||
// MARK: Type aliases
|
||||
|
||||
typealias Output = String
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private var process: Processable
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
init(process: Processable) {
|
||||
self.process = process
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
@discardableResult
|
||||
mutating func callAsFunction(
|
||||
path: String, arguments: [String] = []
|
||||
) async throws (RunProcessError) -> Output {
|
||||
process.executableURL = URL(at: path)
|
||||
process.arguments = arguments
|
||||
|
||||
let pipeError = Pipe()
|
||||
let pipeOutput = Pipe()
|
||||
|
||||
process.standardError = pipeError
|
||||
process.standardOutput = pipeOutput
|
||||
|
||||
async let streamOutput = pipeOutput.availableData.append()
|
||||
async let streamError = pipeError.availableData.append()
|
||||
|
||||
do {
|
||||
try process.run()
|
||||
|
||||
let dataOutput = await streamOutput
|
||||
let dataError = await streamError
|
||||
|
||||
guard dataError.isEmpty else {
|
||||
guard let errorOutput = String(data: dataError, encoding: .utf8) else {
|
||||
throw RunProcessError.unexpected
|
||||
}
|
||||
|
||||
throw RunProcessError.output(errorOutput)
|
||||
}
|
||||
|
||||
guard let output = String(data: dataOutput, encoding: .utf8) else {
|
||||
throw RunProcessError.unexpected
|
||||
}
|
||||
|
||||
return await withCheckedContinuation { continuation in
|
||||
process.terminationHandler = { _ in
|
||||
continuation.resume(returning: output)
|
||||
}
|
||||
}
|
||||
} catch let error as RunProcessError {
|
||||
throw error
|
||||
} catch {
|
||||
throw RunProcessError.captured(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Errors
|
||||
|
||||
public enum RunProcessError: Error, Equatable {
|
||||
case captured(_ output: String)
|
||||
case output(_ output: String)
|
||||
case unexpected
|
||||
}
|
||||
Reference in New Issue
Block a user