bintool

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 29, 2023 License: MIT Imports: 18 Imported by: 0

README

bintool

import "github.com/dmvolod/mageutil/bintool"

Package bintool manages local binary tool dependencies in your project.

Tools are first defined with bintool.New(), which is provided with the tool's executable name, desired version, and template URL for downloading it if needed.

For example, this call will configure version 1.23.6 of golangci-lint for use:

linter, err = bintool.New(
	"golangci-lint{{.BinExt}}",
	"1.23.6",
	"https://github.com/golangci/golangci-lint/releases/download/v{{.Version}}/golangci-lint-{{.Version}}-{{.GOOS}}-{{.GOARCH}}{{.ArchiveExt}}",
)

Since errors are only reported for templating issues, it's common to wrap the call with bintool.Must(), which will panic if an error is returned, rather than making you handle it:

linter := bintool.Must(bintool.New(
	"golangci-lint{{.BinExt}}",
	"1.23.6",
	"https://github.com/golangci/golangci-lint/releases/download/v{{.Version}}/golangci-lint-{{.Version}}-{{.GOOS}}-{{.GOARCH}}{{.ArchiveExt}}",
))
Templates

Both the executable name and the download URL are configurable using templates so that they can easily be used cross-platform and with alternative versions using one set of code.

Wherever a template can be used, the following variables are available:

- GOOS         The value of runtime.GOOS for your installation of go

- GOARCH       The value of runtime.GOARCH for your installation of go

- Version      The version of the tool specified on initialization

- Cmd          The evaluated name of the command template provided. Not
               available in the command template itself.

- FullCmd      The path to the command where it will be installed on your
               system.  By default, this is the result of evaluating
               ./bin/{{.Cmd}}

- ArchiveExt   The extension to use when defining an archive path. Defaults
               to .zip for Windows and .tar.gz for all other operating
               systems. Can be customized using bintool.WithArchiveExt().

- BinExt       The extension to use when defining a binary executable path.
               Defaults to .exe for Windows and is empty for all other
               operating systems. Can be customized using
               bintool.WithBinExt().
Capabilities

Once you've defined your tool, you can check for its existence with the correct version using IsInstalled(), install it using Install(), install it only if it isn't already installed using Ensure(), or run a command using the resulting binary with Command("rest of args"). See the individual method docs for more details.

Configuration Options

There are a few options to configure the tool at creation time. All are presented with a top-level function named "With<option>". They are provided like this:

linter := bintool.Must(bintool.New(
	"golangci-lint{{.BinExt}}",
	"1.23.6",
	"https://github.com/golangci/golangci-lint/releases/download/v{{.Version}}/golangci-lint-{{.Version}}-{{.GOOS}}-{{.GOARCH}}{{.ArchiveExt}}",
	bintool.WithFolder("./cmds"), // Put commands in a ./cmds folder
))

To provide isolation between projects and ensure that your project has access to the exact version of the tooling you desire, the installed execuables are placed in a ./bin folder within your project. This location can be customized using bintool.WithFolder(). Paths are normalized for Windows, so they should be specified as unix-style paths.

When determining whether the version of the command is correct, a command must be run to check the version against the expected one. This varies from tool to tool, but is assumed to be `{{.FullCmd}} --version` by default. If your tool uses a different version command, you can customize it using bintool.WithVersionCmd(). The provided command is a template accepting all of the parameters defined above.

If your archive and/or binary files use different extensions than the default ones provided, you can customize them for your templates using bintool.WithArchiveExt() and bintool.WithBinExt(), respectively.

Index

func GoBin

func GoBin() (string, error)

GoBin returns the value of the GOBIN environment variable. If it's not set, then the path from the GOPATH environment variable joined with the bin directory.

type BinTool

BinTool represents a single binary tool/version combination with the information needed to check and/or install the tool if desired.

The struct provides a set of utilities for checking the existence of a valid version of the command and installing the command in a way that is scoped to the project at hand, if desired.

type BinTool struct {
    // contains filtered or unexported fields
}
func Must
func Must(t *BinTool, err error) *BinTool

Must provide a utility for asserting that methods returning a BinTool and an error have no error. If there is an error, this call will panic.

func New
func New(command, version, url string, opts ...Option) (*BinTool, error)

New initializes a BinTool with the provided command, version, and download url. Additional options may be provided to configure things such as the version test command, file extensions and folder containing the binary tool.

The command, url, and version command may all use text templates to define their formats. If any of these templates fails to compile or evaluate, this call will return an error.

func NewGo
func NewGo(pkg, version string, opts ...Option) (*BinTool, error)

NewGo initializes a BinTool with the provided go package and version. Additional options may be provided to configure things such as the version test command and folder containing the binary tool.

func (*BinTool) Command
func (t *BinTool) Command(args string) shellcmd.Command

Command generates a runnable command using this binary tool along with the provided args.

func (*BinTool) Ensure
func (t *BinTool) Ensure() error

Ensure checks to see if a valid version of the tool is installed, and downloads/installs it if it isn't already.

func (*BinTool) Install
func (t *BinTool) Install() error

Install unconditionally downloads and installs the tool to the configured folder.

If you don't want to download the tool every time, you may prefer Ensure() instead.

func (*BinTool) IsInstalled
func (t *BinTool) IsInstalled() bool

IsInstalled checks whether the correct version of the tool is currently installed as defined by the version command.

type Option

Option configures a BinTool with optional settings

type Option func(t *BinTool) error
func WithArchSubstitution
func WithArchSubstitution(subst map[string]string) Option

WithArchSubstitution allows to map runtime.GOARCH value with the substitution map.

func WithArchiveExt
func WithArchiveExt(ext string) Option

WithArchiveExt defines a custom extension to use when identifying an archive via the ArchiveExt template variable. The default archive extension is .tar.gz except for Windows, where it is .zip.

func WithBinExt
func WithBinExt(ext string) Option

WithBinExt defines a custom extension to use when identifying a binary executable via the BinExt template variable. The default binary extension is empty for all operating systems except Windows, where it is .exe.

func WithFolder
func WithFolder(folder string) Option

WithFolder defines a custom folder path where the tool is expected to exist and where it should be installed if desired. Paths will be normalized to the operating system automatically, so unix-style paths are recommended.

func WithGoBinFolder
func WithGoBinFolder() Option

WithGoBinFolder defines a golang binary location path where the tool is expected to exist and where it should be installed if desired.

func WithOsSubstitution
func WithOsSubstitution(subst map[string]string) Option

WithOsSubstitution allows to map runtime.GOOS value with the substitution map.

func WithVersionCmd
func WithVersionCmd(cmd string) Option

WithVersionCmd defines a custom command used to test the version of the command for purposes of determining if the command is installed. The provided command is a template that can use any of the template parameters that are available to the url. If no command is provided, the version check will be skipped.

The default test command is "{{.FullCmd}} --version".

Generated by gomarkdoc

Documentation

Overview

Package bintool manages local binary tool dependencies in your project.

Tools are first defined with bintool.New(), which is provided with the tool's executable name, desired version, and template URL for downloading it if needed.

For example, this call will configure version 1.23.6 of golangci-lint for use:

linter, err = bintool.New(
	"golangci-lint{{.BinExt}}",
	"1.23.6",
	"https://github.com/golangci/golangci-lint/releases/download/v{{.Version}}/golangci-lint-{{.Version}}-{{.GOOS}}-{{.GOARCH}}{{.ArchiveExt}}",
)

Since errors are only reported for templating issues, it's common to wrap the call with bintool.Must(), which will panic if an error is returned, rather than making you handle it:

linter := bintool.Must(bintool.New(
	"golangci-lint{{.BinExt}}",
	"1.23.6",
	"https://github.com/golangci/golangci-lint/releases/download/v{{.Version}}/golangci-lint-{{.Version}}-{{.GOOS}}-{{.GOARCH}}{{.ArchiveExt}}",
))

Templates

Both the executable name and the download URL are configurable using templates so that they can easily be used cross-platform and with alternative versions using one set of code.

Wherever a template can be used, the following variables are available:

  • GOOS The value of runtime.GOOS for your installation of go

  • GOARCH The value of runtime.GOARCH for your installation of go

  • Version The version of the tool specified on initialization

  • Cmd The evaluated name of the command template provided. Not available in the command template itself.

  • FullCmd The path to the command where it will be installed on your system. By default, this is the result of evaluating ./bin/{{.Cmd}}

  • ArchiveExt The extension to use when defining an archive path. Defaults to .zip for Windows and .tar.gz for all other operating systems. Can be customized using bintool.WithArchiveExt().

  • BinExt The extension to use when defining a binary executable path. Defaults to .exe for Windows and is empty for all other operating systems. Can be customized using bintool.WithBinExt().

Capabilities

Once you've defined your tool, you can check for its existence with the correct version using IsInstalled(), install it using Install(), install it only if it isn't already installed using Ensure(), or run a command using the resulting binary with Command("rest of args"). See the individual method docs for more details.

Configuration Options

There are a few options to configure the tool at creation time. All are presented with a top-level function named "With<option>". They are provided like this:

linter := bintool.Must(bintool.New(
	"golangci-lint{{.BinExt}}",
	"1.23.6",
	"https://github.com/golangci/golangci-lint/releases/download/v{{.Version}}/golangci-lint-{{.Version}}-{{.GOOS}}-{{.GOARCH}}{{.ArchiveExt}}",
	bintool.WithFolder("./cmds"), // Put commands in a ./cmds folder
))

To provide isolation between projects and ensure that your project has access to the exact version of the tooling you desire, the installed execuables are placed in a ./bin folder within your project. This location can be customized using bintool.WithFolder(). Paths are normalized for Windows, so they should be specified as unix-style paths.

When determining whether the version of the command is correct, a command must be run to check the version against the expected one. This varies from tool to tool, but is assumed to be `{{.FullCmd}} --version` by default. If your tool uses a different version command, you can customize it using bintool.WithVersionCmd(). The provided command is a template accepting all of the parameters defined above.

If your archive and/or binary files use different extensions than the default ones provided, you can customize them for your templates using bintool.WithArchiveExt() and bintool.WithBinExt(), respectively.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GoBin

func GoBin() (string, error)

GoBin returns the value of the GOBIN environment variable. If it's not set, then the path from the GOPATH environment variable joined with the bin directory.

Types

type BinTool

type BinTool struct {
	// contains filtered or unexported fields
}

BinTool represents a single binary tool/version combination with the information needed to check and/or install the tool if desired.

The struct provides a set of utilities for checking the existence of a valid version of the command and installing the command in a way that is scoped to the project at hand, if desired.

func Must

func Must(t *BinTool, err error) *BinTool

Must provide a utility for asserting that methods returning a BinTool and an error have no error. If there is an error, this call will panic.

func New

func New(command, version, url string, opts ...Option) (*BinTool, error)

New initializes a BinTool with the provided command, version, and download url. Additional options may be provided to configure things such as the version test command, file extensions and folder containing the binary tool.

The command, url, and version command may all use text templates to define their formats. If any of these templates fails to compile or evaluate, this call will return an error.

func NewGo

func NewGo(pkg, version string, opts ...Option) (*BinTool, error)

NewGo initializes a BinTool with the provided go package and version. Additional options may be provided to configure things such as the version test command and folder containing the binary tool.

func (*BinTool) Command

func (t *BinTool) Command(args string) shellcmd.Command

Command generates a runnable command using this binary tool along with the provided args.

func (*BinTool) Ensure

func (t *BinTool) Ensure() error

Ensure checks to see if a valid version of the tool is installed, and downloads/installs it if it isn't already.

func (*BinTool) Install

func (t *BinTool) Install() error

Install unconditionally downloads and installs the tool to the configured folder.

If you don't want to download the tool every time, you may prefer Ensure() instead.

func (*BinTool) IsInstalled

func (t *BinTool) IsInstalled() bool

IsInstalled checks whether the correct version of the tool is currently installed as defined by the version command.

type Option

type Option func(t *BinTool) error

Option configures a BinTool with optional settings

func WithArchSubstitution

func WithArchSubstitution(subst map[string]string) Option

WithArchSubstitution allows to map runtime.GOARCH value with the substitution map.

func WithArchiveExt

func WithArchiveExt(ext string) Option

WithArchiveExt defines a custom extension to use when identifying an archive via the ArchiveExt template variable. The default archive extension is .tar.gz except for Windows, where it is .zip.

func WithBinExt

func WithBinExt(ext string) Option

WithBinExt defines a custom extension to use when identifying a binary executable via the BinExt template variable. The default binary extension is empty for all operating systems except Windows, where it is .exe.

func WithFolder

func WithFolder(folder string) Option

WithFolder defines a custom folder path where the tool is expected to exist and where it should be installed if desired. Paths will be normalized to the operating system automatically, so unix-style paths are recommended.

func WithGoBinFolder

func WithGoBinFolder() Option

WithGoBinFolder defines a golang binary location path where the tool is expected to exist and where it should be installed if desired.

func WithOsSubstitution

func WithOsSubstitution(subst map[string]string) Option

WithOsSubstitution allows to map runtime.GOOS value with the substitution map.

func WithVersionCmd

func WithVersionCmd(cmd string) Option

WithVersionCmd defines a custom command used to test the version of the command for purposes of determining if the command is installed. The provided command is a template that can use any of the template parameters that are available to the url. If no command is provided, the version check will be skipped.

The default test command is "{{.FullCmd}} --version".

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL