Skip to content

kriipke/provii

Repository files navigation

provii

a lightweight cli power tool installer


provii is an extremely light-weight provisioning tool that aims to be a pseudo-packagemanager for modern command line tools. It allows you to painlessly download your favorite command-line utilities as pre-compiled binaries on a machine that that may be missing them in the blink of an eye.

It was designed for those who may be constantly popping and and out of Docker containers or VMs all day and want a simple way to install some of the most handy cli tools without thinking or expending more than 5 seconds of effort. Handy tools available include search utilities like fd and fzf, greppers like rg, logfile analyzers and many other amazing tools contributed to the open source community.

The beauty of provii is that it is a single shell script. You can download it with curl as follows:

curl -o /usr/bin https://cdn.spencersmolen.com/provii

The list of available installers be found by typing provii ls or by browsing here.

provii was designed with 3 goals:

  1. Provide the easiest possible access to the most powerful command line tools avaialble.

  2. Have as small of a footprint as possible. Unlike a traditional package manager, most of the provii installers will put only a few kilobytes of data on your machines and rarely exceed more than 3 files:

    1. a binary executable (the program)

    2. a shell autocompletion script

    3. a man page

  3. To run on as many systems as possible. For this reason it was written in POSIX sh.

🚀
If you would like to add your piece of software to the list of installers avaliable via provii, either make a pull request or contact me.

Installation

Method 1: curl provii directly into bash

The simplest way to use provii is to curl the script directly into bash. For example, to download the tool fd, you would simply run:

bash -c "$( curl https://cdn.spencersmolen.com/provii )" fd

Once run, provii will print out the location to which the binary will be installed and print some information as the script runs. See provii install for output.

The best part about running provii this way is that after the installation of a program such as fd, the only files left on your machine will be the ones you requested. In other words, when provii is run by downloading via curl/wget and piped directly into bash, there will be no trace of provii itself or any intermediary files used during the installation!

Method 2: download provii and place in $PATH

If you choose to download provii you will be afforded a few more features, mostly geared towards previewing the changes that will be made before running an installation. Once downloaded, the subcommands below will be available. There is also .deb and .rpm packages available for install like so:

Method 3: using the .rpm or .deb packages

# Fedora-based distributions
dnf install -y https://github.com/kriipke/provii/releases/download/0.3.1/provii-0.3.1-1.el7.noarch.rpm
# Debian-based distributions
apt install -y https://github.com/kriipke/provii/releases/download/0.3.1/provii_0.3.1-1.el7_all.deb

Usage

man page

	PROVII(1)                        provii manual                       PROVII(1)



	NAME
	       provii  - minimalist command-line utility installer & provisioning tool


	SYNOPSIS
	       provii install [-vi] APPLICATION ...
	       provii env [APPLICATION]
	       provii cat APPLICATION
	       provii ls


	DESCRIPTION
	       provii is a provisioning tool to painlessly download your favorite com‐
	       mand-line utilities as pre-compiled binaries on a machine that that may
	       be  missing  them.  It is a convenient alternative when you do not have
	       the premissions required to install software using the systems  package
	       manager or when you do not wish to install the software system-wide.


	STANDARD OPTIONS
	       -b     Choose  the git branch that provii uses to fetch   installer in‐
		      formation.


	       -i     Ask user for confirm before any changes  to  the  system  before
		      they are made.


	       -v     Print extra information to standard out during runtime.


	       -h     Print help menu.


	PROVII COMMANDS
	       provii install
		      Install the application or applications given as arguments.


	       provii cat
		      Print  the  installation  script that would be run by provii in‐
		      stall for a given application.


	       provii env
		      Show the values for variables that will populate the environment
		      in  which  the  installation script for the given application is
		      run.


	       provii ls
		      List all avaliable  applications  that  can  be  installed  with
		      provii.


	ENVIRONMENT VARIABLES
	       PROVII_LOG
		      Location  of file to write logs of all files created during run‐
		      time.

	       PROVII_CACHE
		      Path to directory used to  store  intermediatary  files  created
		      during installation.  Cleared at the end of every installation.

	       PROVII_SCOPE
		      Can  be set to either "system" or "user" - used to determine the
		      path to use for the installation directories  (unless  they  are
		      given  explicitly  as  environment  variables or in the proviirc
		      file).

	       PROVII_USER_BIN
		      Installation path for all executables (when PROVII_SCOPE=user).

	       PROVII_USER_MAN
		      Installation path for all MAN pages (when PROVII_SCOPE=user).

	       PROVII_USER_ZSH_COMP
		      Installation   path    for    all    ZSH    completions    (when
		      PROVII_SCOPE=user & zsh installed).

	       PROVII_USER_BASH_COMP
		      Installation    path    for    all    BASH   completions   (when
		      PROVII_SCOPE=user & bash-completion).

	       PROVII_SYSTEM_BIN
		      Installation path for all  executables  (when  PROVII_SCOPE=sys‐
		      tem).

	       PROVII_SYSTEM_MAN
		      Installation path for all MAN pages (when PROVII_SCOPE=system).

	       PROVII_SYSTEM_ZSH_COMP
		      Installation    path    for    all    ZSH    completions   (when
		      PROVII_SCOPE=system & zsh installed).

	       PROVII_SYSTEM_BASH_COMP
		      Installation   path   for    all    BASH    completions    (when
		      PROVII_SCOPE=system & bash-completion installed).


	FILES
	       Configuration
		      $XDG_CONFIG_HOME/proviirc
		      $HOME/.config/proviirc


	       Log    $HOME/.provii.log


	HOMEPAGE
	       https://github.com/kriipke/provii


	BUGS
	       No known bugs. File an issue report:
	       https://github.com/kriipke/provii/issues


	AUTHOR
	       Spencer Smolen (mail@spencersmolen.com)



	provii                            2020-11-01                         PROVII(1)

provii install

The install subcommand is the crux of provii as this is how you install the command-line utilities available via provii. Note that when you use provii using method 1, interally provii just runs this command. Example output of provii install fd:

provii install fd

For more information, run provii install -h.

provii env

The env subcommand takes an optional argument, an installer name, and is meant to gather facts and define variables that would be used in the provii installer provided. For example, if provii env fd was run as root it would produce output that would look something like the following:

provii env fd

For more information, run provii env -h.

provii ls

The ls subcommand allows you to print all the command-line tools avaliable for installation via provii. Example output:

provii ls

For more information, run provii ls -h.

Note
Alternatively, you can browse the installers avaliable using your browser at https://github.com/kriipke/provii/tree/master/installs

provii cat

The cat subcommand takes the name of an installer as an argument and prints the actual script that will be run without running it. Example output of provii cat fd:

provii cat fd

Note that unless you are writing a provii installer yourself or are doing debugging, you really don’t need to know anything about the script or how it works unless you just want to make sure you’re not running anything malicious.

For more information, run provii cat -h.

How provii works

provii works by gathering the necessary information about the system its running on to install the pre-built binary (as well as man pages & shell completions if available), and then fetching & running the appropriate installion scripts hosted in provii’s github repository in the installs directory.

When gathering facts, provii intelligently determines the relevant settings based on, most imporarntly, whether it was run with root privilages or not along with things like operating system, processor type & installed version of libc.

For example, during a typical install of fd, an alternative to the find tool written in Rust, if the default settings are used, provii would install the following files:

  1. fd binary

  2. fd man page

  3. fd shell completions

For more information on where these files are installed and how that location is determined see Environment and How provii works below.

The script runs through the following steps to install a piece of software:

  1. determining whether it is being run with root privilages or not and subsequently setting the variable $PROVII_SCOPE, which will either be defined as system or user

  2. gathering information about directories to place binary files, man pages, and shell completions based on $PROVII_SCOPE

  3. gathering information about the current system running provii needed to select and install the correct binary, including this like processor type and operating system

  4. next, provii creates a bash subshell with a clean environment and populates that environment with variables that will be used while running the installation, defined during steps 1, 2 & 3 - for more information on what these varaibles are and how they are used see Environment.

  5. finally, within the newly created subshell provii runs the requested installer that has been fetched from the provii Github repository in the installs directory.

Environment

This section explains all the varaibles that exists in the subshells in which the provii installers are run and how they are defined. This information is of particular interest to those who wish to modify the way that provii works or those who wish to contribute an installer script of their own to the project.

All of the variables listed in Environment below are the names of the variables as they are used in the provii script itself. These variables are then used to populate the environment of the subshell in which the installer is run under different names. So, for example, when run as root the value assigned to $PROVII_SYSTEM_BIN will be avaliable in the installer subshell via $BIN. Likewise, if provii is run as a regular user the value assigned to $PROVII_USER_BIN will be avaliable via $BIN.

These variables are redefined by new names in the subshell for two reasons:

  1. so that the installer scripts can be written without any regard to whether they will be run with root privilages or not, while at the same time allowing for provii to be intricately configured in the proviirc

  2. so that any exported varaibles in the shell from which provii is run, e.g. exported varaibles in the environment of the shell in which you run ./provii …​ do not interfere with the operation of provii. For example, if provii did not do this and you had an environment variable named $BIN, provii will use that variable as the default install destination for binary files which could cause unintended consequences.

Below is a list of all the varaibles avaliable within the subshells (and consequently the installer scripts) along with how they are defined in their parent shell, e.g. the main provii script before the subshell is entered.

Note
Variables defined in a proviirc file, should one exist on the machine, will not be set according to the logic below, but rather retain the value defined in the proviirc file (assuming that value is not null), see Configuration for more information.
variable definition logic

$SCOPE

  1. output of id -u determines value of $PROVII_SCOPE

  2. when passed to subshell, $PROVII_SCOPE$SCOPE

$OS

  1. output of uname -s determines value of $PROVII_SYSTEM

  2. when passed to subshell, PRVOII_SYSTEM$OS

$ARCH

  1. output of uname -m determines value of $PROVII_MACHINE

  2. when passed to subshell, PRVOII_MACHINE$ARCH

$LIBC

  1. output of ldd --version determines value of $PROVII_LIBC

  2. when passed to subshell, $PROVII_LIBC$LIBC

$CACHE

  1. hard-coded, PROVII_CACHE=~/.cache/provii

  2. when passed to subshell, $PROVII_CACHE$CACHE

$LOG

  1. hard-coded, PROVII_LOG=$PROVII_CACHE/run.log

  2. when passed to subshell, $PROVII_LOG$LOG

$BIN

  1. value of $PROVII_BIN set

    1. when run as root, PROVII_BIN=/usr/local/bin

    2. when run as regular user, PROVII_BIN=~/.local/bin

  2. when passed to subshell, $PROVII_BIN$BIN

$MAN

  1. value of $PROVII_MAN set

    1. when run as root

      1. if /usr/share/man listed in output of manpath, then /usr/share/man$PROVII_MAN

      2. elif, first directory listed in the output of manpath$PROVII_MAN

      3. else, $PROVII_MAN remains unset

    2. regular user

      1. if ~/.local/share/man listed in output of manpath, then ~/.local/share/man$PROVII_MAN

      2. elif, first directory listed in the output of manpath prefixed with $HOME$PROVII_MAN

      3. else, $PROVII_MAN remains unset

  2. when passed to subshell, if $PROVII_MAN was set $PROVII_MAN$MAN

$ZSH_COMP

  1. value of $PROVII_ZSH_COMP set

    1. when run as root

      1. if first directory contained in the value of $fpath containing completion prefixed with /usr or /etc$PROVII_ZSH_COMP

      2. elif, first directory contained in the value of $fpath containing custom prefixed with /usr or /etc$PROVII_ZSH_COMP

      3. else, $PROVII_ZSH_COMP remains unset

    2. when run as regular user

      1. if first directory contained in the value of $fpath containing completion prefixed with $HOME$PROVII_ZSH_COMP

      2. elif, first directory contained in the value of $fpath containing custom prefixed with $HOME$PROVII_ZSH_COMP

      3. else, $PROVII_ZSH_COMP remains unset

  2. when passed to subshell, if $PROVII_ZSH_COMP was set $PROVII_ZSH_COMP$ZSH_COMP

$BASH_COMP

  1. value of $PROVII_BASH_COMP set

    1. when run as root, PROVII_BASH_COMP=/etc/bash_completion.d

    2. when run as regular user

      1. when bash-completion version >= 2.9, PROVII_BASH_COMP=~/bash-completion.d

      2. when bash-completion version < 2.9, PROVII_BASH_COMP=${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion.d

  2. when passed to subshell, $PROVII_BASH_COMP$BASH_COMP

Configuration

If you wish to change the default operation of provii as explained in the Environment section, you may explicitly define the value of the variables that dictate the operation of provii in a proviirc file. provii will check for a configuration file containing variable definitions in the following locations:

  • $XDG_CONFIG_HOME/proviirc, if $XDG_CONFIG_HOME is defined

  • $HOME/.config/proviirc otherwise

Below is a sample configuration file with all of the possible variables and their default values. Variables without values listed below do not have a hard-coded default value but rather, their value is dynamically determined at runtime unless they are explicitly defined in the configuration file. For more information see Environment.

Note
The proviirc can contain as few or as many variables as you wish. However, it would only make sense to explictly define a variable in proviirc if you wish to override the default value as determined by the logic explained in the Environment section.
# Sample ~/.config/proviirc with default values
# variables without values have values that are dynamically determined at runtime,
# unless they are explicitly defined in the proviirc, in which case that value is used

PROVII_CACHE=~/.cache/provii
PROVII_LOG=$PROVII_CACHE/run.log

PROVII_SCOPE=
PROVII_ARCH=
PROVII_OS=
PROVII_LIBC=

# variables used when $PROVII_SCOPE == system

PROVII_SYSTEM_BIN=/usr/local/bin
PROVII_SYSTEM_MAN=/usr/share/man
PROVII_SYSTEM_ZSH_COMP=
PROVII_SYSTEM_BASH_COMP=/etc/bash_completion.d

# variables used when $PROVII_SCOPE == user

PROVII_USER_BIN=~/.local/bin
PROVII_USER_MAN=~/.local/share/man
PROVII_USER_ZSH_COMP=
PROVII_USER_BASH_COMP=