How to Use Vendoring with Go Modules

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setup
  4. Using Vendoring with Go Modules
  5. Example
  6. Conclusion


Introduction

In this tutorial, we will learn about using vendoring with Go Modules. Vendoring is a technique used in Go to manage dependencies more effectively. By the end of this tutorial, you will understand how to utilize vendoring to include and manage external packages in your Go project.

Prerequisites

To follow along with this tutorial, you should have a basic understanding of the Go programming language and be familiar with Go modules. You should also have Go installed on your machine.

Setup

Before we begin, let’s ensure that Go modules are enabled:

export GO111MODULE=on

This command instructs Go to use modules for dependency management.

Using Vendoring with Go Modules

Go modules allow us to manage dependencies without relying on the $GOPATH environment variable. Instead, dependencies can be resolved based on the go.mod file in the project’s root directory. However, sometimes it may be necessary to have fine-grained control over the dependencies, especially when working with projects that require specific versions or have strict compatibility requirements.

Vendoring allows us to achieve this level of control. When vendoring is enabled, the Go build system looks for dependencies not only in the module cache but also in a local vendor directory within the project.

To enable vendoring, we need to set the GOFLAGS environment variable:

export GOFLAGS="-mod=vendor"

This tells Go to prioritize the vendor directory for dependency resolution.

Example

Let’s illustrate how to use vendoring with Go Modules with a simple example. Assume we have a project named myapp with the following directory structure:

myapp/
├── go.mod
├── main.go
└── vendor/
    └── github.com/
        └── example/
            └── package/
                └── package.go

To start, create the go.mod file in the root of the myapp directory:

cd myapp
go mod init

This will initialize a new Go module.

Next, create a simple main.go file with the following code:

package main

import (
	"fmt"
	"github.com/example/package"
)

func main() {
	fmt.Println(package.SayHello())
}

Now let’s create the package.go file within the vendor/github.com/example/package directory:

mkdir -p vendor/github.com/example/package
echo 'package package

func SayHello() string {
	return "Hello, World!"
}' > vendor/github.com/example/package/package.go

Now that we have our files in place, we can build and run our application:

go build
./myapp

You should see the output Hello, World! printed to the console.

By using vendoring, we included the github.com/example/package package directly in our project’s vendor directory. This ensures that the correct package version is used, regardless of changes in the remote repository.

Conclusion

In this tutorial, we learned how to use vendoring with Go Modules. We saw how to enable vendoring and include external packages within the project’s vendor directory. By using vendoring, we gain control over our dependencies, ensuring that the correct package versions are used. This allows us to easily manage and share projects with specific dependencies.