Top View


Author shiro seike / せいけ しろう / 清家 史郎

Go製S3クライアントS3ry

2018/11/15

何故作ったのか

S3に保存してあるJsonファイルをいくつも確認しないといけないことがあって、
AWSコンソールを使うにも既存のCLIを使うにも少し使い辛いと感じた為です。

利用技術

  • Go
    • CLIツールなので親和性高いのとGoで作りたかった
  • AWS SDK for Go
    • S3を扱う為
  • promptui
    • 「使いにくい」を改善するためにリッチなCLIpromptが欲しかったため
  • spinner
    • データが大量にある際の待ち時間中の動作をユーザに伝える為

Demo

コード

機能

  • ファイルのダウンロード
    • このCLIを作った理由、/で検索も出来ます
  • ファイルのアップロード
  • ファイルの削除
    • 追加、削除は出来た方が良い
  • ファイルリスト作成
    • 大量にあるファイルリストが欲しいと要望があったため

工夫点

 - SDK側が100件ずつしかデータを取って来れないらしいのでページング実装したこと
 (これ書きながら凄いgoroutine化したくなった)

func (s S3ry) ListObjectsPages(bucket string) []PromptItems {
 sps("オブジェクトの検索中です...")
 items := []PromptItems{}
 key := 0
 err := s.svc.ListObjectsPages(&s3.ListObjectsInput{Bucket: aws.String(bucket)},
 func(listObjects \*s3.ListObjectsOutput, lastPage bool) bool {
 for \_, item := range listObjects.Contents {
 if strings.HasSuffix(\*item.Key, "/") == false {
 items = append(items, PromptItems{Key: key, Val: \*item.Key, LastModified: \*item.LastModified, Tag: "Object"})
 key++
 }
 }
 return !lastPage
 })
 if err != nil {
 awsErrorPrint(err)
 }
 sort.Slice(items, func(i, j int) bool {
 return items[i].LastModified.After(items[j].LastModified)
 })
 spe()
 return items
 }
  • promptui利用
    • Goは言語仕様でパッケージが小さくなるため外部パッケージを利用しやすい

まとめ

簡単なCLIツールではありますが、あっという間に作れてしまいました。
改善点は多々あるのですが、既存機能でも使えるポイントはあるので是非使ってみてください。

brew対応しました

brew tap seike460/s3ry
 brew install s3ry

あと気に入ったらStarください。
使う人いそうだったら連続ダウンロードだったり速度改善進めます。

shiro seike / せいけ しろう / 清家 史郎

shiro seike / せいけ しろう / 清家 史郎

Twitter X

Company:Fusic CO., LTD. Slides:slide.seike460.com blog:blog.seike460.com Program Language:PHP , Go Interest:Full Serverless Architecture