Dram - Keep Your Package Manager Packaged¶
Author: Scott Torborg
Dram is a POSIX-specific tool for managing shell environments. The basic goal is to make it possible to install new shell-based software, from a number of different sources, with the confidence that it won’t mess up your global environment.
Instead of simply installing new software into /usr/local
, you can quickly
activate a new “dram”, and install it there. If something goes wrong, no
problem: just delete the entire dram.
You can also create new drams that contain an instance of Homebrew or Macports. This makes it easy to use both Homebrew and Macports at the same time, or multiple instances of either. Again, if somsething goes wrong, nothing to worry about: just delete the dram.
Contents¶
Basics¶
Concepts¶
Each new sandboxed environment is referred to as a dram.
The environment variable DRAM_ROOT
is the root directory where all drams
are kept. Each dram is a subdirectory.
Warning
Root privileges should generally not be necessary to install anything into
a dram. Avoid the temptation to use sudo
. You may wish to consider
changing the ownership of your /usr/local
directory to root in order to
prevent any dram usage from “spilling” into the global environment.
Dram Types¶
- Plain drams are intended for installing most open source “directly”, via
a
./configure
script or similar mechanism. They are not populated with any initial files or directories, but set up environment variables that will - Plain-with-python drams are the same as Plain drams with the addition of an integrated python virtual environment for the dram.
- Homebrew drams populate an instance of Homebrew.
- Macports drams populate an instance of MacPorts.
Command-Line Usage¶
Dram includes a command-line utility which is the expected entry point for most usage. Some examples are below. You can also see the utility itself for more info:
$ dram help
Creating a New Dram¶
This will create a new dram you can then install stuff into.:
$ dram create example
To create a dram of a particular type:
$ dram create -t macports example
When creating a dram of type plain-with-python
you can also pass the
-p
and --system-site-packages
flags and they will be passed through
to the virtual environement when it is created for that dram.
Using The Dram¶
Creating a dram automatically switches to it, but if you want to switch to an already created dram:
$ dram use example
Note that if you have set the DRAM_AUTO_CDSOURCE
environment variable, then dram will automatically
switch to the source directory of the activated dram whenever you do dram use <dram name>
Dram includes wrappers around common build tools (autotools and cmake) to ease installing software into the dram.
Installing Software with CMake¶
As an example, let’s install libftdi from a source tarball.
First move into the source subdirectory, by convention:
$ dram cdsource
Download and extract the package here:
$ curl -O https://www.intra2net.com/en/developer/libftdi/download/libftdi1-1.5.tar.bz2
$ tar -xvf libftdi1-1.5.tar.bz2
$ cd libftdi1-1.5
Invoke CMake using the dram wrapper:
$ dram cmake ..
Install normally, which will install into this dram’s directory structure:
$ make && make install
Install Software with Autotools¶
Install autotools-based software is similar. Here is a typical installation of liquid-sdr:
$ dram cdsource
$ git clone https://github.com/jgaeddert/liquid-dsp.git
$ cd liquid-dsp
$ ./bootstrap.sh
$ dram configure
$ make && make install
Listing Drams¶
List all the current drams in your root:
$ dram list
If the -l
flag is passed to dram list
, then the size of each dram on disk will be printed as well.
Extending Behavior with Hooks¶
You can extend dram to add special user-specific behavior with specially-named
function hooks. To implement a hook, simply define a function with the hook’s
name in your shell environment (for example, in .bashrc
).
Example¶
Set the shell prompt to include the name of the activated dram, upon activation:
function dram_hook_postactivate() {
local dram_name=$1
local dram_prefix=$2
PS1="($local_dram_name) $PS1"
}
Deactivate a Python virtualenv
before activating a dram, if one is
currently active:
function deactivate_any_virtualenv () {
type deactivate >/dev/null 2>&1
if [ $? -eq 0 ]
then
deactivate
fi
}
function dram_hook_preactivate () {
local dram_name=$1
local dram_prefix=$2
deactivate_any_virtualenv
}
Available Hooks¶
Currently available hooks are:
dram_hook_preactivate
: Called prior to activating a dram, with the name and
path prefix of the dram.
dram_hook_postactivate
: Called immediately after activating a drone, with
the name and path prefix of the dram.
Contributing¶
Patches and suggestions are strongly encouraged! GitHub pull requests are preferred, but other mechanisms of feedback are welcome.