🔥 하위 명령어 정의하기
이제 앞서 언급한 하위 명령어 중 Add와 Multiply를 먼저 정의해 볼게요. 이 두 하위 명령어는 모두 @OptionGroup 프로퍼티 래퍼로 Options 타입에 정의된 인자를 포함하고 있어요. (OptionGroup 참고)
extension Math {
struct Add: ParsableCommand {
static var configuration
= CommandConfiguration(abstract: "Print the sum of the values.")
@OptionGroup var options: Options
mutating func run() {
let result = options.values.reduce(0, +)
print(format(result: result, usingHex: options.hexadecimalOutput))
}
}
struct Multiply: ParsableCommand {
static var configuration
= CommandConfiguration(abstract: "Print the product of the values.")
@OptionGroup var options: Options
mutating func run() {
let result = options.values.reduce(1, *)
print(format(result: result, usingHex: options.hexadecimalOutput))
}
}
}
extension Math {
struct Add: ParsableCommand {
static var configuration
= CommandConfiguration(abstract: "Print the sum of the values.")
@OptionGroup var options: Options
mutating func run() {
let result = options.values.reduce(0, +)
print(format(result: result, usingHex: options.hexadecimalOutput))
}
}
struct Multiply: ParsableCommand {
static var configuration
= CommandConfiguration(abstract: "Print the product of the values.")
@OptionGroup var options: Options
mutating func run() {
let result = options.values.reduce(1, *)
print(format(result: result, usingHex: options.hexadecimalOutput))
}
}
}
@OptionGroup은 다른 ParsableArguments 타입에 정의된 인자를 그대로 가져와서 현재 명령어에 추가해줍니다.
예를 들어, 다음과 같이 CommonOptions라는 ParsableArguments 타입이 있다고 가정해 봅시다.
struct CommonOptions: ParsableArguments {
@Option(help: "Verbose 모드 활성화")
var verbose: Bool = false
@Option(help: "출력 파일 경로")
var output: String?
}
struct CommonOptions: ParsableArguments {
@Option(help: "Verbose 모드 활성화")
var verbose: Bool = false
@Option(help: "출력 파일 경로")
var output: String?
}
그리고 MyCommand라는 명령어가 있는데, 이 명령어에서 CommonOptions의 인자를 사용하고 싶다면 다음과 같이 @OptionGroup을 사용할 수 있습니다.
struct MyCommand: ParsableCommand {
@OptionGroup var commonOptions: CommonOptions
@Argument(help: "입력 파일 경로")
var inputFile: String
mutating func run() throws {
if commonOptions.verbose {
print("Verbose 모드 활성화")
}
print("입력 파일: \(inputFile)")
print("출력 파일: \(commonOptions.output ?? "기본 경로")")
}
}
struct MyCommand: ParsableCommand {
@OptionGroup var commonOptions: CommonOptions
@Argument(help: "입력 파일 경로")
var inputFile: String
mutating func run() throws {
if commonOptions.verbose {
print("Verbose 모드 활성화")
}
print("입력 파일: \(inputFile)")
print("출력 파일: \(commonOptions.output ?? "기본 경로")")
}
}
이렇게 하면 MyCommand에서 CommonOptions에 정의된 verbose와 output 인자를 직접 정의하지 않아도 사용할 수 있습니다. 마치 CommonOptions의 인자를 MyCommand에 복사해 넣은 것처럼 동작하는 거죠.
이렇게 @OptionGroup을 사용하면 여러 명령어에서 공통으로 사용되는 인자를 별도의 ParsableArguments 타입으로 분리하고, 필요한 곳에서 가져다 쓸 수 있어 코드 재사용성을 높일 수 있습니다.









