【追記】AppEngine Goで、go-app-builder: Failed parsing input: app file users.go conflicts with same file imported from GOPATH と叱られる問題
問題
AppEngineなアプリケーションをGoで開発していて、もちろんコントローラとかモデルとかは、init
があるところとは別のディレクトリ切って作ったりするんだけど、意気揚々とgoapp serve ./
すると以下のように叱られる
% goapp serve ./ # 中略 ERROR 2016-05-07 16:19:44,645 go_runtime.py:179] Failed to build Go application: (Executed command: /Users/otiai10/.gcp/go_appengine/goroot/bin/go-app-builder -app_base /Users/otiai10/proj/go/src/github.com/otiai10/foo -arch 6 -dynamic -goroot /Users/otiai10/.gcp/go_appengine/goroot -nobuild_files ^^$ -unsafe -gopath /Users/otiai10/proj/go -print_extras_hash app/main.go app/controllers/citation.go) 2016/05/07 18:19:44 go-app-builder: Failed parsing input: app file users.go conflicts with same file imported from GOPATH
調査
- google app engine - How to import local Golang package in GAE - Stack Overflow
- google app engine - Go Package Conflict - Stack Overflow
- go - Good way to use and test local packages in Google App Engine apps written in golang? - Stack Overflow
- Go Runtime Environment - Go — Google Cloud Platform
- go - Golang how to import local packages without gopath? - Stack Overflow
- Google Go AppEngine imports and conflicts when serving / testing - Stack Overflow
- "This will cause two imports, one by appengine when it scans the directories, and a second by your source when it is explicitly imported."
appengineによるimportと、そこでimportされたソースコードによるimport(自分のケースだとmain.go
がimport
してる)が、同じファイルをimport
しようとしているっぽい。
解決
import "myproject/handler"
ベンダー込みの$GOPATH/src/github.com/otiai10/foo/controllers
ではなくて、app.yaml
から見た相対pathを以下のように書く
import ( "net/http" - "github.com/otiai10/foo/app/controllers" + "app/controllers" )
この際、
"./app/controllers"
であってもgoapp
は動かない。でもapp/controllers
にしなきゃならんので、govetから以下のように叱られる。
cannot find package "app/controllers" in any of: 以下いつもの
うーん... appengineなruntimeからではないビルドを除外するために、controllers/users.go
の冒頭に以下を加えても同じ
+// +build appengine +
このwarningうざいんだけど、とりあえず動くからこの方向で行く
DRY
追記: 2016/05/09
goappによって2重インストールになってしまう問題は上記のように解決したけれど、cannot find packageになってしまうのはじゃっかんうざいので、以下のように、app.yaml
とimport
する側のmain.go
があるところ、importされるsrc
があるところを分けたことによって解決した。
foo ├── README.md ├── app │ ├── app.yaml │ └── main.go └── src ├── controllers │ ├── users.go │ └── index.go
で、起動は
goapp serve ./app/app.yaml # または # goapp serve app # これでもちゃんと ./app/app.yaml をさがしてくれる
DRY