読者です 読者をやめる 読者になる 読者になる

Go で TODO を管理する CLI を作ろうと思っていて

A Tour of Go を一通り終えたので,実際に何か作ってみようと思っていたときに,会社のデスクの上にタスクをメモった付箋が大量に貼ってあることに気付いて「よし!この TODO を管理する CLI を作ってみよう」と思い立ったのが3日前のこと.

Go ビギナーだから初歩的なところで困ったりもするけど,試行錯誤している過程で学んだことなども多いので,簡単に現状を整理しておこうかと思う.

試作している CLI をチラッと

ザッと以下の基本操作をできるようにした.

  • togoo init
    • SQLite データベースを作成してテーブルを追加する
  • togoo add
    • タスクを追加する
  • togoo list
    • タスクを一覧する
  • togoo done
    • タスクを完了する

タスクを一覧してみると以下のような出力になる.まだ表示できていないけど,データとしては created_atupdated_atUNIX time で保持している.

$ togoo list
| --- | -------------------------------------------------- | ------- |
| No  | Title                                              | Status  |
| --- | -------------------------------------------------- | ------- |
|   1 | sample_task1                                       | Done    |
|   2 | sample_task2                                       | -       |
| --- | -------------------------------------------------- | ------- |

Go で CLI の雛形を作るには

Ruby で言う Thor のようなものがあるかなとー思って調べたら codegangsta/cli · GitHub が人気そうだったので,tcnksm/gcli · GitHub を使ってスケルトンを生成した.gcli は本当に便利で,一瞬で CLI が動くようになった.素晴らしすぎる!

$ gcli new -c init -c add -c list -c done togoo
$ cd ${GOPATH}/src/github.com/kakakakakku/togoo
$ go build
$ ./togoo

SQLite を操作する

Go から SQLite を操作するために mattn/go-sqlite3 · GitHub を使った.サンプルコードが参考になった.

ホームディレクトリを取得する

togoo init を実行するとホームディレクトリに SQLite データベースを作成するようにしている.ホームディレクトリを取得するときに,最初は os/user を使って実装してみたんだけど,motemen/gore · GitHub のコードを読んでいたら mitchellh/go-homedir · GitHub を使っていることに気付いて真似してみた.cgo を必要としないため,クロスコンパイルの観点でメリットがあるとのこと.

UNIX time を取得する

SQLite にはタイムスタンプ型がないため Integer で定義して UNIX time を保持している.取得するには time.Now().Unix() と書く.

package main

import (
    "fmt"
    "time"
)

func main() {
    fmt.Println(time.Now().Unix())
}

困ってること

日本語(ダブルバイト)のタスク名を登録すると表示がズレてしまう.ちゃんと %-50s として幅固定しているのになぜ?こういうのをすぐ解決できないあたり,ビギナーだなと感じる.悔しー!(誰か指導プルリクを...!)

$ togoo list
| --- | -------------------------------------------------- | ------- |
| No  | Title                                              | Status  |
| --- | -------------------------------------------------- | ------- |
|   1 | sample_task1                                       | Done    |
|   2 | sample_task2                                       | -       |
|   3 | あ                                                  | -       |
| --- | -------------------------------------------------- | ------- |

引き続きやること

楽しそう!

  • 機能改善イロイロ
  • テストコードを書く(stretchr/testify · GitHub を使ってみる?)
  • TravisCI or Wercker でテストを回す
  • lint を導入する

まとめ

メリークリスマス!