A few questions by a newby mostly about initial structure

I’ve just started playing with Go and I have a few questions which are mostly to get a good structure to start with so I’m going forward with good practices for the language. I have read both the official documentation, not in full - I’m trying to take things in small chunks, and some people suggesting best practices based on experience through searches.

Q1: The first documentation I came across talking about splitting externals from your own code by setting GOPATH to something like: $HOME/Go/external:$HOME/Go/internal and by doing so all code will automatically download into $HOME/Go/external since it’s the first on the path.

However, now I am seeing that as of version 1.5 (I am using 1.7) you can just put a vendor folder in you project path and Go will put all externals in the vendor directory.

Does this make the use of $HOME/Go/external obsolete or am I confusing two separate issues with each other? I’m from the Drupal community and the vendor folder is anything pulled from projects external to Drupal’s own code base.

Q2: If you look at my basic structure below you can see that my projects are diycs/sc & diycs/scsims. Does this mean I should put a vendor folder at diycs/sc/vendor and diycs/scsims/vendor? Or, should there be a vendor folder for each package that has vendor dependencies such as “diycs/sc/server/vendor”?

Q3: Part of the reason for Q2 is I am a little uncertain about exactly what is a project folder. My understanding is that anything at the level of src/author/project is a project. Is this correct?

Q4: I am using the liteide for Go development. Whenever I create a package it creates two files as you can see from the tree below one file is always doc.go. Is this something that I am required to manually fill out… I’m just trying to ascertain why it’s put there automatically. If so, usually we document what’s in a source code file from within the file so what does this file add?

My current structure that I am asking about:

    ├── external
    │     └── src
    └── internal
          └── src
              └── diycs
                  ├── sc
                  │   ├── cmd
                  │   │   └── runsims
                  │   │       ├── doc.go
                  │   │       ├── main.go
                  │   │       └── runsims
                  │   ├── pkg
                  │   │   └── server
                  │   │       ├── doc.go
                  │   │       ├── http.go
                  │   │       └── server.go
                  │   └── vendor
                  └── scsims
                      ├── cmd
                      │   └── runsims
                      │       ├── doc.go
                      │       └── main.go
                      ├── pkg
                      │   └── sims
                      │       ├── doc.go
                      │       └── sims.go
                      └── vendor

Finally, I would like to offer an improvement (for Linux users) to the recommendations on how to setup GOPATH and PATH in a few shell lines which is below. Admittedly, I’m just gettting started it may be flawed because of things I don’t know yet:

# In ~/.profile
# These are for "Go"
# Adjust absolute path suit your needs
GoPP=$HOME/Jobs/Go # PP = PathPrefix.

# Adjust subpaths and alternate paths to suit your needs.
# My installation automatically added /usr/share/go/contrib, not
# sure it's use yet but others will probably not want it.
export GOPATH=$GoPP/external:$GoPP/internal:/usr/share/go/contrib 

# This sets path for bin file taking into account having multiple 
# paths in GOPATH
export PATH=$PATH:$(echo $GOPATH|sed 's#:#/bin:#g')/bin

# Some features (at least through liteide) don't like src missing 
# so make sure they all exist.
srcPath=$(echo $GOPATH|sed 's#:#/src #g')/src
mkdir -p $srcPath
1 Like

Hi @Reg,

Welcome to Go :slight_smile:

Let me try giving some answers.


I am not useing a “split GOPATH” myself, so I cannot advise on this, nor did I find a suitable answer on the net. My personal feeling is that a two-part GOPATH would not provide additional benefit to using vendoring. But that’s just my point of view, not backed by any practical experience with this combination.


There is a thread here in the forum that seems to summarize the question very well. (TL;DR: flatten the vendor directory. Use vendoring only for main projects, not for libraries.)


I certainly cannot speak for all of the community, but I have seen others proposing the following approach:

  • If your project is a library, put the library packages at top level and move any commands that you might add to your library to a subfolder, e.g. cmd.

    E.g., if your library project is named mylib and has a sub-package server, then put the mylib package on top, and any sub-packages and any commands beneath:

                ├── mylib
                │   ├── mylib.go
                │   ├── asubpackage
                │   │├── http.go
                │   │└── server.go
                │   ├── cmd
                │   │   └── cmdone
                │   │       └── main.go
                │   │   └── cmdtwo
                │   │       └── main.go
                │   │   └── vendor

Here you get a library that can be imported as diycs/mylib, and two commands named cmdone and cmdtwo.

  • If your project is an executable, put the main package at the top of the project.

                ├── myexec
                │   ├── main.go
                │   ├── anothermainpkgfile.go
                │   └── somepackage
                │   │ ├── somepackage.go
                │   ├── someotherpkg
                │   │├── http.go
                │   │└── server.go
                │   └── vendor

This creates a command named myexec that uses the two packages somepackage and someotherpkg for itself.


Go has support for auto-generating documentation from source files. If the documentation you write belongs to the package as a whole, you can put it in a separate file named doc.go (but this is optional). See this post on the Go blog for an introduction to Go documentation.

I have no idea why LiteIDE creates a doc.go file by default. Maybe they simply want to enforce proper documentation behavior. :slight_smile:


Hi @christophberger,

This was an outstanding reply. Thanks a whole lot!


1 Like

Any time! :slight_smile:

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.