bindown

package module
v3.20.2 Latest Latest
Warning

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

Go to latest
Published: May 11, 2023 License: MIT Imports: 3 Imported by: 0

README

bindown

bindown is a command-line utility to download and install binary dependencies. It is intended to be used in development and ci environments where it is important to guarantee the same version of the same binary is downloaded every time.

Installation

Using bootstrap-bindown.sh

This is the preferred method for ci or development environments. Each release contains a shell script bootstrap-bindown.sh that will download bindown for the current os. Place bootstrap-bindown.sh from the latest release in your project's repository. Don't forget to make it executable first (chmod +x bootstrap-bindown.sh on most systems). Then you can call bootstrap-bindown.sh before bindown in the project's bootstrap script or Makefile.

./bootstrap-bindown.sh -h
./bootstrap-bindown.sh: download the bindown binary

Usage: ./bootstrap-bindown.sh [-b bindir] [-d]
  -b sets bindir or installation directory, Defaults to ./bin
  -d turns on debug logging
go install

If you happen to already have go installed on your system, you can install bindown with:

go install github.com/willabides/bindown/v3/cmd/bindown@latest 

Note the lowercase willabides. Pro tip: Your life will be easier with a lowercase GitHub username.

Quick Start

Set up your first dependency

This will show you how to get bindown configured to install jq in the development environment for your project.

  1. Install bindown using one of the methods above and make sure it is in your PATH.
  2. (optional) Configure completions for your shell.
$ `bindown install-completions`
  1. In your project's root create a bindown configuration file (.bindown.yaml)
$ bindown init
  1. Add a template source that contains a template for jq. We will use https://github.com/WillAbides/bindown-templates.
$ bindown template-source add origin https://raw.githubusercontent.com/WillAbides/bindown-templates/main/bindown.yml
  1. Add the jq dependency. It will prompt you for a version. You can use any version you like. 1.6 is currently the latest version of jq, so let's use 1.6
$ bindown dependency add jq --source origin jq
Please enter a value for required variable "version":	1.6
  1. Install jq to bin/jq.
$ bindown install jq
installed jq to bin/jq
$ bin/jq --version
jq-1.6
  1. Add the .bindown cache directory to your .gitignore. If you aren't already ignoring bin, you should add that too.
$ echo '/.bindown/' >> .gitignore
$ echo '/bin/' >> .gitignore
  1. Commit .bindown.yaml and .gitignore.
$ git add .bindown.yaml .gitignore
$ git commit -m 'Add initial bindown configuration'
Integrate with make
  1. Add this to your Makefile
BINDOWN_VERSION := 3.10.0

bin/bootstrap-bindown.sh: Makefile
	@mkdir -p bin
	curl -sL https://github.com/WillAbides/bindown/releases/download/v$(BINDOWN_VERSION)/bootstrap-bindown.sh -o $@
	@chmod +x $@

bin/bindown: bin/bootstrap-bindown.sh
	bin/bootstrap-bindown.sh

bin/jq: bin/bindown
	bin/bindown install jq
  1. Install jq
$ make bin/jq
curl -sL https://github.com/WillAbides/bindown/releases/download/v3.10.0/bootstrap-bindown.sh -o bin/bootstrap-bindown.sh
bin/bootstrap-bindown.sh
bin/bootstrap-bindown.sh info installed ./bin/bindown
bin/bindown install jq
installed jq to bin/jq
  1. Run jq
$ bin/jq --version
jq-1.6
Integrate with scripts-to-rule-them-all

If you use scripts-to-rule-them-all, you can create scripts for each dependency bindown manages.

  1. Download bootstrap-bindown.sh from the latest release.
$ curl -L https://github.com/willabides/bindown/releases/latest/download/bootstrap-bindown.sh -o script/bootstrap-bindown.sh
  1. Create script/bindown
#!/bin/sh

set -e

CDPATH="" cd -- "$(dirname -- "$(dirname -- "$0")")"
mkdir -p bin
[ -f bin/bindown ] || sh script/bootstrap-bindown.sh 2>/dev/null
exec bin/bindown "$@"
  1. Create script/jq
#!/bin/sh

set -e

CDPATH="" cd -- "$(dirname -- "$(dirname -- "$0")")"
script/bindown install jq > /dev/null
exec bin/jq "$@"
  1. Make your scripts executable
$ chmod +x script/bindown script/jq
  1. Run jq
$ script/jq --version
jq-1.6

Config file properties

cache

The directory where bindown will cache downloads and extracted files. This is relative to the directory where the configuration file resides. cache paths should always use / as a delimiter even on Windows or other operating systems where the native delimiter isn't /.

Defaults to <path to config file>/.bindown

install_directory

The directory that bindown installs files to. This is relative to the directory where the configuration file resides. install_directory paths should always use / as a delimiter even on Windows or other operating systems where the native delimiter isn't /.

Defaults to <path to config file>/bin

dependencies

Dependencies are all the dependencies that bindown can install. It is a map where the key is the dependency's name.

Property Description
url The url to download a dependency from.
archive_path The path in the downloaded archive where the binary is located. Default is ./<dependency name>.
bin The name of the binary to be installed. Default is the name of the dependency.
link Whether to create a symlink to the bin instead of copying it.
template The name of a template to provide default values for this dependency. See templates.
vars A map of variables that will be interpolated in the url, archive_path and bin values. See vars
overrides A list of value overrides for certain systems. See overrides
substitutions Values that will be substituted for one variable. See substitutions
systems A list of systems that this dependency is compatible with in format os/arch. For example linux/amd64 or darwin/arm64.
vars

Vars are key value pairs that are used in constructing url, archive_path and bin values using go templates. If you aren't familiar with go templates, all you need to know is that to use the value from a variable named "foo", you would write {{.foo}}. Go templates can do more than this, but that's all that is practical for bindown.

In addition to variables explicitly defined in vars, bindown adds os and arch variables based on the current system.

Consider this dependency:

myproject:
  url: https://github.com/me/myproject/releases/download/v{{.version}}/myproject_{{.version}}_{{.os}}_{{.arch}}.tar.gz
  archive_path: myproject_{{.version}}_{{.os}}_{{.arch}}/myproject
  vars:
    version: 1.2.3

When bindown is run for a linux/amd64 system, it will download from https://github.com/me/myproject/releases/download/v1.2.3/myproject_1.2.3_linux_amd64.tar.gz and use the archive path myproject_1.2.3_linux_amd64/myproject

substitutions

Substitutions provide replacement values for vars. The primary use case is for projects that don't use the same values for os and arch.

substitutions:
  arch:
    "386": i386
    amd64: x86_64
  os:
    darwin: Darwin
    linux: Linux
    windows: Windows
templates

Templates provide base values for dependencies. If a dependency has an unset value, the value from its template is used.

For vars, the value is initially set to the template's var map which is then overridden by values from the dependency. substitutions is handled similarly.

overrides concatenated with the template values coming first.

Template configuration is identical to dependencies.

overrides

Overrides allow you to override values for certain operating systems or system architectures.

It is a list of overrides that each contain a matcher and a dependency. Dependency properties are the same as described in dependencies. Matchers match "os", "arch" or vars. A matcher matches if any of its values match the config value. Matchers can be semver constraints or strings.

overrides:
  - matcher:
      os:
        - windows
    dependency:
      vars:
        archivepathsuffix: .exe
  - matcher:
      arch:
        - arm
        - arm64
      version:
        - ">=1.0.0"
    dependency:
      archive_path: special/path/for/arm

Usage

Usage: bindown <command>

Flags:
  -h, --help                       Show context-sensitive help.
      --json                       treat config file as json instead of yaml
      --configfile=STRING          file with bindown config. default is the first one of
                                   bindown.yml, bindown.yaml, bindown.json, .bindown.yml,
                                   .bindown.yaml or .bindown.json ($BINDOWN_CONFIG_FILE)
      --cache=STRING               directory downloads will be cached ($BINDOWN_CACHE)
      --trust-cache=TRUST-CACHE    trust the cache contents and do not recheck existing downloads
                                   and extracts in the cache ($BINDOWN_TRUST_CACHE)
  -q, --quiet                      suppress output to stdout

Commands:
  download                            download a dependency but don't extract or install it
  extract                             download and extract a dependency but don't install it
  install                             download, extract and install a dependency
  format                              formats the config file
  dependency list                     list configured dependencies
  dependency add                      add a template-based dependency
  dependency add-by-urls              add a dependency by urls
  dependency add-by-github-release    add a dependency by github release
  dependency remove                   remove a dependency
  dependency info                     info about a dependency
  dependency show-config              show dependency config
  dependency update-vars              update dependency vars
  dependency validate                 validate that installs work
  template list                       list templates
  template remove                     remove a template
  template update-from-source         update a template from source
  template update-vars                update template vars
  template-source list                list configured template sources
  template-source add                 add a template source
  template-source remove              remove a template source
  supported-system list               list supported systems
  supported-system add                add a supported system
  supported-system remove             remove a supported system
  checksums add                       add checksums to the config file
  checksums prune                     remove unnecessary checksums from the config file
  init                                create an empty config file
  cache clear                         clear the cache
  version                             show bindown version
  install-completions                 install shell completions

Run "bindown <command> --help" for more information on a command.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AddDependencyFromTemplateOpts added in v3.1.0

type AddDependencyFromTemplateOpts struct {
	TemplateSource string
	DependencyName string
	Vars           map[string]string
}

AddDependencyFromTemplateOpts options for AddDependencyFromTemplate

type Config

type Config struct {
	Cache           string                 `json:"cache,omitempty" yaml:"cache,omitempty"`
	TrustCache      bool                   `json:"trust_cache,omitempty" yaml:"trust_cache,omitempty"`
	InstallDir      string                 `json:"install_dir,omitempty" yaml:"install_dir,omitempty"`
	Systems         []SystemInfo           `json:"systems,omitempty" yaml:"systems,omitempty"`
	Dependencies    map[string]*Dependency `json:"dependencies,omitempty" yaml:",omitempty"`
	Templates       map[string]*Dependency `json:"templates,omitempty" yaml:",omitempty"`
	TemplateSources map[string]string      `json:"template_sources,omitempty" yaml:"template_sources,omitempty"`
	URLChecksums    map[string]string      `json:"url_checksums,omitempty" yaml:"url_checksums,omitempty"`
}

Config is our main config

func ConfigFromURL added in v3.10.0

func ConfigFromURL(ctx context.Context, cfgSrc string) (*Config, error)

ConfigFromURL loads a config from a URL

func (*Config) AddChecksums

func (c *Config) AddChecksums(dependencies []string, systems []SystemInfo) error

AddChecksums downloads, calculates checksums and adds them to the config's URLChecksums. AddChecksums skips urls that already exist in URLChecksums.

func (*Config) AddDependencyFromTemplate added in v3.1.0

func (c *Config) AddDependencyFromTemplate(ctx context.Context, templateName string, opts *AddDependencyFromTemplateOpts) error

AddDependencyFromTemplate adds a dependency to the config

func (*Config) BinName

func (c *Config) BinName(depName string, system SystemInfo) (string, error)

BinName returns the bin name for a downloader on a given system

func (*Config) BuildDependency added in v3.1.1

func (c *Config) BuildDependency(depName string, info SystemInfo) (*Dependency, error)

BuildDependency returns a dependency with templates and overrides applied and variables interpolated for the given system.

func (*Config) ClearCache added in v3.16.0

func (c *Config) ClearCache() error

func (*Config) CopyTemplateFromSource added in v3.3.0

func (c *Config) CopyTemplateFromSource(ctx context.Context, src, srcTemplate, destName string) error

CopyTemplateFromSource copies a template from source

func (*Config) DefaultSystems added in v3.1.1

func (c *Config) DefaultSystems() []SystemInfo

DefaultSystems returns c.Systems if it isn't empty. Otherwise returns the runtime system.

func (*Config) DependencySystems added in v3.3.0

func (c *Config) DependencySystems(depName string) ([]SystemInfo, error)

DependencySystems returns the supported systems of either the config or the dependency if one is not empty if both are not empty, it returns the intersection of the lists

func (*Config) DownloadDependency

func (c *Config) DownloadDependency(
	name string,
	sysInfo SystemInfo,
	opts *ConfigDownloadDependencyOpts,
) (_ string, errOut error)

DownloadDependency downloads a dependency

func (*Config) ExtractDependency

func (c *Config) ExtractDependency(dependencyName string, sysInfo SystemInfo, opts *ConfigExtractDependencyOpts) (_ string, errOut error)

ExtractDependency downloads and extracts a dependency

func (*Config) InstallDependency

func (c *Config) InstallDependency(dependencyName string, sysInfo SystemInfo, opts *ConfigInstallDependencyOpts) (_ string, errOut error)

InstallDependency downloads, extracts and installs a dependency

func (*Config) ListTemplates added in v3.1.0

func (c *Config) ListTemplates(ctx context.Context, templateSource string) ([]string, error)

ListTemplates lists templates available in this config or one of its template sources.

func (*Config) MissingDependencyVars added in v3.1.0

func (c *Config) MissingDependencyVars(depName string) ([]string, error)

MissingDependencyVars returns a list of vars that are required but undefined

func (*Config) PruneChecksums added in v3.8.0

func (c *Config) PruneChecksums() error

PruneChecksums removes checksums for dependencies that are not used by any configured system.

func (*Config) SetDependencyVars added in v3.4.0

func (c *Config) SetDependencyVars(depName string, vars map[string]string) error

SetDependencyVars sets the value of a dependency's var. Adds or Updates the var.

func (*Config) SetTemplateVars added in v3.4.0

func (c *Config) SetTemplateVars(tmplName string, vars map[string]string) error

SetTemplateVars sets the value of a template's var. Adds or Updates the var.

func (*Config) UnsetDependencyVars added in v3.4.0

func (c *Config) UnsetDependencyVars(depName string, vars []string) error

UnsetDependencyVars removes a dependency var. Noop if the var doesn't exist.

func (*Config) UnsetTemplateVars added in v3.4.0

func (c *Config) UnsetTemplateVars(tmplName string, vars []string) error

UnsetTemplateVars removes a template var. Noop if the var doesn't exist.

func (*Config) Validate

func (c *Config) Validate(dependencies []string, systems []SystemInfo) (errOut error)

Validate installs the downloader to a temporary directory and returns an error if it was unsuccessful.

type ConfigAddChecksumsOptions

type ConfigAddChecksumsOptions struct {
	// Only add checksums for these dependencies. When Dependencies is empty, AddChecksums adds checksums for all
	// configured dependencies.
	Dependencies []string

	// Only add checksums for these system targets. When Systems is empty, AddChecksums adds checksums for all known
	// builds configured for each dependency.
	Systems []SystemInfo
}

ConfigAddChecksumsOptions was never used but included by mistake. It will be removed in a future release.

type ConfigDownloadDependencyOpts

type ConfigDownloadDependencyOpts struct {
	TargetFile           string
	Force                bool
	AllowMissingChecksum bool
}

ConfigDownloadDependencyOpts options for Config.DownloadDependency

type ConfigExtractDependencyOpts

type ConfigExtractDependencyOpts struct {
	TargetDirectory      string
	Force                bool
	AllowMissingChecksum bool
}

ConfigExtractDependencyOpts options for Config.ExtractDependency

type ConfigFile added in v3.1.0

type ConfigFile struct {
	Filename string `json:"-"`
	Config
}

ConfigFile is a file containing config

func LoadConfigFile added in v3.1.0

func LoadConfigFile(ctx context.Context, filename string, noDefaultDirs bool) (*ConfigFile, error)

LoadConfigFile loads a config file

func (*ConfigFile) Write added in v3.1.0

func (c *ConfigFile) Write(outputJSON bool) error

Write writes a file to disk

type ConfigInstallDependencyOpts

type ConfigInstallDependencyOpts struct {
	// TargetPath is the path where the executable should end up
	TargetPath string
	// Force - install even if it already exists
	Force bool
	// AllowMissingChecksum - whether to allow missing checksum
	AllowMissingChecksum bool
}

ConfigInstallDependencyOpts provides options for Config.InstallDependency

type ConfigValidateOptions

type ConfigValidateOptions struct {
	// Only validates these dependencies. When Dependencies is empty, Validate validates all configured dependencies.
	Dependencies []string

	// Only validates system targets. When Systems is empty, AddChecksums validates all known builds configured for each
	// dependency.
	Systems []SystemInfo
}

ConfigValidateOptions was never used but included by mistake. It will be removed in a future release.

type Dependency

type Dependency struct {
	Homepage      *string                      `json:"homepage,omitempty" yaml:",omitempty"`
	Description   *string                      `json:"description,omitempty" yaml:",omitempty"`
	Template      *string                      `json:"template,omitempty" yaml:",omitempty"`
	URL           *string                      `json:"url,omitempty" yaml:",omitempty"`
	ArchivePath   *string                      `json:"archive_path,omitempty" yaml:"archive_path,omitempty"`
	BinName       *string                      `json:"bin,omitempty" yaml:"bin,omitempty"`
	Link          *bool                        `json:"link,omitempty" yaml:",omitempty"`
	Vars          map[string]string            `json:"vars,omitempty" yaml:",omitempty"`
	RequiredVars  []string                     `json:"required_vars,omitempty" yaml:"required_vars,omitempty"`
	Overrides     []DependencyOverride         `json:"overrides,omitempty" yaml:",omitempty"`
	Substitutions map[string]map[string]string `json:"substitutions,omitempty" yaml:",omitempty"`
	Systems       []SystemInfo                 `json:"systems,omitempty" yaml:"systems,omitempty"`
}

Dependency is something to download, extract and install

type DependencyOverride

type DependencyOverride struct {
	OverrideMatcher OverrideMatcher `json:"matcher" yaml:"matcher,omitempty"`
	Dependency      Dependency      `json:"dependency" yaml:",omitempty"`
}

DependencyOverride overrides a dependency's configuration

type OverrideMatcher

type OverrideMatcher map[string][]string

OverrideMatcher contains a list or oses and arches to match an override. If either os or arch is empty, all oses and arches match.

type SystemInfo

type SystemInfo struct {
	OS   string
	Arch string
}

SystemInfo contains os and architecture for a target system

func (SystemInfo) MarshalText

func (s SystemInfo) MarshalText() (text []byte, err error)

MarshalText implements encoding.TextMarshaler

func (*SystemInfo) String

func (s *SystemInfo) String() string

func (*SystemInfo) UnmarshalText

func (s *SystemInfo) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler

Directories

Path Synopsis
cmd
internal

Jump to

Keyboard shortcuts

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