#!/usr/bin/env swift import Foundation struct TerminationStatus: Error { let code: Int32 } func run(_ command: Command) throws { print(command.rendered.joined(separator: " ")) let task = Process() task.launchPath = "/usr/bin/env" task.arguments = command.rendered task.launch() task.waitUntilExit() if task.terminationStatus != 0 { throw TerminationStatus(code: task.terminationStatus) } } @dynamicMemberLookup @dynamicCallable struct Command { typealias Component = (String, [String: String?]) let components: [Component] init(components: [Component] = []) { self.components = components } var rendered: [String] { components.flatMap { c in [c.0] + c.1.flatMap { ["-\($0.0)", $0.1] }.compactMap { $0 } } } subscript(dynamicMember member: String) -> Self { addingComponent(member) } func dynamicallyCall(withKeywordArguments args: KeyValuePairs) throws { try run(self.addingArguments(args)) } func addingComponent(_ component: String) -> Command { Command( components: components + [(component, [:])] ) } func addingArguments(_ arguments: [String, String?]) -> Command { guard components.count > 0 else { return Command(components: [("", arguments)]) } var c = self c.components.last?.1 += arguments return c } } // Examples let cmd = Command() try cmd.xcodebuild.archive( project: "projectPath/ProjectName.xcodeproj", scheme: "production" )