Coder Social home page Coder Social logo

tools.mod's Introduction

tools.mod

Go projects may require tools that do not end up being the code running in a production environment, examples include linters for static code analysis or code generation tools.

One common approach to track tool dependencies in Go is the use of a tools.go file, which includes all tools with import statements and using a //go:build tools build constraint. Tool dependencies can also be managed in a separate Go modules file within the same project.

This repository illustrates how to manage your Go tool dependencies using a separate Go modules file which is described in more detail here: https://konradreiche.com/blog/managing-tool-dependencies-with-go-modules

TL;DR

Create a separate Go modules file:

go mod -modfile=tools.mod init 

Add tool dependencies to track, for example staticcheck and sqlc:

go get -modfile=tools.mod honnef.co/go/tools/cmd/[email protected]
go get -modfile=tools.mod ithub.com/kyleconroy/sqlc/cmd/[email protected]

Install dependencies based on the version specified:

go install -modfile=tools.mod honnef.co/go/tools/cmd/staticcheck
go install -modfile=tools.mod github.com/kyleconroy/sqlc/cmd/sqlc

tools.mod

To illustrate this we are going to create a new Go project with one of my two favorite tools:

In this project we want to use staticcheck to lint our code. The specific version used in this project will be tracked in a different Go modules file. Here we call it tools.mod but you can choose a different name.

go mod init -modfile=tools.mod

To add staticcheck as a new tool dependencies we call go get with -modfile=tools.mod specifying the alternative Go modules file.

go get -modfile=tools.mod honnef.co/go/tools/cmd/[email protected]

This will add all of staticchecks' dependencies to the tools.mod file and will generate a tools.sum containing the cryptographic hashes of the content of specific module versions. We repeat this for sqlc.

go get -modfile=tools.mod github.com/kyleconroy/sqlc/cmd/[email protected]

If someone checks out this project, they can now install both tools according to the version specified in tools.mod by running:

go install -modfile=tools.mod honnef.co/go/tools/cmd/staticcheck
go install -modfile=tools.mod github.com/kyleconroy/sqlc/cmd/sqlc

Note here how the version tag is omitted because tools.mod defines which version to install. To make it easier for someone new to set everything up those commands can be extracted into a make target:

.PHONY: install-tools
install-tools:
	go install -modfile=tools.mod honnef.co/go/tools/cmd/staticcheck
	go install -modfile=tools.mod github.com/kyleconroy/sqlc/cmd/sqlc

To remove a dependency you can run:

go get -modfile=tools.mod github.com/kyleconroy/sqlc@none

With all of this in mind: why would you choose a tools.mod over a tools.go which tracks tool dependencies in the same Go modules file? Using a Go file which imports the tools with a blank identifier works around the requirement for dependencies to be referenced in code.

If the referenced code is run in production, should it even be imported in the first place? The tools might generate code which runs in production but those dependencies will be tracked in the go.mod file after all.

Using a separate tools.mod makes it possible to cleanly separate code which is compiled into the target build and tools which are used to maintain the code.

There is, however, an issue with not being able to run go mod tidy. This command only works based on dependencies being referenced in code. Since none of the code is referenced, running go mod tidy -modfile=tools.mod will end up wiping out the content of your tools.mod file. If you want to keep your tools.sum file tidy you would need to re-generate it from scratch.

To get the best of both worlds, you could use a tools.go file but manage it in a git submodule which allows you to manage the tool dependencies in a go.mod file, be able to run go mod tidy but also keep the dependency graph separate from your main module.

tools.mod's People

Contributors

konradreiche avatar

Stargazers

Thomas Harr avatar Ian avatar Nikita avatar

Watchers

 avatar James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.