Asset downloader
godyl
helps with batch-downloading and installing statically compiled binaries from:
- GitHub releases
- URLs
- Go projects
As an alternative to above, custom commands can be used as well.
godyl
will infer the platform and architecture from the system it is running on, and will attempt to download the appropriate binary.
This uses simple heuristics to select the correct binary to download, and will not work for all projects.
However, most properties can be overridden, with hints
and skip
used to help godyl
make the correct decision.
Warning
This repo is a work in progress! Needing both cleaning up and documenting.
Caution
This project serves as a learning exercise for Go and its surrounding ecosystem and tooling. As such, it might be of limited use for others, but feel free to use it if you find it useful.
Note
Tested on:
Linux: amd64
, arm64
, armv7
Windows: amd64
MacOS: amd64
, arm64
for tools listed in tools.yml
Tool is inspired by task, dra and ansible
go install github.com/idelchi/godyl@latest
curl -sSL https://raw.githubusercontent.com/idelchi/godyl/refs/heads/main/install.sh | sh -s -- -d ~/.local/bin
Run
curl -sSL https://raw.githubusercontent.com/idelchi/godyl/refs/heads/main/install.sh | sh -s -- -h
for all available options.
godyl --update
Use together with yaml
file:
godyl [tools.yml] --output ./bin
Or use to download a single tool:
godyl idelchi/godyl --output ./bin
When used to download a single tool, the mode
will be set to extract
by default.
Override os
and arch
to download a specific binary:
godyl idelchi/godyl --os linux --arch amd64 --output ./bin
Note
Set up a GitHub API token to avoid rate limiting when using github
as a source type.
See configuration for more information, or simply export GODYL_GITHUB_TOKEN=<token>
The tools can be configured (in order of priority) by
- flags
- environment variables
.env
file
The following flags and their corresponding environment variables are available:
Flag | Environment Variable | Default | Description |
---|---|---|---|
--help , -h |
GODYL_HELP |
false |
Show help message and exit |
--version |
GODYL_VERSION |
false |
Show version information and exit |
--dot-env |
GODYL_DOT_ENV |
.env |
Path to .env file |
--defaults , -d |
GODYL_DEFAULTS |
defaults.yml |
Path to defaults file |
--show-config |
GODYL_SHOW_CONFIG |
false |
Show the parsed configuration and exit |
--show-defaults |
GODYL_SHOW_DEFAULTS |
false |
Show the parsed default configuration and exit |
--show-env |
GODYL_SHOW_ENV |
false |
Show the parsed environment variables and exit |
--show-platform |
GODYL_SHOW_PLATFORM |
false |
Detect the platform and exit |
--update |
GODYL_UPDATE |
false |
Update godyl itself |
--dry |
GODYL_DRY |
false |
Run without making any changes (dry run) |
--log |
GODYL_LOG |
info |
Log level (debug, info, warn, error) |
--parallel , -j |
GODYL_PARALLEL |
0 |
Number of parallel downloads (0 is unlimited) |
--output |
GODYL_OUTPUT |
"" |
Output path for the downloaded tools |
--tags , -t |
GODYL_TAGS |
["!native"] |
Tags to filter tools by. Use ! to exclude |
--source |
GODYL_SOURCE |
github |
Source from which to install the tools |
--strategy |
GODYL_STRATEGY |
none |
Strategy to use for updating tools |
--os |
GODYL_OS |
"" |
Operating system to use for downloading |
--arch |
GODYL_ARCH |
"" |
Architecture to use for downloading |
--github-token |
GODYL_GITHUB_TOKEN |
"" |
GitHub token for authentication |
The path to the file containing the tool installation instructions is provided as a positional argument, defaulting to tools.yml
.
An example tools.yml is provided.
In general, settings can be set in the following ways (order of priority):
-
as a field in the tools.yml definition
output: ~/.local/bin
-
as a flag to the tool
godyl --output ~/.local/bin
-
as an environment variable
GODYL_OUTPUT=~/.local/bin godyl
-
in an
.env
fileGODYL_OUTPUT=~/.local/bin
-
by setting the value in a
defaults.yml
file (see defaults)output: ~/.local/bin
If none of the above are fulfilled, the default configuration embedded from defaults.yml will be used.
A YAML file controls the tools to download and install. Alternatively, if the positional argument to the tool is not a YAML file, it will be treated as a single tool name or URL.
Examples are provided in tools.yml.
- idelchi/godyl
Above is the simple
form to attempt to download the latest release of godyl
from idelchi/godyl
.
If it is a URL, it will be considered as a source.url
type.
Otherwise, it will be assumed to be a source.github
type on the form owner/repo
.
name: string
description: string
version:
version: string
commands: []
patterns: []
path: string
output: string
exe:
name: string
patterns:
- regex
platform:
os: string
architecture:
type: string
version: string
library: string
extension: string
distribution: string
aliases: []
values: {}
fallbacks: []
hints:
- pattern: regex
weight: string
must: boolean
source:
type: string
github:
repo: string
owner: string
token: string
url:
url: string
token: string
go:
command: string
commands: []
tags:
- string
strategy: string
extensions:
- string
skip:
- condition: string
reason: string
post: []
mode: string
env:
key: string
Any field that accepts a list, can also be provided as a string.
For example:
aliases: gd
fallbacks: go
exe:
patterns: "{{ .Exe }}{{ .EXTENSION }}$"
is equivalent to:
aliases:
- gd
fallbacks:
- go
exe:
patterns:
- "{{ .Exe }}{{ .EXTENSION }}$"
and
skip:
reason: "tool is not available on windows"
condition: '{{ eq .OS "windows" }}'
is equivalent to:
skip:
- reason: "tool is not available on windows"
condition: '{{ eq .OS "windows" }}'
Template | Templated | As Template |
---|---|---|
{{ .Name }} |
name
is the name of the tool to download.
Template | Templated | As Template |
---|---|---|
description
is an optional description of the tool, for documentation purposes.
Template | Templated | As Template |
---|---|---|
{{ .Version }} |
-
As template for other fields
-
To compare tool versions if
strategy
is set toupgrade
-
Will be inferred and populated by the
source
method if not given -
version.version
is the version of the tool to download -
version.commands
is a list of commands to run to get the version of the tool (for upgrades) -
version.patterns
is a list of patterns to use for finding the version of the tool (for upgrades) -
version.commands
&version.patterns
set according to defaults if not given
Set version.commands
to []
if version parsing is not available. This will result in always downloading the tool
when strategy
is set to upgrade
.
Pinning to a specific version will prevent upgrades.
version: v0.1.0
is equivalent to:
version:
version: v0.1.0
Template | Templated | As Template |
---|---|---|
path
is the path to the tool to download. Currently only supports URLs.
- Will be inferred and populated by the
source
method if not given
Template | Templated | As Template |
---|---|---|
output
is the path to the directory where the tool will be installed.
- Set according to flags and environment variables or defaults if not given
Template | Templated | As Template |
---|---|---|
{{ .Exe}} |
||
{{ .Exe.Patterns }} |
exe
is a dictionary containing the name of the executable and patterns to use for finding the executable.
exe.name
is the name of the executable, inferred fromname
if not givenexe.patterns
is a list of patterns to use for finding the executable, inferred fromname
if not given- Set according to defaults if not given
exe: godyl
is equivalent to:
exe:
name: godyl
Template | Templated | As Template |
---|---|---|
{{ .Platform.<> }} |
See variables |
platform
is a dictionary containing the platform and architecture information.
- Any field not given will be inferred from the system
- Set according to defaults if not given
Template | Templated | As Template |
---|---|---|
aliases
is a list of aliases for the tool. Will be used to create symlinks (or copies on Windows
) for the tool.
Template | Templated | As Template |
---|---|---|
{{ .Values.<> }} |
values
is an arbitrary values map, which can be used for templating in other fields.
Template | Templated | As Template |
---|---|---|
fallbacks
is a list of fallback strategies to use if the tool cannot be found.
They will be tried in order until the tool is found or all have been tried.
Template | Templated | As Template |
---|---|---|
{{ .Hints.Weight }} |
||
{{ .Hints.Pattern }} |
||
{{ .Hints.Regex }} |
||
{{ .Hints.Must }} |
hints
is a list of hints for matching, which can be used to help godyl
find the correct tool.
- Set according to defaults if not given
Template | Templated | As Template |
---|---|---|
source.type
is the source type. Accepted values are:
github
url
go
commands
Template | Templated | As Template |
---|---|---|
source.github
is a dictionary containing the owner, repository and token of the tool.
repo
andowner
will be inferred fromname
if not given, or set according to defaults (not recommended)token
will be set according to flags and environment variables or defaults if not given
Template | Templated | As Template |
---|---|---|
source.url
is a dictionary containing the URL and token of the tool.
token
will be set according to flags and environment variables if not given
Template | Templated | As Template |
---|---|---|
source.go
can be set to the relative path of the go command
to download, if non-standard (i.e not matching <name>
, cmd/<name>
or cmd
).
Warning
Go will be downloaded into a temporary directory /tmp/.godyl-go
if not present.
Template | Templated | As Template |
---|---|---|
commands
is a list of commands to run to install the tool.
Template | Templated | As Template |
---|---|---|
tags
is a list of tags to filter tools by.
- the
name
of the tool will always be added as a tag
Template | Templated | As Template |
---|---|---|
strategy
is the strategy to use for updating the tool.
Accepted values are:
none
upgrade
force
- Set according to flags and environment variables or defaults if not given
none
will skip the tool if it already existsupgrade
will attempt to parse the version of an existing tool and upgrade if necessaryforce
will always download and install the tool
Template | Templated | As Template |
---|---|---|
extensions
is a list of extensions to consider when matching the most suitable tool to download (used only for github
source type).
- Set according to defaults if not given
- Can be used to for example prefer
.zip
files for Windows
Template | Templated | As Template |
---|---|---|
skip
is a list of conditions under which the tool should be skipped.
reason
is a description of why the tool was skippedcondition
is a condition to check, and can use templating
skip: <condition>
is equivalent to:
skip:
- condition: <condition>
Template | Templated | As Template |
---|---|---|
post
is a list of commands to run after the tool has been installed.
Template | Templated | As Template |
---|---|---|
mode
is the mode to use for the tool.
Accepted values are:
find
extract
find
will download, extract and find the executableextract
will download the tool and extract it directly to the output directory- Set according to flags and environment variables or defaults if not given
- Automatically set to
extract
if the tool is used withouttools.yml
(e.g.godyl idelchi/godyl
)
A default configuration may be used to specify default settings for all tools. These will override (or extend in some case) the settings for each tool.
The following is embedded and used by default if no default configuration is provided:
The example above defines:
-
The default output directory for all tools (
~/.local/bin
) -
Patterns to use for when searching for the executable
^{{ .Exe }}{{ .EXTENSION }}$
.\*/{{ .Exe }}{{ .EXTENSION }}$
-
Hints to:
-
use the executable name as a pattern (useful for repositories with multiple binaries, such as
ahmetb/kubectx
)pattern: "{{ .Exe }}" weight: 1
-
prefer
.zip
files for Windowspattern: zip weight: '{{ if eq .OS "windows" }}1{{ else }}0{{ end }}'
-
prefer the three last versions of the arm architecture, in descending order
- pattern: "armv{{.ARCH_VERSION}}" weight: 3 - pattern: "armv{{sub .ARCH_VERSION 1}}" weight: 2 - pattern: "armv{{sub .ARCH_VERSION 2}}" weight: 1
-
-
Extensions to use when filtering assets
.exe
for Windows, empty for Linux and MacOS.zip
for Windows and Darwin.tar.gz
for all platforms
-
find
mode for downloading, extracting and finding the executable -
The default source type as
github
-
none
strategy to skip tools which already exist -
Settings the environment variable
GH_TOKEN
to the value ofGODYL_GITHUB_TOKEN
The full set of default options are:
exe:
output:
platform:
values:
fallbacks:
hints:
source:
tags:
strategy:
env:
mode:
For reference full reference of what values you can set, see the tools section.
All functions available in the slim-sprig library are available for use in templates.
The following table lists the available template variables, where they may be used, and their descriptions:
Variable | Description |
---|---|
{{ .Name }} |
The name of the tool or project |
{{ .Output }} |
The output path template for built artifacts |
{{ .Exe }} |
The name of the executable |
{{ .Env.<> }} |
Any environment variable |
{{ .Values.<> }} |
Custom values for templating |
{{ .Version }} |
The version of the tool or project |
{{ .OS }} |
The operating system (e.g., linux , darwin , windows ) |
{{ .ARCH }} |
The architecture type (e.g., amd64 , arm64 ) |
{{ .ARCH_VERSION }} |
The version of the architecture, if applicable |
{{ .LIBRARY }} |
The system library (e.g., gnu , musl ) |
{{ .EXTENSION }} |
The file extension specific to the platform |
{{ .DISTRIBUTION }} |
The distribution name (e.g., debian , alpine ) |
Only certain fields are templated. Below is a list of fields where templating is allowed, along with examples of how they might be used:
-
output
output: bin/{{ .OS }}-{{ .ARCH }}
-
skip
skip: reason: "tool is not available for windows" condition: '{{ eq .OS "windows" }}'
-
version
version: |- {{- if has .OS (list "linux" "darwin") -}} v0.1.0 {{- else -}} v0.2.0 {{- end -}}
-
source.type
source: type: |- {{- if has .OS (list "linux" "darwin") -}} github {{- else -}} go {{- end -}}
-
exe.patterns
exe: patterns: - "^{{ .OS }}-{{ .Exe}}"
-
extensions
extensions: - '{{ if eq .OS "windows" }}.exe{{ else }}{{ end }}'
-
source.commands
commands: - pip install {{ .Exe}}=={{ .Version }}
-
hints[].pattern
hints: - pattern: "{{ .OS }}" must: true
-
hints[].weight
hints: - pattern: armhf weight: |- {{- if eq .ARCH "arm" -}} 1 {{- else -}} 0 {{- end -}}
-
path
path: https://get.helm.sh/helm-v{{ .Version }}-{{ .OS }}-{{ .ARCH }}.tar.gz
Note
Not that if Version
is not provided, it will be evaluated to an empty string. If it is being inferred, it will be available in the following fields:
exe.name
exe.patterns
extensions
hints[].pattern
hints[].weight
path
source.commands
post
OS | Inferred from |
---|---|
Linux | linux |
Darwin | darwin, macos, mac, osx |
Windows | windows, win |
FreeBSD | freebsd |
Android | android |
NetBSD | netbsd |
OpenBSD | openbsd |
Architecture | Inferred from |
---|---|
AMD64 | amd64, x86_64, x64, win64 |
ARM64 | arm64, aarch64 |
AMD32 | amd32, x86, i386, i686, win32, 386, 686 |
ARM32 (v7) | armv7, armv7l, armhf |
ARM32 (v6) * | armv6, armv6l |
ARM32 (v5) | armv5, armel |
ARM32 (v) | arm |
Library | Inferred from |
---|---|
GNU | gnu |
Musl | musl |
MSVC | msvc |
LibAndroid | android |
All regex
expressions are evaluated using search
, meaning that ^
and $
are necessary to match the start and end of the string.
When running 32-bit
userland on a 64-bit
Kernel, there's some attempts to infer the matching 32-bit
architecture.
However, to be certain that the right binary is downloaded, it's recommended to pass the --arch
flag to the tool.