Installer
This is a package for installing software on linux.
Ideally, all installation in a "normal" linux distribution should be handled by a package manager, and this simple package is in no way meant to replace this functionality. There are however many cases in which one must install either a highly customized configuration, "bleeding edge" software, or software which is not easily available.
This package was originally created to manage my dotfiles and this is the best (and presumably, by far the most common) use case for this package.
Installation (of Installer.jl itself)
In some contexts simply cloning the package git clone https://gitlab.com/ExpandingMan/Installer.jl
may be best.
You can also clone the package with the package manager
Pkg.dev("https://gitlab.com/ExpandingMan/Installer.jl")
Currently the package is not registered and there are no tags.
For the time being, Installer.jl quite deliberately has no dependencies outside of the Julia stdlib. This is to ensure that latency due to compilation is minimized when running it. As solutions for reducing Julia's startup latency improve, I may at some point consider adding useful dependencies.
Usage
Setting Up Directories
Installer.jl expects the locations of a home directory and a directory from which to install configuration files. The following environment variables are relevant:
INSTALLER_DOTFILES_DIR
: this is a directory that should mirror the structure of your home directory. Configs in this directory (usually dotfiles, but they can be anything) by default get installed to the same relative path in$HOME
.INSTALLER_PROGRAMS_DIR
: a directory containing Julia source files which provide program install configurations (see below).
If this package is run interactively, i.e. in the Julia REPL, it will prompt the user with various requests to make installation safer and easier.
Getting Started
When used interactively, when the runtime of the package module starts, it will print a helpful message showing available functions.
During interactive use, run
install()
to bring up a selectable list of installable programs. This list will be obtained from the configurations you gave it either with INSTALLER_PROGRAMS_DIR
or with addprograms(dir)
.
This package is also intended to be useful for non-interactive scripts. If the Julia REPL is not running, instead of prompting the user, reasonable defaults will be used. Such usage is not as safe: for example, with the REPL the installer will prompt you before overwriting anything, but if you use it in a script it will overwrite without asking.
The Program
Interface
Installation is defined via the Program
struct. This is a simple data sctructure providing users the ability to easily specify common installation tasks.
A list of exmaples of configuration definitions can be found here.
An example of an installation config is as follows:
const alacritty = Program(:alacritty,
configs=[".config/alacritty/alacritty.yml"],
packages=["alacritty"]
)
The first argument is the name used to identify the program config. Additionally, Program
accepts keyword arguments which are useful for describing common installation tasks. In this example, Insatller.jl will copy the alacritty configuration YAML from $INSTALLER_DOTFILES_DIR/.config/alacritty/alacritty.yml
to $HOME/.config/alacritty/alacritty.yml
(prompting the user and offering the chance to edit a diff before overwriting, if in interactive mode) and it will attempt to install the package manager package alacritty
(this will be skipped if not sudo
, since package managers require sudo
to run).
Available keyword arguments are:
configs
(Vector{String}
): Config files to be copied from$INSTALLER_DOTFILES_DIR
to the same relative location in$HOME
. When used in interactive mode, you will be prompted whether you'd like to overwrite or edit the diff.downloads
(Vector{Download}
): Specifies downloads from URL's to their target, and whether the target should be made executable.repos
(Vector{GitRepo}
): A list of git repos to clone and update.commands
(Vector{Cmd}
): Specifies shell commands to be executed.packages
(Vector{String}
): Specifies package manager packages to be installed (will requiresudo
).aux
(Dict{Symbol,Any}
): A dict storing any other data that might be needed.
Adding Programs
Program configs should be provided in Julia source files. The files provided will be evaluated directly into the Installer.Programs
module. It is recommended that these be defined as a const
with the same name as the first argument of Program
. These can be defined in as many separate files as the user would like.
To add all Julia source code files in a directory to Installer.Programs
set the value of the environment variable INSTALLER_PROGRAMS_DIR
to the chosen directory or call addprograms(dir)
.
Custom Installation Steps
Sometimes installation steps are required which are hard to describe in simple lists. For these cases, the aux
function can be defined to run arbitrary blocks of code. This function is run on the sole argument p::Program{name}
where name
is a Symbol
which designates the program. See, for example, the following aux
method
function aux(p::Program{:neovim})
# get AppImage unless FUSE is unavailable
if I.hasfuse()
download(Download("https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage",
"sbin/nvim", true))
else
I.pminstall("neovim") # installation via package manager
end
I.installconfig(".config/nvim/init.vim")
# we run this here to make sure that `which nvim` is evaluated *last*
nvim = String(readchomp(`which nvim`))
I.runcommand(Cmd([nvim, "-c", "PlugInstall", "-c", "UpdateRemotePlugins", "-c", "qa", "--headless"]))
end
As the function is evaluated in the Programs
submodule, functions from Installer
must be qualified with either Installer
or the alias I
, as seen above.
It is recommended that functions from Installer
be used when defining aux
methods, as these provide helpful utility features such as prompts when used interactively, however, of course you can put anything in aux
you want. Additionally, you can put anything in the program soruce files you want that does not conflict with existing functionality.
The Download
Struct
Download
is a struct provided to let users easily specify where something should be downloaded from and where it should be downloaded to, as well as whether the donwloaded files should be made execeutable. For example
Download("https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage",
"sbin/nvim", true)
can be used to download the binaries from the URL provided to the file $HOME/sbin/nvim
, after which it will be made executable.