Crates.io | avatar-cli |
lib.rs | avatar-cli |
version | 0.18.1 |
source | src |
created_at | 2020-07-24 11:07:02.806558 |
updated_at | 2020-10-16 11:10:17.115929 |
description | Magic wrapper to run containerized CLI tools |
homepage | https://www.avatar-cli.dev |
repository | https://gitlab.com/avatar-cli/avatar-cli.git |
max_upload_size | |
id | 268952 |
size | 111,918 |
Avatar-CLI is a command line tool that allows you to run thousands of cli programs for your dev projects without having to install them in your system.
Avatar-CLI can ease the development forkflow in many ways:
nvm
,
nodeenv
,
pyenv
,
rbenv
,
goenv
,
asdf-vm
, ... I guess you already have seen the
pattern.git
and
docker
are required.Why Avatar-CLI exists and what problems it tries to solve?
Problems solved by Avatar-CLI and surrounding practices:
Works on my machine - With Avatar-CLI, each developer (and/or CI agent) gets a consistent and reproducible environment built with a combination of docker images.
Avatar-CLI helps to fight configuration drift. Tools and configurations in the CI/CD environments and developers' environments tend to accumulate differences and mismatches over time. Avatar-CLI allows using exactly the same tools, having a single source of truth for their configuration.
First, install docker, if you haven't already.
You can get our pre-compiled binaries in the Releases section. For now we only can provide Linux binaries, but in the future we'll also provide binaries for Macos.
If you want to use Avatar-CLi in Macos, or you don't mind waiting a little bit
more for its compilation, you can use
cargo
¹ to install it:
cargo install avatar-cli
1: If you don't have cargo
in your system,
you can obtain it via rustup.
In the command line:
# 1. Enter into your project directory
cd /your/project/path
# 2. Initialize Avatar-CLI for this project, this will create a new config file.
# You only have to do this one single time per project.
avatar init
# 3. Edit the generated configuration file, without modifying its
# `internalProjectId` property. You can see an example in the next code
# block of this README.md file.
# 4. Now you can enter into an Avatar-CLI subshell and use all the configured
# tools. If, for example, you configured a specific version of NodeJS, then
# it will be available inside that subshell.
avatar shell
# Now you can use the software you specified in the configuration, even if it
# was not installed in your system.
---
# This is of no use... for now, but it must be there
avatarVersion: '0.17.0'
# Keep the value generated by `avatar init`, don't share it across projects.
# This value is used (among other things) to keep track of managed volumes and
# containers
projectInternalId: v2ZmtbkGuVdvGwVE
# The field shellConfig is optional, it allows you to define some settings for
# the Avatar-CLI subshell (started via `avatar shell`).
shellConfig:
# You can define environment variables for the subshell
env:
SOME_ENV_VAR: 42
# In the case of the $PATH environment variable, Avatar-CLI forbids declaring
# it through the `env` field, but you can extend it adding multiple paths to
# the `extraPaths` field. This can be useful if you want to access tools
# provided by some package manager, like `npm` or `composer`, as if they were
# installed globally.
extraPaths:
- ./node_modules/.bin
# In this section we declare the OCI images that we'll use in our project
images:
# Image name
node:
tags:
14-buster:
# The runConfig block allows us to tweak our containers, to improve
# their integration with our development environment.
runConfig:
# You can specify hardcoded environment variables for your containers,
# in this example we use this to configure NPM's cache
env:
npm_config_cache: /caches/.npm
# You can pass host environment variables to your containers
envFromHost:
- NPM_TOKEN
# You can specify which container paths have to be mounted as volumes,
# this is specially useful for package managers' caches
volumes:
/caches/.npm: {} # In most cases, we won't need to configure volumes
/another/example:
# Volume names are usually autogenerated, use this configuration
# option only in case you want to share volumes accross projects
name: exotic_volume
# By default, the scope of a volume is "Project", allowed values
# are "Project", "OCIImage" and "Binary".
# This setting defines how volumes are shared between containers,
# and has no effect if a custom volume name has been set.
scope: Project
# In most cases, bindings won't be necessary, and it's advisable to
# avoid them as they difficult to share development environments with
# other people. But, if you really need to map a container path to
# your host filesystem, they will allow you to do so.
bindings:
/container/path: /host/path
# For each image, we can declare which binaries we want to expose to our
# project.
binaries:
node:
path: node # The path can also be an absolute path
# Although we don't do it in this example, each binary can have its
# own `runConfig` block, and its values will override the ones defined
# at the image tag level
# Usually we can skip configuring the binary, we just have to list it
npm: {}
npx: {}
yarn: {}
# Image name
rust:
tags:
1.45-stretch:
binaries:
cargo:
path: cargo
If you want to use Avatar-CLI in your own CI/CD pipelines, you can rely on the generated OCI images. We provide the Avatar-CLI images through three different registries:
registry.gitlab.com/avatar-cli/avatar-cli:[ major[.minor[.patch]] | latest ]
docker.pkg.github.com/avatar-cli/avatar-cli/avatar-cli:[ major[.minor[.patch]] | latest ]
avatarcli/avatar-cli:[ major[.minor[.patch]] | latest ]
Given that creating subshells inside scripts may be too cumbersome, you can also
"source" the output of the avatar export-env
command.
In Bash scripts, you could do something like this:
#!/bin/bash
source <(avatar export-env)
If you want full compatibility with POSIX shell, then you have to first create a file and then source it:
#!/bin/sh
avatar export-env > /your/temporary/file
. /your/temporary/file
When using your preferred IDE, sometimes you have to specify the path of certain interpreters like Python or PHP.
For that, Avatar-CLI generates wrapper scripts in the directory
.avatar-cli/volatile/wrappers
of your project, and you can tell your IDE to
find the interpreters there.
As a side note, notice that there is a similar directory
(.avatar-cli/volatile/bin
), this is where the symbolic links used by
avatar shell
are, and they won't work with your IDE.
Git hooks are non-interactive by default, if you want to transform them into
interactive programs, the program must connect its standard input to a
pseud-tty device (usually /dev/tty
) by itself.
If such git hooks use tools managed by Avatar, you must ensure that the TTY attachment is performed before any managed container is spawned, because once the container has been already connected and started, there's no sensible way to attach a terminal to it for Avatar-CLI.
One example for the mentioned problem is the combination of tools such as
NodeJS, Husky and Commitizen. Husky will start a shell script for each git hook,
and pass the control of execution to npm
after some checks.
In the specific case of Avatar-CLI, we solved this problem by creating a patch for Husky (PR #747), and forking the project while the Husky project mantainers decide whether to accept this PR or not.
$PATH
environment variableIn case you have a customized $PATH environment variable via configuration
scripts like ~/.bashrc
, you should wrap that redefinition with a conditional
statement to avoid breaking how Avatar-CLI works.
For example, something like this:
export PATH="/custom/extra/bin/path:${PATH}";
Should be converted into this:
if [ -z "${AVATAR_CLI_SESSION_TOKEN}" ]; then
export PATH="/custom/extra/bin/path:${PATH}";
fi
Don't worry, the paths you declared are still available, but Avatar-CLI must be sure that its own managed paths are the first ones to be evaluated.
Read the contributing guidelines.
Avatar-CLI is licensed under the GPL 3.0 license.