diff --git a/Sources/remindctl/CommandHelpers.swift b/Sources/remindctl/CommandHelpers.swift index 9e9bd45..d4138ba 100644 --- a/Sources/remindctl/CommandHelpers.swift +++ b/Sources/remindctl/CommandHelpers.swift @@ -73,17 +73,6 @@ enum CommandHelpers { return nil } - static func requiredListTarget( - name: String?, - id: String?, - argumentName: String = "list" - ) throws -> ReminderListTarget { - guard let target = try listTarget(name: name, id: id) else { - throw ParsedValuesError.missingArgument(argumentName) - } - return target - } - static func reminder(_ reminder: ReminderItem, matchesSearch query: String) -> Bool { let trimmed = query.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { return false } diff --git a/Sources/remindctl/CommandRouter.swift b/Sources/remindctl/CommandRouter.swift index fa4cc18..9409256 100644 --- a/Sources/remindctl/CommandRouter.swift +++ b/Sources/remindctl/CommandRouter.swift @@ -8,25 +8,27 @@ struct CommandRouter { let specs: [CommandSpec] let program: Program + static let commandSpecs: [CommandSpec] = [ + ShowCommand.spec, + ListCommand.spec, + SearchCommand.spec, + InfoCommand.spec, + AddCommand.spec, + EditCommand.spec, + CompleteCommand.spec, + DeleteCommand.spec, + StatusCommand.spec, + AuthorizeCommand.spec, + DoctorCommand.spec, + ExportCommand.spec, + LinkCommand.spec, + OpenCommand.spec, + CompletionCommand.spec, + ] + init() { self.version = CommandRouter.resolveVersion() - self.specs = [ - ShowCommand.spec, - ListCommand.spec, - SearchCommand.spec, - InfoCommand.spec, - AddCommand.spec, - EditCommand.spec, - CompleteCommand.spec, - DeleteCommand.spec, - StatusCommand.spec, - AuthorizeCommand.spec, - DoctorCommand.spec, - ExportCommand.spec, - LinkCommand.spec, - OpenCommand.spec, - CompletionCommand.spec, - ] + self.specs = Self.commandSpecs let descriptor = CommandDescriptor( name: rootName, abstract: "Manage Apple Reminders from the terminal", diff --git a/Sources/remindctl/CommandSpec.swift b/Sources/remindctl/CommandSpec.swift index 7dea258..eb4744c 100644 --- a/Sources/remindctl/CommandSpec.swift +++ b/Sources/remindctl/CommandSpec.swift @@ -1,12 +1,12 @@ import Commander -struct CommandSpec: @unchecked Sendable { +struct CommandSpec: Sendable { let name: String let abstract: String let discussion: String? let signature: CommandSignature let usageExamples: [String] - let run: (ParsedValues, RuntimeOptions) async throws -> Void + let run: @Sendable (ParsedValues, RuntimeOptions) async throws -> Void var descriptor: CommandDescriptor { CommandDescriptor( diff --git a/Sources/remindctl/Commands/AddCommand.swift b/Sources/remindctl/Commands/AddCommand.swift index d257044..317bb3e 100644 --- a/Sources/remindctl/Commands/AddCommand.swift +++ b/Sources/remindctl/Commands/AddCommand.swift @@ -145,13 +145,12 @@ enum AddCommand { radius: String?, leaving: Bool ) throws -> LocationTrigger? { - if location == nil { + guard let location else { if radius != nil || leaving { throw RemindCoreError.operationFailed("Use --location with --radius or --leaving") } return nil } - guard let location else { return nil } let radius = try radius.map(parseRadius) ?? 100 return LocationTrigger( address: location, diff --git a/Sources/remindctl/Commands/CompletionCommand.swift b/Sources/remindctl/Commands/CompletionCommand.swift index bafc055..a621f24 100644 --- a/Sources/remindctl/Commands/CompletionCommand.swift +++ b/Sources/remindctl/Commands/CompletionCommand.swift @@ -32,10 +32,9 @@ enum CompletionCommand { } } - private static let commands = [ - "show", "list", "search", "info", "add", "edit", "complete", "delete", "status", "authorize", "doctor", "export", - "link", "open", "completion", - ] + private static var commands: [String] { + CommandRouter.commandSpecs.map(\.name) + } private static func zsh() -> String { """ diff --git a/Sources/remindctl/Commands/OpenCommand.swift b/Sources/remindctl/Commands/OpenCommand.swift index fba02ff..ded4757 100644 --- a/Sources/remindctl/Commands/OpenCommand.swift +++ b/Sources/remindctl/Commands/OpenCommand.swift @@ -56,16 +56,8 @@ enum OpenCommand { } let url: URL - if values.flag("app") { - if values.argument(0) != nil || listTarget != nil { - let result = try await LinkCommand.resolve(values: values) - guard let parsed = URL(string: result.url) else { - throw RemindCoreError.operationFailed("Invalid Reminders URL") - } - url = parsed - } else { - url = URL(string: "x-apple-reminderkit://")! - } + if values.flag("app"), values.argument(0) == nil, listTarget == nil { + url = URL(string: "x-apple-reminderkit://")! } else { let result = try await LinkCommand.resolve(values: values) guard let parsed = URL(string: result.url) else { diff --git a/Sources/remindctl/ParsedValues+Decode.swift b/Sources/remindctl/ParsedValues+Decode.swift index 36b8893..42c8b1e 100644 --- a/Sources/remindctl/ParsedValues+Decode.swift +++ b/Sources/remindctl/ParsedValues+Decode.swift @@ -2,16 +2,10 @@ import Commander import Foundation enum ParsedValuesError: LocalizedError, CustomStringConvertible { - case missingOption(String) - case invalidOption(String) case missingArgument(String) var description: String { switch self { - case .missingOption(let name): - return "Missing required option: --\(name)" - case .invalidOption(let name): - return "Invalid value for option: --\(name)" case .missingArgument(let name): return "Missing required argument: \(name)" } @@ -31,17 +25,6 @@ extension ParsedValues { options[label]?.last } - func optionValues(_ label: String) -> [String] { - options[label] ?? [] - } - - func optionRequired(_ label: String) throws -> String { - guard let value = option(label), !value.isEmpty else { - throw ParsedValuesError.missingOption(label) - } - return value - } - func argument(_ index: Int) -> String? { guard positional.indices.contains(index) else { return nil } return positional[index]