Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Go AppEngine imports and conflicts when serving / testing

So I have spent the better part of two days trying to figure this one out and no matter what I do I can't get things straightened out. Here is what is going on:

  • Using Go and Appengine. I am running into issues when trying to get proper unit tests working.
  • I have tried lots of structures but here is a sample of where I am now: https://github.com/markhayden/SampleIssue
  • I am running into dependency issues in either goapp serve or goapp test -v ./src/lib1 depending on how I have my import paths set.

If I use "src/lib1" for my import path and then goapp serve. My app boots and runs fine, but when I run tests I get the following failure:

src/lib1/lib1.go:5:2: cannot find package "src/lib2" in any of:
    /Users/USERNAME/go_appengine/goroot/src/pkg/src/lib2 (from $GOROOT)
    /Users/markhayden/Projects/go/src/src/lib2 (from $GOPATH)

Likewise, if I use "dummy/src/lib1" as my path, my tests are happy and run fine but upon goapp serve ing the app I now get:

2014/11/06 20:33:34 go-app-builder: Failed parsing input: app file lib1.go conflicts with same file imported from GOPATH

Have fiddled with all sorts of different options and can't figure out how to handle dependencies and still have solid testing. Maybe its a appengine / golang bug? Or am I missing something?

Any help would be very much appreciated. Thanks in advance!


Updated everything based on first comment feedback. I can run tests (as I was able to do before) but I still can not serve the app. Here is what I get when running goapp serve

INFO     2014-11-07 17:24:48,727 devappserver2.py:745] Skipping SDK update check.
INFO     2014-11-07 17:24:48,748 api_server.py:172] Starting API server at: http://localhost:60732
INFO     2014-11-07 17:24:48,751 dispatcher.py:185] Starting module "default" running at: http://localhost:8080
INFO     2014-11-07 17:24:48,754 admin_server.py:118] Starting admin server at: http://localhost:8000
ERROR    2014-11-07 17:24:49,041 go_runtime.py:171] Failed to build Go application: (Executed command: /Users/markhayden/go_appengine/goroot/bin/go-app-builder -app_base /Users/markhayden/Projects/go/src/github.com/markhayden/SampleIssue -arch 6 -dynamic -goroot /Users/markhayden/go_appengine/goroot -nobuild_files ^^$ -unsafe -gopath /Users/markhayden/Projects/go -print_extras_hash lib1/lib1.go lib2/lib2_test.go main_test.go main.go lib1/lib1_test.go lib2/lib2.go)

2014/11/07 09:24:49 go-app-builder: Failed parsing input: app file lib2.go conflicts with same file imported from GOPATH

$GOPATH = /Users/markhayden/Projects/go $GOROOT = not set (according to docs it doesnt need to be if you dont use a custom directory)

App Structure:

$GOPATH/src/github.com/markhayden/SampleIssue/
 - app.yaml
 - /lib1
    - lib1_test.go
    - lib1.go
 - /lib2
    - lib2_test.go
    - lib2.go
 - main_test.go
 - main.go

In main.go:

import (
    "fmt"
    "github.com/markhayden/SampleIssue/lib1"
    "net/http"
)

In lib1/lib1.go:

import (
    "fmt"
    "github.com/markhayden/SampleIssue/lib2"
)
like image 894
Mark Hayden Avatar asked Nov 07 '14 04:11

Mark Hayden


1 Answers

Appengine "conflicts with same file imported from GOPATH" issue:

Appengine is importing things underneath the root directory (i.e. where the app.yaml is). This will cause two imports, one by appengine when it scans the directories, and a second by your source when it is explicitly imported.

You have two choices:

Don't use the full import path (for sub-folder packages) with appengine.

  • Remove the source repository part of import. So instead of "github.com/blah/blah" it would be "blah/blah".

    Note: This kinda sucks as it makes your build and software appengine specific. You could make this a little better -maybe- by using build constraints. e.g. +build !appengine or +build !appengine to include/remove certain files from the build depending on if you are targeting appengine.

Move your modules/dependencies (sub-folders) to a separate and independent project to make it work with the full path import convention:

  1. Get rid of all directories / dependencies in the main project (where your app.yaml is), so that appengine can't scan and find them.
  2. Move them to another independent project (I did SampleIssueDeps) with no app.yaml that is not a sub-directory (e.g. /MarkHayden/SampleIssueDeps).
  3. Then pull those dependencies via full path import. e.g. github.com/MarkHayden/SampleIssueDeps/lib1.

Summary: For sub-folder packages in an appengine project don't include the "source repository" part of the import path OR only use appengine to init() and move all of your other code to separate projects and use like external dependencies.

like image 150
Matt Self Avatar answered Oct 04 '22 23:10

Matt Self