20
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Golangで実装するCUIコマンド

Last updated at Posted at 2015-06-05

最近、RDB(Mysql)を操作するバッチ処理を実装することが多く、お勉強がてらgolangを使い始めました。

やることはいつも

  • パラメーター判断
  • トランザクション制御
  • ログ出力

こんな感じなので、
golangの動作確認を兼ねて、コマンドアプリのひな型になりそうなサンプルを作りました。

package main

import (
  "flag"
  "fmt"
  "time"
  "os"
)

const VERSION = `0.0.1`

type ErrMessage struct {
	What string
}
func (e ErrMessage) Error() string {
	return fmt.Sprintf("%v: %v", time.Now(), e.What)
}

var (
  version = flag.Bool("V", false, "display version information")
  failure = flag.Bool("failure", false, "失敗させます")
)

func DoSomething(str string) (err error) {
    defer func() {
      // panicがおきたらRollback
      if e := recover(); e != nil {
          fmt.Fprintf(os.Stderr, "Rollback!!\n")
          // エラーメッセージフォーマット変換
          x, _ := e.(string)
          err = ErrMessage{x}
      }
    }()

    if *failure {
      // Error発生
      panic("DoSomething error...")
    }

    fmt.Fprintf(os.Stdout, "%s\n", str)
    return nil
}

func main() {
  flag.Parse()
  if *version {
    fmt.Printf("dosomething %s\n", VERSION)
    os.Exit(0)
  }

  str := "do something & commit!!"
  err := DoSomething(str)
  if err != nil {
    fmt.Fprintf(os.Stderr, "%s\n", err)
    os.Exit(1)
  }

  str = "and finish!!"
  fmt.Fprintf(os.Stdout, "%s\n", str)
}

パラメーターの実装は、flagを使えば楽ですね。

トランザクション制御について、
異常時のRollBackを実行するには、deferとrecover()を使えば良さそうです。
どのような動きになるのか、パラメーターで動作を分けて試してみました。

また、
ログ出力時、メッセージフォーマットを自作するサンプルがあったので、採用してみました。
正常時のログはStdoutへ、異常時はStderrへ出力したいですから、そのあたりも実装してます。
fmt.Fprintf() に標準出力(os.Stdout)、標準エラー(os.Stderr)のファイルディスクリプタを渡します。

さて、実行してみましょう。
実行時パラメータ無しで、正常終了します。

$ (コマンド) 2>./stderr.log 1>./stdout.log

などとやれば、stderr.log には、何も出力されず、
stdout.log にログが出力されます。

failureパラメータをつけると、異常時の動作を確認できます。
(実際にはこんなパラメータは要らないですが...)

$ (コマンド) --failure 2>./stderr.log 1>./stdout.log

stderr.log で、deferに指定した処理が実行されたことがわかります。
stdout.logには出力されません。

何か異常があれば、すぐにpanic()を起こしてrollbackしてしまいましょう。

20
20
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?