Over a million developers have joined DZone.

Go Exposed: How Remote Import Paths Work

One of the confusing and not well-documented aspects of Go is the way remote import paths work. That is, how do the naming conventions tell Go how to get from the right remote locations? Let's take an in-depth look at how this works.

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

One of the confusing and not well-documented aspects of Go is the way remote import paths work. That is, how do the naming conventions tell Go how to get from the right remote locations? In Glide, we have chosen to keep compatibility with go get based names. This has turned out to be one of the areas where we get the most questions and see the most confusion. If you've run into a problem, you're not alone.

Remote package names have a few steps to resolve the location and version control system. Go does support Git, SVN, Bzr, and Hg, meaning the type of VCS matters.

First, Go (as of 1.6) looks at a list of hosts and patterns to detect the location and VCS. This list allows it to detect locations on:

  • Google Code (this should hopefully redirect somewhere else now that it's deprecated but not always)
  • GitHub (e.g., github.com/foo/bar)
  • Bitbucket (e.g., bitbucket.org/foo/bar)
  • IBM DevOps Services (JazzHub) (e.g., hub.jazz.net/git/foo/bar)
  • Git on Apache
  • Imports ending in .git, .svn, .bzr, and .hg. That means example.com/foo.git or example.com/foo.git/bar will be detected.

During some of these phases, such as checking Bitbucket which can host repos of varying types, Go may reach out to a known API to find out the type.

If none of these work, Go moves to a second detection phase. If the path is a URL it will append ?go-get=1 to the end and perform a GET request to it. It's looking for an HTML (XML really) document containing a meta tag with a name of go-import. The value of this has the root package, VCS type, and VCS location to use.

For example, the import gopkg.in/yaml.v2 causes Go to do an HTTP get on https://gopkg.in/yaml.v2?go-get=1 which returns:

<meta name="go-import" content="gopkg.in/yaml.v2 git https://gopkg.in/yaml.v2">
<meta name="go-source" content="gopkg.in/yaml.v2 _ https://github.com/go-yaml/yaml/tree/v2{/dir} https://github.com/go-yaml/yaml/blob/v2{/dir}/{file}#L{line}">
go get gopkg.in/yaml.v2

Note, Go does some security checks on this. If you want to dig through the code, you'll see them.

From this, any tooling can see it should fetch the package gopkg.in/yaml.v2 using git from https://gopkg.in/yaml.v2.

If you want a more interesting example, you can try golang.org/x/net/context. The import for that reads:

<meta name="go-import" content="golang.org/x/net git https://go.googlesource.com/net">

Here you can see that the root package golang.org/x/net (the repo) is available via git at https://go.googlesource.com/net.

Finally, if this fails there is one more phase to try and detect via other means. Right now it only tries to detect lanuchpad.net (e.g., imports like launchpad.net/foo/bar). This third phase (instead of keeping this as part of the first phase) is to allow some to transition to meta tag support (step 2).

If you want to dig further into this detection you can start reading the repoRootForImportPath function inside Go.

Glide respects these same naming conventions to allow for clean transitions with go get.

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.


Published at DZone with permission of Matt Farina, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}