ConMan is tool for managing dotfiles and other config files on multiple unix systems, each requiring largely the same set of files but with minor changes in each location. The system is built on the m4 macro processor which is widely installed and reasonably powerful.
Configuration/dot file templates should be placed in ConMan/configs/*.m4
(can be overridden by -t
). In the simplest case this requires just a single
modification. For example:
CONFIG_FILE(my bash rc, ~/.bashrc) # bashrc continues as-per-normal below...
This defines the contents of ~/.bashrc
for all machines. Nice and straight
forward. Note: as this is still a 'normal' m4 script you must ensure that
templates don't accidentally trigger any m4 functionality.
Obviously this isn't very useful as we want to make things only appear for certain machines. Say we have a config file we only want on machines in my university department, we can make the config file conditional like so:
CONFIG_FILE(ARCADE Settings, ~/.arcaderc, UNI) # ...configuration file for some university software here...
The extra argument here (UNI
) is an expression saying which computers this
file should be present on. See the 'Defining Computers' section to see how you
define these names.
Given that your dotfiles are also now in m4 you can use other macros to clean up your configs. Some macros are provided by ConMan to help make fine-grain conditional inclusion easier:
CONFIG_FILE(Example File, ~/.examplerc) These lines appear on all computers (as usual). ON_COMPUTER(LAPTOP) These lines only appear on my laptop's version of exaple RC. How lovely! ELSE_COMPUTER() These lines only appear on other computers' versions. END_COMPUTER() IF_COMPUTER(LAPTOP|UNI_RESEARCH_DOMAIN, `only appears on laptop & uni on the research domain', `appears everywhere else')
Finally, it is also worth noting that you can have multiple files defined in one template. For example, your bashrc and bashprofile all in one template:
CONFIG_FILE(my bashrc, ~/.bashrc) # Stuff from your bashrc goes here. Maybe you define/use some handy m4 macros? CONFIG_FILE(my bashprofile, ~/.bashprofile) # Stuff for the bash profile goes here (still the same file!). Maybe you can # use some of those handy macros again here too?
A list of all the computers which your config files might apply to should be
defined in the 'global' configuration file ConMan/config.m4
(or
alternatively the file specified by the -C
argument) like so:
DEFINE_COMPUTER(LAPTOP) DEFINE_COMPUTER(DESKTOP) DEFINE_COMPUTER(UNI_TEACHING_DOMAIN) DEFINE_COMPUTER(UNI_RESEARCH_DOMAIN)
It is also possible to group combinations of computers (and groups) under a common label. For example, you can add:
DEFINE_GROUP(PERSONAL, LAPTOP | DESKTOP) DEFINE_GROUP(UNI, UNI_RESEARCH_DOMAIN | UNI_TEACHING_DOMAIN)
Each computer also has a 'local' configuration file ConMan/local_config.m4
(or alternatively the file specified by the -c
argument) which simply
defines which computer this actually is:
SET_COMPUTER(LAPTOP)
When a config file is created from a template, a backup is made in
ConMan/backups
(or the directory set by -b
). If the file being created
doesn't match its backup then you'll be asked to confirm the overwrite. This is
designed to protect against overwriting changes made to config files by other
utilities.
You can force ConMan to overwrite files which don't match their backups using
the -f
option.
Using conman -e filename
will attempt to open the M4 file which created the
given file in your $EDITOR.
There are a few thins you should be aware of when using ConMan. Hopefully these should be resolved over time but for now...
- It is worth mentioning a second time: your templates are just regular m4 and so must be careful to avoid any keywords etc. A list of extra keywords to avoid due to ConMan can be found by reading its source (sorry...).
- Your m4 templates actually get parsed 1+n times (where n is the number of config files defined within it). This is due to the current bodge being used to get multiple files (and their file names) out of an m4 file. This may change to use a different bodge at some time in the future which solves this...
- Be very careful using m4's
divert
command in your m4 scripts... Hopefully this will be cleaned up in the future...
ConMan can be extended with plugins giving it extra functionality. These are documented below.
The GIT_REPO(local_dir, repo_url)
macro requests the git repo stored in
local_dir
is pulled from repo_url
. For example, here it is fetching
various VIM plugins:
CONFIG_FILE(my vim configs, ~/.vimrc) " stuff for my .vimrc goes here as usual GIT_REPO(~/.vim/bundle/pathogen, git://github.com/tpope/vim-pathogen.git) GIT_REPO(~/.vim/bundle/fugitive, git://github.com/tpope/vim-fugitive.git) GIT_REPO(~/.vim/bundle/ctrlp, git://github.com/kien/ctrlp.vim.git)
The plugin can be disabled using the -g
flag.
The INSTALL_BINARY(src, dst)
macro copies a binary file (make sure it
doesn't end in .m4 to prevent conman processing it as a template) at the
location "src" (relative to the m4 file's directory) into dst. For example, this
installs a nice font for vim:
CONFIG_FILE(my vim configs, ~/.vimrc) " stuff for my .vimrc goes here as usual INSTALL_BINARY(Monaco_Linux.ttf,~/.fonts/)
The plugin can be disabled using the -B
flag.
ConMan searches for plugins in ConMan/plugins
(but this can be overridden by
-p
). There are two types of plugin:
- Files ending in
.m4
will be included after ConMan's header and before the target m4 file. What you do here is up to you. Have fun. - Executable (bash) files ending in
.sh
will be sourced by ConMan. The rest of the documentation in this section describes the facilities available to the plugin writer.
The easiest way to define an macro is to define a suitable bash function and use
add_m4_command
to make it available to m4 like so:
function touch_file() { touch "$1" } add_m4_command "TOUCH_FILE" "touch_file"
This defines the m4 macro TOUCH_FILE
which essentially wraps the bash
function touch_file
passing on all arguments. For example if you place the
following in a template:
TOUCH_FILE(/tmp/some_file)dnl
The file /tmp/some_file
will be touched.
Warning: Arguments given to the m4 wrapper will be (double) quoted but not escaped so watch out!
The environment variable $M4_FILE is set with the full path of the m4 file which called the the macro.
You can append m4 commands into the file defined by $M4_INCLUDE
which is
included by m4 after the ConMan header and before the target m4 file.
You can add command-line arguments to ConMan.
You can define an argument which, when given, executes a function using
add_argument
. This takes an argument to match, a bash expression to eval
if found and a documentation string, e.g.:
add_argument -t "echo testing $1;shift" "Print 'testing' and the argument on stdout."
Remember that arguments can be accessed via $1
etc. remember to shift any
that you use.
If you just want to add an argument that overrides a bash variable with the
argument given, you can use add_argument_var
which takes an argument to
match, a variable name to override and a help string. For example:
MY_VAR="initial value" add_argument_var -v "MY_VAR" "Override MY_VAR."
If called without an argument, $MY_VAR
will remain 'initial value
' but
if called with -v something
then $MY_VAR
will be set to 'something
'.