DRYな備忘録

Don't Repeat Yourself.

【追記】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

調査

appengineによるimportと、そこでimportされたソースコードによるimport(自分のケースだとmain.goimportしてる)が、同じファイルを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.yamlimportする側の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