GOLANG

Anatomy of Modules in Go

Modules are a new way to manage dependencies of your Go project. Modules enable us to incorporate different versions of the same dependency without breaking the application.

Uday Hiwarale
May 4, 2019 · 24 min read
Image for post
Image for post
(source: pexels.com)
import "github.com/username/packagename"
go get github.com/username/packagename

➪ Read tutorial on Go packages from here.

go get domain.com/path/to/sub/directory
Bazaar        .bzr
Fossil .fossil
Git .git
Mercurial .hg
Subversion .svn
Bitbucket              (bitbucket.org)     .git/.hg
GitHub (github.com) .git
Launchpad (launchpad.net) .bzr
IBM DevOps Services (hub.jazz.net) .git
<meta name="go-import" content="import-prefix type repo-root">
  • type: This is the type of your VCS repository. It can be one of the supported types mentioned earlier. In our case, it could be a Git repository, hence git is the type.
  • repo-root: This is the URL where the VCS repository is located. This should be a fully qualified VCS repository. For example, in our case, it could be https://domain.com/repos/name.git . This git the extension type is optional as we already mentioned the type as git.
Image for post
Image for post
(Source code of a repository page hosted on GitHub)
go get domain.com/some/sub/directory
<meta name="go-import" content="domain.com/someother/sub/directory git https://domain.com/repos/name.git">
import "domain.com/someother/sub/directory"
  • We should be able to install the precise version of a dependency package to avoid breaking changes.
  • We should be able to import multiple versions of the same dependency package. This is useful when our old application code is running with the old version of the dependency but we would like to use the new version of the dependency package for any new developments.
  • Like package.json in NPM, we need a file that can list the dependencies of our project. This is helpful because when you distribute your project, you don’t need to distribute your dependencies with it. Go can just look at this file and download the dependencies for you.
  • A Go module should contain one or more packages
  • A package should contain one or more .go files in a single directory.
Image for post
Image for post
Image for post
Image for post
https://github.com/thatisuday/nummanip
Image for post
Image for post
go mod init github.com/thatisuday/nummanip
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
GitHub provides information about tag inside the Releases section.
Image for post
Image for post
Image for post
Image for post
go.mod file
Image for post
Image for post
($GOPATH/pkg/mod)
Image for post
Image for post
go.sum file
Image for post
Image for post
Add is not variadic function
Image for post
Image for post
update Go modules
Image for post
Image for post
$GOPATH/pkg/mod

Upgrading to a Major Version

Now the time has come to explain why Go only automatically resolves only v1.x.x versions of a dependency module or why go get -u updates only modules within the current major version.

Image for post
Image for post
incompatible changes in the Add function
Image for post
Image for post
Image for post
Image for post
(installing v2)
Image for post
Image for post
go.mod file
Image for post
Image for post
module cache

Run and Build Executable Module

When you are working on an executable module, you can run the module by using go run . command or run individual files using go run path/*.go command which I have explained in my packages tutorial.

Indirect Dependencies

We have used the “Indirect Dependencies” term before but haven’t explained yet. Well, Indirect Dependencies as they sound aren’t direct dependencies to our module. Direct dependencies are those which our module imports while indirect dependencies are those which direct dependencies import.

Image for post
Image for post
(direct vs indirect dependencies)

Minimal Version Selection

From what we have learned so far, we can import multiple versions of the same dependency modules but as long as they are major release versions.

Image for post
Image for post
Dependency Copy Problem
Image for post
Image for post
Diamond Dependency
Image for post
Image for post
Final Verdict with Minimal Version Selection

BONUS TIPS

Local Development

When you develop a module that is supposed to be consumed as a public library, you should always write test cases to make sure every exported API is working as expected. You should follow this article to write test cases.

// nummanip/transform/program.go
package transform
import "fmt"
import "github.com/thatisuday/nummanip/calc"
func SomeFunc() {
fmt.Println( calc.Add(1,2) ) // 3
}
module maingo 1.13require github.com/thatisuday/nummanip v1.0.1replace github.com/thatisuday/nummanip => /path/to/local/nummanip
go mod edit -replace "github.com/thatisuday/nummanip=/path/to/local/nummanip"

Tidy Module

If you have a module that you wish to publish but its go.mod file does not track the dependencies that might have been imported inside the source code then you should run go mod tidy command.

Vendoring Dependencies

Sometimes, when you are running automated tests for your project (executable module like main in our case), there is a chance that your test machine may face some network issues while downloading the dependencies or when a test machine is running in an isolated environment.

Installing CLI modules

To install a CLI application (module) from anywhere in the terminal, use the following command.

$ GO111MODULE=on go install <package>@<version>
Image for post
Image for post

RunGo

A go-to guide for learning Go programming language

Uday Hiwarale

Written by

Senior Software Engineer / thatisuday.com ☯ github.com/thatisuday ☯ thatisuday@gmail.com

RunGo

RunGo

A place to find introductory Go programming language tutorials and learning resources. In this publication, we will learn Go in an incremental manner, starting from beginner lessons with mini examples to more advanced lessons.

Uday Hiwarale

Written by

Senior Software Engineer / thatisuday.com ☯ github.com/thatisuday ☯ thatisuday@gmail.com

RunGo

RunGo

A place to find introductory Go programming language tutorials and learning resources. In this publication, we will learn Go in an incremental manner, starting from beginner lessons with mini examples to more advanced lessons.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store