title: Go modules, private repos and gopath
body: <p>We are converting our internal codebase from the <code>dep</code> dependency manager to go modules (<code>vgo</code> or built in with go1.11.2). Imagine we have code like this:</p>
  
  <p><em>$GOPATH/src/mycompany/myprogram/main.go:</em></p>
  
  <pre><code>package main
  
  import (
          "fmt"
          lib "mycompany/mylib" )
  
  func main() {
          fmt.Println("2+3=", lib.add(2, 3)) 
  }
  </code></pre>
  
  <p><em>$GOPATH/src/mycompany/myprogram/go.mod:</em></p>
  
  <pre><code>module mycompany/myprogram
  </code></pre>
  
  <p>(it doesn't have any dependencies; our real-world code does).</p>
  
  <p><em>$GOPATH/src/mycompany/mylib/lib.go:</em></p>
  
  <pre><code>package mylib
  
  func Add(x int, y int) int {
          return x + y
  }
  </code></pre>
  
  <p>I didn't module-ize this code; it doesn't seem to matter whether I do or don't.</p>
  
  <p>These are trivial examples but our internal code follows a similar structure as this worked historically.</p>
  
  <p>Since these directories are on the Gopath, <code>export GO111MODULE=auto</code> still builds as before and this works fine (modules not used because we are on the gopath). However, when I set <code>export GO111MODULE=on</code> I immediately get the error:</p>
  
  <pre><code>build mycompany/myprogram: cannot find module for path mycompany/mylib
  </code></pre>
  
  <p>So I did some research and I would like to validate my understanding. First let me say our old approach worked, but I am more interested in changing to use go modules as it appears to be where the go project itself is headed. So.</p>
  
  <ol>
  <li><p>It seems the intention of the golang authors was that "dotless" paths belong to the standard repository only; that is there should be a binding between domain name and project. We don't use go get on our internal project, unsurprisingly. <a href="https://github.com/golang/go/issues/27503#issuecomment-418859602" rel="noreferrer">Here is the source</a> specifically:</p>
  
  <blockquote>
    <p>Dotless paths in general are reserved for the standard library; go get has (to my knowledge) never worked with them, but go get is also the main entry point for working with versioned modules.</p>
  </blockquote>
  
  <p>Can anyone with more knowledge of golang than me confirm this?</p></li>
  <li><p><strong>My key assumption</strong> is that once go decides to use modules, <strong>all</strong> dependencies must be modules and the gopath becomes somewhat irrelevant, except as a cache (for downloaded modules). Is this correct?</p></li>
  <li><p>If this is true, we need to use a private gitlab (in our case) repository on the path. <a href="https://github.com/golang/go/issues/26134" rel="noreferrer">There's an open issue on handling this that I'm aware of</a> so we can implement this if necessary. I'm more interested in the consequences, specifically for iterating in the private repositories. Previously we could develop these libraries locally before committing any changes; now it seems we have a choice:</p>
  
  <ol>
  <li>Accept this remote dependency and iterate. I was hoping to avoid needing to push and pull remotely like this. There are workarounds to needing an internet connection if strictly necessary.</li>
  <li>Merge everything into one big git repository.</li>
  </ol></li>
  </ol>
  
  <p>If it matters, I'm using <code>go version go1.11.2 linux/amd64</code> and my colleagues are using <code>darwin/amd64</code>. If it helps, my golang is exactly as installed by Fedora's repositories.</p>
  
  <p>So, <code>tl;dr</code>, my question is: are go modules all-or-nothing, in that any dependency must be resolved using the module system (go get, it seems) and the gopath has become redundant? Or is there something about my setup that might trigger this to fail? Is there some way to indicate a dependency should be resolved explicitly from the gopath?</p>
  
  <p><strong>Updates since asking the question</strong>:</p>
  
  <ol>
  <li>I can move <code>myprogram</code> out of the gopath. The same issue occurs (<code>mylib</code> has been left in the gopath).</li>
  <li>I can run, or not run, <code>go mod init mycompany/mylib</code> in the mylib directory; it makes no difference at all.</li>
  <li>I came across <a href="https://research.swtch.com/vgo-module" rel="noreferrer">Russ Cox's blog post on vgo</a>. My concerns about offline development that I tried not to dive into too far are resolved by <code>$GOPROXY</code>.</li>
  </ol>