Upgrade to Pro — share decks privately, control downloads, hide ads and more …

swift-argument-parserで
簡単 CLI ツール作り

swift-argument-parserで
簡単 CLI ツール作り

ry-itto

July 18, 2020
Tweet

More Decks by ry-itto

Other Decks in Programming

Transcript

  1. ϛχϚϜͳ ࢖͍ํ struct SampleCommand: ParsableCommand { func run() throws {

    print("sample") } } SampleCommand.main() 1. ParsableCommand ʹ४ڌ ͨ͠Ϋϥε/ߏ଄ମΛ༻ҙ ͢Δ 2. run() ϝιουΛ࣮૷͢Δ 3. main() ΛݺͿ 6
  2. ͪΐͬͱԠ༻ import ArgumentParser struct SampleCommand: ParsableCommand { @Argument() var context:

    String @Flag() var upper: Bool = false @Option( name: .shortAndLong, help: "Repeating context" ) var repeatTimes: Int? mutating func run() throws { if upper { self.context = context.uppercased() } if let repeatTimes = repeatTimes { self.context = String(repeating: context, count: repeatTimes) } print(context) } } SampleCommand.main() echo ίϚϯυͷΑ͏ͳ΋ͷɻ • @Argument • @Flag • @Option ͕ग़͖ͯͨ 7
  3. ͪΐͬͱԠ༻ @Argument • ίϚϯυʹର͢ΔҾ਺ • σϑΥϧτ஋Λ༩͓͑ͯ͘ͱࢦఆ ͠ͳͯ͘΋ಈ࡞͢Δ • ΠχγϟϥΠβ͸ҎԼ̎ͭͳͲ͕ ༻ҙ͞Ε͍ͯΔ

    • @Argument(help:transform:) • @Argument(wrappedValue:parsing:help:trans form:) • ෳ਺ͷҾ਺ʹ΋ରԠ͍ͯ͠Δ 8
  4. ͪΐͬͱԠ༻ @Flag • ϑϥάɻ (ls -a ͷ -a ͱ͔ͷΠϝʔ δ)

    • ྫͷΑ͏ʹ Bool Ͱͷ੾Γସ͑΋ Ͱ͖Δ͕ɺenum Ͱ΋͍͚Δ • ↓ΠχγϟϥΠβͰΑ͘࢖͍ͦ͏ • @Flag(name:help:) 9
  5. @Flag (͓·͚) import ArgumentParser enum OutputCase: EnumerableFlag { case upper

    case lower case natural } struct SampleCommand: ParsableCommand { @Argument() var context: String @Flag() var outputCase: OutputCase = .natural @Option( name: .shortAndLong, help: "Repeating context" ) var repeatTimes: Int? mutating func run() throws { switch outputCase { case .upper: self.context = context.uppercased() case .lower: self.context = context.lowercased() case .natural: break } if let repeatTimes = repeatTimes { self.context = String(repeating: context, count: repeatTimes) } print(context) } } SampleCommand.main() enum Ͱॻ͍ͨόʔδϣϯ (lower ΋ͨͯ͠Έͨ) 10
  6. ͪΐͬͱԠ༻ @Option • git commit -m <commit- message> ͷΠϝʔδ •

    σϑΥϧτ஋Λ༩͑Δ·ͨ͸Φϓ γϣφϧܕʹ͠ͳ͍ͱඞਢͷΦϓ γϣϯʹͳͬͯ͠·͏ 11
  7. ͪΐͬͱԠ༻ > ./.build/debug/SampleCommand --help USAGE: sample-command <context> [--upper] [--repeat- times

    <repeat-times>] ARGUMENTS: <context> OPTIONS: --upper -r, --repeat-times <repeat-times> Repeating context -h, --help Show help information. —help
  8. αϒίϚϯυ import ArgumentParser struct SampleSubCommands: ParsableCommand { static var configuration:

    CommandConfiguration = .init( subcommands: [Sum.self, Average.self], defaultSubcommand: Sum.self ) } struct Sum: ParsableCommand { @Argument() var numbers: [Int] = [] mutating func run() throws { print(numbers.reduce(0, +)) } } struct Average: ParsableCommand { @Argument() var numbers: [Int] = [] func validate() throws { if numbers.count == 0 { throw ValidationError("Please specify numbers.") } } mutating func run() throws { print(numbers.reduce(0, +) / numbers.count) } } SampleSubCommands.main()
  9. αϒίϚϯυ > ./.build/debug/SampleSubCommands --help USAGE: sample-sub-commands <subcommand> OPTIONS: -h, --help

    Show help information. SUBCOMMANDS: sum (default) average See 'sample-sub-commands help <subcommand>' for detailed help. --help
  10. αϒίϚϯυ ࡞Γํ • ParsableCommand ʹ४ڌͨ͠Ϋ ϥε/ߏ଄ମ Λ༻ҙ • configuration Λఆٛͯ͠ɺҾ਺

    ͷ subcommands ʹ࡞ͬͨαϒί ϚϯυΛೖΕΔ • defaultSubcommand Λࢦఆ͢Δ ͜ͱͰɺsubcommand ໊Λࢦఆ ͠ͳͯ͘΋ྑ͘ͳΔ
  11. ࡞ͬͯΈͨ΋ͷͷ঺հ (⭐͍ͩ͘͞) AtCoderSwiftCLI (github.com/ry-itto/AtCoderSwiftCLI) • cargo-atcoder ͷ Swift ൛ΛΠϝʔδ •

    ఏग़ػೳ͸࡞ͬͯΈͯΔ్த • brew ͰམͱͤΔΑ͏ʹͯ͠ͳ͍ͷͰ mint ͔ɺखಈϏϧυͰ 19