Specifiying data files¶
Most packages have some files besides pure code: configuration, data files, documentation, etc... When those files need to be installed, you should use DataFiles sections. Each such section has two mandatory fields, to specify the target directory (where files are installed) and which files are specific to this section:
DataFiles: manage TargetDir: /usr/man/man1 Files: fubar/fubar1
This will install the file top_dir/fubar/fubar1 into /usr/man/man1/fubar/fubar1.
Flexible install scheme¶
Hardcoding the target directory as above is not flexibe. The user may want to install manpages somewhere else. Bento defines a set of variable paths which are customizable from bentomaker, with platform-specific defaults. For manpages, the variable is mandir:
DataFiles: manpage TargetDir: $mandir/man1 Files: fubar/fubar.1
Now, the installation path is customizable, e.g.:
bentomaker configure --mandir=/opt/man
will cause the target directory to translate to /opt/man/man1. Moreover, as mandir default value is defined relatively to $prefix ($prefix/man on unix), modifying the prefix will also change how mandir is expanded at install time:
# $mandir is automatically expanded to /opt/man bentomaker configure --prefix=/opt
If you do not want to install files with their directory component, you need to use the SourceDir option:
DataFiles: manpage TargetDir: $mandir SourceDir: fubar Files: fubar.1
will install fubar/fubar.1 as $mandir/fubar.1 instead of $mandir/fubar/fubar.1.
Custom data paths¶
While the default list should cover most package needs, it is sometimes useful to define custom path variable:
Path: foo Description: foo directory Default: $datadir/foo
Bentomaker will automatically add the –foodir option, and $foo will be expanded to the customized value (or $datadir/foo by default). The description will be used as a description in the help message.
It is sometimes necessary to define platform-specific default for custom paths. This can be done as follows:
Path: foo Description: foo directory if os(darwin): Default: /Library/foo else: Default: $bin/foo
FIXME: refer to conditional
Retrieving data files at runtime¶
It is often necessary to retrieve data files from your python code. For example, you may have a configuration file which needs to be read at startup. The simplest way to do so is to use __file__ and refer to data files relatively to python code location. This is not very flexible, because it requires dealing with platform idiosyncraties w.r.t. file location. Setuptools and its descendents have an alternative mechanism to retrieve resources at runtime, implemented in the pkg_resource module.
Bento uses a much simpler system, based on a simple python module generated at install time, containing all the relevant information. This file is not generated by default, and you need to define which file will contain all those variables with the ConfigPy field:
This tells bento to generate a module, and install it into foo/__bento_config.py. The path is always relative to site-packages (e.g. /usr/local/lib/python2.6/site-packages/foo/__bento_config.py by default on unix). The file looks as follows:
DOCDIR = "/usr/local/share/doc/config_py" SHAREDSTATEDIR = "/usr/local/com" ...
to that you can import every path variable with its expanded value in your package:
from foo.__bento_config import DOCDIR, SHAREDSTATEDIR
As the generated python module is a simple python file with pair values, it is easy to modify it if desired (for debugging, etc...), and understandable by any python programmer.
If you need to support the case where the package has not been built yet, you can do as follows:
try: from foo.__bento_config import DOCDIR, SHAREDSTATEDIR except ImportError: # Default values (so that the package may be imported/used without # being built) DOCDIR = ...
This is not done by default as it is not possible to know the right default value.
Assuming the following bento file:
... DataFiles: test_data SourceDir: data TargetDir: $pkgdatadir Files: foo.dat ConfigPy: foo/__bento_config.py
you can access “foo.dat” as follows in your package:
try: from foo.__bento_config import PKGDATADIR except ImportError: PKGDATADIR = "data" # default value data = os.path.join(PKGDATADIR, "foo.dat")
This will point to the right location independently on $pkgdatadir value.
Recursive package description¶
If you have a package with a lot of python subpackages which require custom configurations, doing everything in one bento.info file is restrictive. Bento has a simple recursive feature so that one bento.info can refer to another bento.info:
... Recurse: foo, bar
The Recurse field indicates to bento that it should look for bento.info in both foo/ and bar/ directories. At this time, those bento.info files support a strict subset of the top bento.info. For example, no metadata may be defined in sub-bento.info.
Let’s assume that you have a software with the packages foo, foo.bar and foo.foo. The simplest way to define this software would be:
... Library: Packages: foo, foo.bar, foo.fubar
Alternatively, an equivalent description, using the recursive feature:
... Recurse: foo Library: Package: foo
and the foo/bento.info:
... Library: Packages: bar, fubar
The packages are defined relatively to the directory where the subento file is located. Obviously, in this case, it is overkill, but for complex, deeply nested packages (like scipy or twisted), this makes the bento.info more readable. It is especially useful when you use this with the hook file mechanism, where each subento file can drive a part of the configure/build through command hooks and overrides. In that case, the hook file defined in a subdirectory only sees the libraries, modules, etc... defined in the corresponding bento.info by default (see hook section).