36

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

3 Answers 3

7

2019 Update

You no longer need to store your project under GOPATH.

Put it in a directory outside of GOPATH. Then type:

go mod init github.com/youruser/yourproject

You'll be good to go.

1
  • What if you have not intention of using github here? Jan 31, 2022 at 19:44
13

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
  • 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, 2017 at 14:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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