Source code for biolite.config
# BioLite - Tools for processing gene sequence data and automating workflows
# Copyright (c) 2012 Brown University. All rights reserved.
#
# This file is part of BioLite.
#
# BioLite is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BioLite is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BioLite. If not, see <http://www.gnu.org/licenses/>.
"""
Loads the entries in the *biolite.cfg* file into two member dictionaries,
`resources` (default parameters and data paths) and `executables` (paths to
external executables called by :ref:`wrappers`).
By default, BioLite will look for the configuration file at the following
paths, in order of preference:
* the value of the $BIOLITE_CONFIG environment variable
* $HOME/.biolite/biolite.cfg
* $PWD/biolite.cfg
"""
import ConfigParser
import os
import shlex
import subprocess
import sys
import utils
[docs]def init(executables, resources):
"""
Called at module load to parse the BioLite configuration file.
"""
# name of configuration file
filename = 'biolite.cfg'
# construct list of paths to search for config file
paths = list()
# environment variable takes precendent, if it exists
envpath = os.getenv("BIOLITE_CONFIG")
if envpath != None:
envpath = os.path.expanduser(envpath)
if not os.path.isfile(envpath):
utils.info("warning: config path '%s' does not exist" % envpath)
paths.append(envpath)
# then default to the user's home directory, the installation path for the
# software, or the current directory
paths.append(os.path.join(os.environ['HOME'], '.biolite', filename))
paths.append(os.path.join("/usr/local/share", 'biolite', filename))
paths.append(os.path.join(os.getcwd(), filename))
parser = ConfigParser.ConfigParser()
for path in paths:
if os.path.isfile(path):
parser.read(path)
for key,val in parser.items('executables'):
executables[key] = os.path.expanduser(val)
for key,val in parser.items('resources'):
resources[key] = os.path.expanduser(val)
resources['configpaths'] = [path]
break
if 'configpaths' not in resources:
utils.die("""can't find config file at:\n %s
Please create a config in one of these locations, or set the path to your
config with the BIOLITE_CONFIG environment variable.""" % '\n '.join(paths))
# Add additional resource values from config files specified by an
# environment variable.
envconfigs = os.getenv("BIOLITE_ADD_CONFIGS")
if envconfigs:
for path in envconfigs.strip().split(','):
if path:
if os.path.isfile(path):
parser.read(path)
for key,val in parser.items('resources'):
resources[key] = os.path.expanduser(val)
resources['configpaths'].append(path)
else:
utils.info("warning: additional config path '%s' does not exist" % path)
# Override resource values from environment variable.
envpairs = os.getenv("BIOLITE_RESOURCES")
if envpairs:
for token in envpairs.strip().split(','):
pair = token.split('=')
if len(pair) == 2:
key, val = pair
resources[key] = os.path.expanduser(val)
utils.info("override: %s=%s" % (key, resources[key]))
else:
utils.info("WARNING: invalid token '%s'" % token)
# Set a hostlist for distributed processing in wrappers that use GNU
# parallel.
envhosts = os.getenv("BIOLITE_HOSTLIST")
if envhosts:
utils.info("hostlist=%s" % envhosts)
resources['hostlist'] = envhosts
[docs]def get_resource(key):
"""
Lookup a resource from the configuration file for `key` and print
an intelligble error message on KeyError.
"""
try:
return resources[key]
except KeyError:
utils.die(
"missing value for '%s' in your biolite.cfg at\n%s" % (
key, resources.get('configpath', '[none found]')))
[docs]def get_resource_default(key, default):
"""
Lookup a resource from the configuration file for `key` and return the
`default` value if the key is not found.
"""
return resources.get(key, default)
[docs]def get_command(key):
"""
Lookup the full path to an executable `key` in the configuration file and
print an intelligble error message if the path can't be found in the user's
PATH environment variable (similar to the Unix utility `which`).
The output is a list, starting with the full path to the executable, ready
for input to subprocess.Popen. Any trailing parameters in config entry for
the executable are preserved in this list.
If there is no config entry for the key, or the entry is blank, the key is
used as the name of the executable. Thus, the config file only needs to
override executable paths that won't resolve correctly using PATH.
"""
executable = executables.get(key)
if not executable:
cmd = [key]
else:
cmd = shlex.split(executable)
cmd[0] = utils.which(cmd[0])
if not cmd[0]:
if not executable:
utils.info(
"empty or missing executable '%s' in config file at:\n %s" % (
key, resources.get('configpath', '[biolite.cfg not found]')))
executable = key
utils.die(
"couldn't find executable '%s' in your PATH:\n %s" % (
executable, '\n '.join(os.environ["PATH"].split(os.pathsep))))
return cmd
[docs]def set_database(path):
"""
Override the path to the BioLite database.
"""
if os.path.isdir(path):
path = os.path.join(path, 'biolite.sqlite')
if os.path.exists(path):
resources['database'] = path
else:
utils.die("couldn't find BioLite database at:", path)
# These dicts are accessible once this module is loaded...
executables = dict()
resources = dict()
# ... and the config file is automatically parsed at module load.
init(executables, resources)
# Detect Linux vs BSD kernel.
kernel = subprocess.check_output(['uname']).strip()
uname = kernel
bindir = '/usr/local/bin'
libdir = '/usr/local/lib'
datadir = os.path.join('/usr/local/share', 'biolite')