32

I am working on a new project using Go, and we are all new to Go. We are following the standard go directory structure, and having all code under

$GOPATH/src/github.com/companyname/projectname

which is also the root of a git repository

The standard recommended path layout does seem a bit strange, especially if we are working on a multi-language project, e.g. a Go based rest/http backend, and an html/javascript front-end. In that case I would probably want my project structure to look like this:

/
  doc/
  src/
    server/
      main.go
      module1/
        module.go
    client/
      index.html
  Makefile

But is it actually necessary to have the code placed inside the GOPATH?

As an attempt I created a small program where the source code was outside the GOPATH. I could easily split the project into packages, so the main package could reference a foo package in a foo/ folder using import "./foo".

As far as I can see, there are two things this disallows me:

  • Other code cannot import this code. This is not a problem as we are building a service specifically for the company.
  • I cannot use go install to install it. This is not a problem either. The build pipeline installs the tool.

It does however allow the build server to not have its workspace be located inside the GOPATH

Is such an approach discouraged? If so, why so?

Are there other negative side effects than the two I have listed?

Bear in mind that this is a private project for a company, not public open source code.

Detaching the actual project from the GOPATH seems tempting, but one should be careful in breaking the rules when you are on the Shu stage

12

You are not required to use GOPATH, but then you miss out on all the nice tooling that you get from the go command. They all expect code to be in the standard GOPATH hierarchy.

You mentioned go install, but also go test (and the nice go test -cover coverage tool) won't work go get, which allows you to download remote code will write everything to the GOPATH, so you will need to copy things over.

Sure, you can replace it all with make/scons/cmake/whatever and get things done and it will likely work for your environment, but its extra work that could be done by the go tool.

9

(disclaimer: I like designing stuff like this but I'm new to Go, I haven't tried it in practice)

Idea: Why not both?

There are two polar options available if you take symlinking into account:

(A) Code in src, symlinked to workspace

/
  doc/
  src/
    server/
      projectname/
    client/
      index.html
  go_workspace/
    src/
      companyname/
        projectname -> ../../../src/server/projectname
      github.com/
        someone/
          library/
    bin/
    pkg/
  Makefile

(B) Code in workspace, symlinked to src

/
  doc/
  src/
    server/
      projectname -> ../../go_workspace/src/companyname/projectname
    client/
      index.html
  go_workspace/
    src/
      companyname/
        projectname/
      github.com/
        someone/
          somelib/
    bin/
    pkg/
  Makefile

I'd lean towards "A" because:

  • all your sources live close together physically,
  • projectname can easily have its own repo, or you can have one repo for your whole project,
  • you can keep whole go_workspace unversioned and initialize it through a make step (using godep then symlinking the project)
  • 1
    It has to be "A", since with "B" go will complain "go install: no install location for directory {dir} outside GOPATH". – OJFord Jan 18 '17 at 14:30
2

2019 Update

You don't need to store your project under GOPATH anymore.

Just put it in any directory outside of GOPATH. Then type:

go mod init github.com/youruser/yourproject

You'll be good to go.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.