Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
swift-argument-parserで 簡単 CLI ツール作り
Search
ry-itto
July 18, 2020
Programming
170
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
swift-argument-parserで 簡単 CLI ツール作り
ry-itto
July 18, 2020
More Decks by ry-itto
See All by ry-itto
決定版!?OSSアプリプロジェクトでのBeta版アプリ配布の方法「Xcode Cloud + TestFlight」
ryitto
0
400
CA.swift#14
ryitto
3
5.9k
Data Essentials in SwiftUI
ryitto
1
540
Composable Architecture
ryitto
0
810
CollectionViewの 新しいレイアウトの作り方
ryitto
0
79
Swift5.1 SwiftUI
ryitto
0
140
Other Decks in Programming
See All in Programming
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
310
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.1k
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
130
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
210
1B+ /day規模のログを管理する技術
broadleaf
0
120
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
240
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
800
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
370
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.4k
JavaDoc 再入門
nagise
1
430
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.7k
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
400
Featured
See All Featured
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
Paper Plane (Part 1)
katiecoart
PRO
0
9.4k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Designing Powerful Visuals for Engaging Learning
tmiket
1
430
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
340
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
320
The Cult of Friendly URLs
andyhume
79
6.9k
Automating Front-end Workflow
addyosmani
1370
210k
Docker and Python
trallard
47
3.9k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
150
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Transcript
swift-argument-parserͰ ؆୯ CLI πʔϧ࡞Γ Zli × DMM ߹ಉLT ry-itto 2020/07/18
1
ࣗݾհ • ҏ౻྇(@ry-itto) • iOS • B4 • Χϐόϥ͕͖ 2
͜Μͳ͜ͱͬͯ·ͨ͠ˠ
ࣗݾհʢଓ͖ʣ ʬ͋ͭ͠ʭChannel ΛΈΔ͜ͱΛ՝ʹͯ͠·͢ ༊͞ΕΔͷͰҰճΈͯ΄͍͠ ↑͓͢͢Ίͷಈը (https://www.youtube.com/watch?v=4tieUdeYHHY)
swift-argument-parser ͱʁʁ • Apple ެࣜͷϥΠϒϥϦ • CLI πʔϧΛ͏࣌ʹΑ͋͘ΔΦϓγϣϯͱ͔ɺίϚϯυͷαϒίϚ ϯυͱ͔Λѻ͏ͷ •
PropertyWrapper Λ͏·͍͜ͱ͍ͬͯΔ • help ͕͍͍ײ͡ʹͳΔ 4
ॾҙ • ࠓճ swift-argument-parser ʹ͍ͭͯͷΈઆ໌͠·͢ • SPM ͰίϚϯυϥΠϯ πʔϧΛ࡞Δํ๏ͳͲݴ͍·ͤΜ 5
ϛχϚϜͳ ͍ํ struct SampleCommand: ParsableCommand { func run() throws {
print("sample") } } SampleCommand.main() 1. ParsableCommand ʹ४ڌ ͨ͠Ϋϥε/ߏମΛ༻ҙ ͢Δ 2. run() ϝιουΛ࣮͢Δ 3. main() ΛݺͿ 6
ͪΐͬͱԠ༻ 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
ͪΐͬͱԠ༻ @Argument • ίϚϯυʹର͢ΔҾ • σϑΥϧτΛ༩͓͑ͯ͘ͱࢦఆ ͠ͳͯ͘ಈ࡞͢Δ • ΠχγϟϥΠβҎԼ̎ͭͳͲ͕ ༻ҙ͞Ε͍ͯΔ
• @Argument(help:transform:) • @Argument(wrappedValue:parsing:help:trans form:) • ෳͷҾʹରԠ͍ͯ͠Δ 8
ͪΐͬͱԠ༻ @Flag • ϑϥάɻ (ls -a ͷ -a ͱ͔ͷΠϝʔ δ)
• ྫͷΑ͏ʹ Bool ͰͷΓସ͑ Ͱ͖Δ͕ɺenum Ͱ͍͚Δ • ↓ΠχγϟϥΠβͰΑ͍ͦ͘͏ • @Flag(name:help:) 9
@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
ͪΐͬͱԠ༻ @Option • git commit -m <commit- message> ͷΠϝʔδ •
σϑΥϧτΛ༩͑Δ·ͨΦϓ γϣφϧܕʹ͠ͳ͍ͱඞਢͷΦϓ γϣϯʹͳͬͯ͠·͏ 11
ͪΐͬͱԠ༻ > ./.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
ͪΐͬͱԠ༻ ͬͯΈΔ :yosasou: 13
αϒίϚϯυ 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()
αϒίϚϯυ > ./.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
αϒίϚϯυ ࡞Γํ • ParsableCommand ʹ४ڌͨ͠Ϋ ϥε/ߏମ Λ༻ҙ • configuration Λఆٛͯ͠ɺҾ
ͷ subcommands ʹ࡞ͬͨαϒί ϚϯυΛೖΕΔ • defaultSubcommand Λࢦఆ͢Δ ͜ͱͰɺsubcommand ໊Λࢦఆ ͠ͳͯ͘ྑ͘ͳΔ
αϒίϚϯυ ͬͯΈΔ
εϥΠυʹग़͖ͯͨιʔείʔυ ↓ʹஔ͍ͯ·͢ github.com/ry-itto-playground/SampleCommand
࡞ͬͯΈͨͷͷհ (⭐͍ͩ͘͞) AtCoderSwiftCLI (github.com/ry-itto/AtCoderSwiftCLI) • cargo-atcoder ͷ Swift ൛ΛΠϝʔδ •
ఏग़ػೳ࡞ͬͯΈͯΔ్த • brew ͰམͱͤΔΑ͏ʹͯ͠ͳ͍ͷͰ mint ͔ɺखಈϏϧυͰ 19