Goのパッケージを作っていく手順(コマンドラインツールを作る)

# パッケージ作りたい

ということで、パッケージを作ってgithub.comまで登録する手順を。
(チュートリアルで書かれてるとは思うけれど...)
どういう感じになるのかなぁと思い、[fizzbuzz-go](https://github.com/futoase/fizzbuzz-go)というものをサンプルとして作りました。
fizzbuzz-goのパッケージを作る前提で、書いておきます。

# Goをインストールする

はい。
```brew install go``` とかでインストールしてください。

# $GOPATHを設定している

はい。適当なディレクトリを設定してください。

# パッケージ用のディレクトリを作成する

github.comを使ってることを前提とします。(使ってますよね)

```
$GOPATH/src/github.com/github-user-name/package-name
``` 

```$GOPATH/src``` ディレクトリ以下にパッケージを作成していきます。
コマンドとしては、以下の形でディレクトリを作成します。

```
> mkdir -p $GOPATH/src/github.com/hogehoge/package-name
```

fizzbuzz-goの場合は以下の形でディレクトリを作成しました。

```
> mkdir -p $GOPATH/src/github.com/futoase/fizzbuzz-go
```

# main packageを作成する

fizzbuzz-goはコマンドラインツールなので、
```package main``` を作成し、且つエントリポイントとなる
ファイルを定義します。

```main.go``` をエントリポイントとして利用します。

```go:main.go
package main

import (
  "fmt"
  "flag"
)

var n *int = flag.Int("n", 100, "Setting last position. (default is 100)")

func main() {
  flag.Parse()
  for i := 1; i <= *n; i++ {
    fmt.Println(i, FizzBuzz(i))
  }
}
```

# FizzBuzz関数を作成する

FizzBuzzの表示はFizzBuzz関数に任せます。

```go:fizzbuzz.go
package main

import "strconv"

func FizzBuzz(i int) string{
  if i % 3 == 0 && i % 5 == 0 {
    return "FizzBuzz"
  } else if i % 3 == 0 {
    return "Fizz"
  } else if i % 5 == 0 {
    return "Buzz"
  }
  return strconv.Itoa(i)
}
```

# テストを書く

テストが無いのはやばいのでテストを書きます。
今回はコマンドラインツールとして利用し、
且つ自分自身をパッケージとして使い、エントリポイントを定義するため、
```package main``` にテストコードを追加します。

```go:fizzbuzz_test.go
package main

import (
  "testing"
  "strings"
)

func TestFizz(t *testing.T) {
  if !strings.EqualFold("FizzBuzz", FizzBuzz(15)) {
    t.Errorf("Correct! Wow, I hope require FizzBuzz") 
  }
  if !strings.EqualFold("Fizz", FizzBuzz(3)){
    t.Errorf("Correct! Wow, I hope require Fizz") 
  }
  if !strings.EqualFold("Buzz", FizzBuzz(5)){
    t.Errorf("Correct! Wow, I hope require Buzz") 
  }
  if !strings.EqualFold("98", FizzBuzz(98)){
    t.Errorf("Correct! Wow, I hope require 98") 
  }
}
```

## ```go test``` を実行

テストを実行してみます。

```
> go test
```

テストが通った！

![スクリーンショット 2013-10-14 13.14.04.png](https://qiita-image-store.s3.amazonaws.com/0/3985/a8c50562-fffd-868d-2378-081070dd4680.png)

通らない形に書き換えて、問題ないか確認。

```go:fizzbuzz_test.go
package main

import (
  "testing"
  "strings"
)

func TestFizz(t *testing.T) {
  if !strings.EqualFold("FizzBuzz", FizzBuzz(16)) {
    t.Errorf("Correct! Wow, I hope require FizzBuzz") 
  }
  if !strings.EqualFold("Fizz", FizzBuzz(4)){
    t.Errorf("Correct! Wow, I hope require Fizz") 
  }
  if !strings.EqualFold("Buzz", FizzBuzz(8)){
    t.Errorf("Correct! Wow, I hope require Buzz") 
  }
  if !strings.EqualFold("98", FizzBuzz(100)){
    t.Errorf("Correct! Wow, I hope require 98") 
  }
}
```

go testを実行。

```
> go test
```

![スクリーンショット 2013-10-14 13.15.53.png](https://qiita-image-store.s3.amazonaws.com/0/3985/2474e2e3-5309-e38e-74ca-1240d50e86fa.png)

テストがコケることを確認。

# go installを行う

github.com/futoase/fizzbuzz-goをインストールします。

```
> go install github.com/futoase/fizzbuzz-go
```

```$GOPATH/bin``` にカレントディレクトリを移動します。

```
> cd $GOPATH/bin
> ls
fizzbuzz-go
```

パッケージ名のコマンドが、```$GOPATH/bin``` にできているのが確認できました。

# github.comにpush

```github.com``` に作ったパッケージのリポジトリを作り、pushします。

```
> git init
> git add .
> git commit -m "Initial import."
> git remote add origin hogehoge~~
> git push -u origin master
```

# TravisCIとの連携

github.comに作ったリポジトリ、publicなものにしてるし、
せっかくなので```.travis.yml``` ファイルを作成し、TravisCIと連携させます。

```yaml
language: go
go:
  - tip
install:
  - go get github.com/futoase/fizzbuzz-go
script:
  - go test -v
```

```git add . && git commit && git push``` をし、
パッケージを登録したgithubのリポジトリとTravisCIをApplication連携させるよう設定すればOK。

# 今後は

今後は、github.comからソースを持ってくることになるので、
go get コマンドでインストールする形になります。

```
> go get github.com/futoase/fizzbuzz-go
```

# fizzbuzz-go実行方法

```$GOPATH/bin``` にPATHが通っていれば、

```
> fizzbuzz-go
> fizzbuzz-go -n 1000
```

で実行ができます。