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
alecthomas/kong はいいぞ
Search
FUJIWARA Shunichiro
July 28, 2025
Technology
2
350
alecthomas/kong はいいぞ
GopherのためのCLIツール開発』最新事情 LT 発表資料
https://findy.connpass.com/event/362163/
FUJIWARA Shunichiro
July 28, 2025
Tweet
Share
More Decks by FUJIWARA Shunichiro
See All by FUJIWARA Shunichiro
ecspressoの設計思想に至る道 / sekkeinight2025
fujiwara3
12
1.9k
さくらのIaaS基盤のモニタリングとOpenTelemetry/OSC Hokkaido 2025
fujiwara3
3
560
監視のこれまでとこれから/sakura monitoring seminar 2025
fujiwara3
11
4.8k
k6による負荷試験 入門から日常的な実践まで/Re:TechTalk #01
fujiwara3
2
99
困難を「一般解」で解く
fujiwara3
10
3.7k
「隙間家具OSS」に至る道/Fujiwara Tech Conference 2025
fujiwara3
7
12k
alecthomas/kong はいいぞ / kamakura.go#7
fujiwara3
1
1.1k
ISUCONに強くなるかもしれない日々の過ごしかた/Findy ISUCON 2024-11-14
fujiwara3
11
1.4k
「最高のチューニング」をしないために / hack@delta 24.10
fujiwara3
21
4.5k
Other Decks in Technology
See All in Technology
Shadow DOM & Security - Exploring the boundary between light and shadow
masatokinugawa
0
720
怖くない!GritQLでBiomeプラグインを作ろうよ
pal4de
1
130
The Madness of Multiple Gemini CLIs Developing Simultaneously with Jujutsu
gunta
1
2.6k
分散トレーシングによる コネクティッドカーのデータ処理見える化の試み
thatsdone
0
250
少人数でも回る! DevinとPlaybookで支える運用改善
ishikawa_pro
4
1.3k
生成AIによる情報システムへのインパクト
taka_aki
1
170
P2P ではじめる WebRTC のつまづきどころ
tnoho
1
230
Wasmで社内ツールを作って配布しよう
askua
0
150
本当にわかりやすいAIエージェント入門
segavvy
10
6.1k
KCD Lima: eBee in Peru!
lizrice
0
100
興味の胞子を育て 業務と技術に広がる”きのこ力”
fumiyasac0921
0
200
20150719_Amazon Nova Canvas Virtual try-onアプリ 作成裏話
riz3f7
0
140
Featured
See All Featured
Facilitating Awesome Meetings
lara
54
6.5k
4 Signs Your Business is Dying
shpigford
184
22k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Optimizing for Happiness
mojombo
379
70k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
720
Site-Speed That Sticks
csswizardry
10
720
Building a Modern Day E-commerce SEO Strategy
aleyda
42
7.4k
Mobile First: as difficult as doing things right
swwweet
223
9.7k
Designing Experiences People Love
moore
142
24k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
Rails Girls Zürich Keynote
gr2m
95
14k
Transcript
alecthomas/kong はいいぞ 2025.07.28 『GopherのためのCLIツール開発』最新事情 LT @fujiwara
自己紹介 @fujiwara (X, GitHub, Bluesky) 2025-02〜 さくらインターネット ISUCON 優勝4回 /
運営5回 github.com/kayac/ecspresso github.com/fujiwara/lambroll
CLI flag parser、何を使ってますか? Claude にお勧めを聞いてみたらこんな感じ flag (標準) spf13/pflag spf13/cobra urfave/cli
alecthomas/kong 今日は alecthomas/kong をお勧めする話をします
https://github.com/alecthomas/kong
package main import "github.com/alecthomas/kong" var CLI struct { Rm struct
{ Force bool `help:"Force removal."` Recursive bool `help:"Recursively remove files."` Paths []string `arg:"" name:"path" help:"Paths to remove." type:"path"` } `cmd:"" help:"Remove files."` Ls struct { Paths []string `arg:"" optional:"" name:"path" help:"Paths to list." type:"path"` } `cmd:"" help:"List paths."` } func main() { ctx := kong.Parse(&CLI) switch ctx.Command() { case "rm <path>": case "ls": default: panic(ctx.Command()) } }
サブコマンドと引数を構造体に定義 var CLI struct { Rm struct { Force bool
`help:"Force removal."` Recursive bool `help:"Recursively remove files."` Paths []string `arg:"" name:"path" help:"Paths to remove." type:"path"` } `cmd:"" help:"Remove files."` Ls struct { Paths []string `arg:"" optional:"" name:"path" help:"Paths to list." type:"path"` } `cmd:"" help:"List paths."` } rm コマンドには --force , --recursive 、 paths (複数可)が引数 command rm --force --recursive foo bar ls コマンドには paths (複数可)が引数 command ls foo bar baz
定義した構造体を kong.Parse に渡して解析 func main() { ctx := kong.Parse(&CLI) //
このctxはcontext.Context**ではない**ので注意 switch ctx.Command() { case "rm <path>": case "ls": default: panic(ctx.Command()) } } 基本はこれだけ コマンドラインから渡された引数( os.Args )を解析して構造体に入れてくれる その後のコードは好きに書いていい
kong のいいところ 宣言的。サブコマンドまで含めて一目でオプションが把握できる map ( Foo map[string]int → --foo="x=1;y=2;z=3" )
slice ( Foo []string → --foo=x --foo=y ) struct tag でいろいろ設定できる required:"" (必須) default:"value" (デフォルト値の設定) short:"x" (短縮形 -x を生成) negatable:"" (bool型の否定形を生成 --wait → --no-wait ) enum:"a,b,c" (a,b,cいずれかの値を要求) env:"FOO" (環境変数FOOを読む) などなど 型に合わせて適切な引数のパースをしてくれる int , bool , time.Duration , time.Time (format指定可)など
kong の一番好きなところ コードの書き方を強要されない CLIフレームワークではなく単なるパーサーとして使える
応用例 例えば Lambda 関数を Go で書く場合、設定値は環境変数から読む func main() { lambda.Start(handler)
} func handler(ctx context.Context) error { // ダメな例 s3Bucket := os.Getenv("BUCKET") if s3Bucket == "" { return errors.New("BUCKET is required") } // ... } 環境変数がないときにエラーになるのは「関数の実行時」 デプロイ直後には発覚しない、めったに通らないところにこれが埋まっていると…?
環境変数を読むのは kong に任せる var CLI struct { Bucket string `env:"BUCKET"
required:"" help:"S3 BUCKET"` LogLevel string `env:"LOG_LEVEL" default:"info" help:"Log level"` } func main() { ctx := kong.Parse(&CLI) // ここで CLI に値が入っている // 必須がなければエラー、デフォルト値も埋まっている lambda.Start(handler) } func handler(ctx context.Context) error { // ここでは CLI の値を使うだけ } こうしておけば、関数の初期化時に確実にエラーになる デフォルト値も設定できる
まとめ alecthomas/kong はパーサー特化、便利なのでお勧めです 最近の fujiwara-ware はだいたい kong を使っています (ecspresso, lambroll
は alecthomas/kingpin から移行)