Add more command line arguments
This commit is contained in:
parent
7e85309883
commit
0b1e439676
@ -5,14 +5,45 @@ import Foundation
|
|||||||
struct CapTrain: AsyncParsableCommand {
|
struct CapTrain: AsyncParsableCommand {
|
||||||
|
|
||||||
@Argument(help: "The path to the configuration file")
|
@Argument(help: "The path to the configuration file")
|
||||||
var configPath: String
|
var configPath: String?
|
||||||
|
|
||||||
|
@Option(name: .shortAndLong, help: "The number of iterations to train")
|
||||||
|
var iterations: Int?
|
||||||
|
|
||||||
|
@Option(name: .shortAndLong, help: "The url of the caps server")
|
||||||
|
var serverPath: String?
|
||||||
|
|
||||||
|
@Option(name: .shortAndLong, help: "The authentication token for the server")
|
||||||
|
var authentication: String?
|
||||||
|
|
||||||
|
@Option(name: .shortAndLong, help: "The folder where the content (images, classifier, thumbnails) is stored")
|
||||||
|
var folder: String?
|
||||||
|
|
||||||
func run() async throws {
|
func run() async throws {
|
||||||
let configurationFileUrl = URL(fileURLWithPath: configPath)
|
let configurationFile = try configurationFile()
|
||||||
|
guard let contentFolder = folder ?? configurationFile?.contentFolder,
|
||||||
let configuration = try Configuration(at: configurationFileUrl)
|
let trainingIterations = iterations ?? configurationFile?.trainingIterations,
|
||||||
let creator = try ClassifierCreator(configuration: configuration)
|
let serverPath = serverPath ?? configurationFile?.serverPath,
|
||||||
|
let authenticationToken = authentication ?? configurationFile?.authenticationToken
|
||||||
|
else {
|
||||||
|
throw TrainingError.missingArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
let configuration = Configuration(
|
||||||
|
contentFolder: contentFolder,
|
||||||
|
trainingIterations: trainingIterations,
|
||||||
|
serverPath: serverPath,
|
||||||
|
authenticationToken: authenticationToken)
|
||||||
|
|
||||||
|
let creator = try ClassifierCreator(configuration: configuration)
|
||||||
try await creator.run()
|
try await creator.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func configurationFile() throws -> ConfigurationFile? {
|
||||||
|
guard let configPath else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
let configurationFileUrl = URL(fileURLWithPath: configPath)
|
||||||
|
return try ConfigurationFile(at: configurationFileUrl)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,34 +1,17 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct Configuration: Codable {
|
struct Configuration {
|
||||||
|
|
||||||
let contentFolder: String
|
let contentFolder: String
|
||||||
|
|
||||||
let trainingIterations: Int
|
let trainingIterations: Int
|
||||||
|
|
||||||
let serverPath: String
|
let serverPath: String
|
||||||
|
|
||||||
let authenticationToken: String
|
let authenticationToken: String
|
||||||
|
}
|
||||||
init(at url: URL) throws {
|
|
||||||
guard FileManager.default.fileExists(atPath: url.path) else {
|
extension Configuration {
|
||||||
print("[ERROR] No configuration at \(url.absoluteURL.path)")
|
|
||||||
throw TrainingError.configurationFileMissing
|
|
||||||
}
|
|
||||||
let data: Data
|
|
||||||
do {
|
|
||||||
data = try Data(contentsOf: url)
|
|
||||||
} catch {
|
|
||||||
print("[ERROR] Failed to load configuration data at \(url.absoluteURL.path): \(error)")
|
|
||||||
throw TrainingError.configurationFileUnreadable
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
self = try JSONDecoder().decode(Configuration.self, from: data)
|
|
||||||
} catch {
|
|
||||||
print("[ERROR] Failed to decode configuration at \(url.absoluteURL.path): \(error)")
|
|
||||||
throw TrainingError.configurationFileDecodingFailed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func serverUrl() throws -> URL {
|
func serverUrl() throws -> URL {
|
||||||
guard let serverUrl = URL(string: serverPath) else {
|
guard let serverUrl = URL(string: serverPath) else {
|
||||||
|
39
Sources/ConfigurationFile.swift
Normal file
39
Sources/ConfigurationFile.swift
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct ConfigurationFile {
|
||||||
|
|
||||||
|
let contentFolder: String?
|
||||||
|
|
||||||
|
let trainingIterations: Int?
|
||||||
|
|
||||||
|
let serverPath: String?
|
||||||
|
|
||||||
|
let authenticationToken: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ConfigurationFile: Decodable {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ConfigurationFile {
|
||||||
|
|
||||||
|
init(at url: URL) throws {
|
||||||
|
guard FileManager.default.fileExists(atPath: url.path) else {
|
||||||
|
print("[ERROR] No configuration at \(url.absoluteURL.path)")
|
||||||
|
throw TrainingError.configurationFileMissing
|
||||||
|
}
|
||||||
|
let data: Data
|
||||||
|
do {
|
||||||
|
data = try Data(contentsOf: url)
|
||||||
|
} catch {
|
||||||
|
print("[ERROR] Failed to load configuration data at \(url.absoluteURL.path): \(error)")
|
||||||
|
throw TrainingError.configurationFileUnreadable
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
self = try JSONDecoder().decode(ConfigurationFile.self, from: data)
|
||||||
|
} catch {
|
||||||
|
print("[ERROR] Failed to decode configuration at \(url.absoluteURL.path): \(error)")
|
||||||
|
throw TrainingError.configurationFileDecodingFailed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,8 @@ import Foundation
|
|||||||
|
|
||||||
enum TrainingError: Error {
|
enum TrainingError: Error {
|
||||||
|
|
||||||
|
case missingArguments
|
||||||
|
|
||||||
case configurationFileMissing
|
case configurationFileMissing
|
||||||
case configurationFileUnreadable
|
case configurationFileUnreadable
|
||||||
case configurationFileDecodingFailed
|
case configurationFileDecodingFailed
|
||||||
|
Loading…
Reference in New Issue
Block a user