Golang - ディレクトリ構成と独自パッケージのimportについて

<font color="DeepPink">追記：GoModules（バージョン管理）を使用した場合の方法を整理しましたのでGoのバージョンが1.11以上の方はそちらを参照してください</font>
[Golang - Go Modulesで開発環境の用意する](https://qiita.com/so_heee_/items/56f5317b42cec3d94383)

## はじめに
環境作成の際に、深く考えず環境変数 `$GOPATH` に `~/go` を設定していましたが、作業していると自身で定義したパッケージの参照でエラーが発生し、保存時にフォーマットかけるようにしてるためimportが消えたりと思ったような動作をしなかったため構成を見直すことにしました。


## GOPATH
パッケージをimportするときの解決先や、`go get`や`go install`をしたときのパッケージやバイナリのインストール先がGOPATHで指定したディレクトリになります。GOPATH配下は以下の三つのディレクトリで構成されます。

ちなみにGOPATHが未指定の場合は`$HOME/go`になります。

```bash
./GOPATH
├── ./bin    // 実行ファイルが格納されるディレクトリ（go installコマンドで自動生成されます）
├── ./pkg    // ビルドしたパッケージオブジェクトが格納されるディレクトリ（go buildをはじめとする各種コマンドで自動生成されます）
└── ./src    // パッケージごとのソースコードを配置するディレクトリ
```


## ディレクトリ構成
src配下にプロジェクトのディレクトリを配置することろまでは間違いなさそうですが、どうやら`src/github.com/username/project`で作成するのが良さそうです。
ずっと悩んでいたのですが以下の記事のおかげで解決できました！！

[独自パッケージのインポート](https://qiita.com/lp-peg/items/9f7da97d9f7292f16fbc)

githubに公開されている外部パッケージを取得する際に`go get github.com/XXXXXX`コマンドで取得できますが
そうするとディレクトリの構成が上記の`src/github.com/username/repository`になるようですね！

ということでできた構成が以下の通りです
プロジェクトのディレクトリ配下は [Standard Go Project Layout](https://github.com/golang-standards/project-layout) を参考にしました。

```bash
└── GolangProjects                          // GOPATHに設定
     ├── bin
     ├── pkg
     └── src
         └── github.com
             └── github-username            // githubのユーザー
                 └── project-sample         // プロジェクトごとのディレクトリ
                     ├── Makefile
                     ├── api
                     ├── assets
                     ├── build
                     ├── cmd
                     ├── configs
                     ├── deployments
                     ├── docs
                     ├── examples
                     ├── githooks
                     ├── init
                     ├── internal
                     ├── pkg
                     ├── scripts
                     ├── test
                     ├── third_party
                     ├── tools
                     ├── vendor
                     ├── web
                     └── website
```

## import
上記の構成にした場合、独自パッケージのimportは以下の通りです

```go
import "github.com/github-username/project-sample/パッケージ名"
```

いくつか参考にgithubで公開されているフレームワークを見てみましたが上記の通りになっていました

- [gin-gonic/gin](https://github.com/gin-gonic/gin)
- [astaxie/beego](https://github.com/astaxie/beego)
- [labstack/echo](https://github.com/labstack/echo)
- [kataras/iris](https://github.com/kataras/iris)

## Docker環境の場合
私は以下の環境で開発を行おうかと思っているのですが、そこでもう一点ハマりました。

[Golang - DockerとVSCodeで開発環境を用意する](https://qiita.com/so_heee_/items/1c2e50d3ed6e5ab3845f)

上記構成のproject-sampleで
`Remote-Containers: Add Development Container Configuration Files`
してしまうと以下の理由から独自パッケージのimportでエラーが発生しました

- 仮想環境上のワークスペースがproject-sample以下になってしまう
（github.com/user-name/が参照できない）

リポジトリに反映して`go get`すれば、GOPATHにパッケージがインストールされるのでエラーは解消しますが、それはかなりめんどくさそうと思ったので以下の通りに対応することでとりあえずエラーは回避できました

- GolangProjectsディレクトリで
`Remote-Containers: Add Development Container Configuration Files`

- Docker上のGOPATHにローカルのGOPATHをマウント（workspaceFolderも合わせて変更しています）

```json:devcontainer.json
	"workspaceFolder": "/go",
	"workspaceMount": "src=ローカルの$GOPATH,dst=/go,type=bind",
```

今回かなり手探りで調査したので誤っている点や、もっとこういう構成の方がいいよー！って構成があればぜひ教えていただきたいです！！