How to handle configuration files with distutils to respect unixen's FHS?
Suppose we have a program called foo
.
If use absolute path:
setup(...,
data_files=[...,
('/etc', ['foo.cfg'])]
)
Then foo$ python setup.py --prefix=/usr/local
and开发者_开发问答 we will have /etc/foo.cfg
.
But we should have /usr/local/etc/foo.cfg
instead according to FHS.
What if we use a relative path?
setup(...,
data_files=[...,
('etc', ['foo.cfg'])]
)
Then if we use the default install path, i.e. install to /usr, we will have /usr/etc/foo.cfg
. Bad
luck again.
So how to do it right?
P.S. To avoid make the problem more complicated, we assume that this program
foo
cannot run under non unix environment.
Sub-classing distutils.command.install.install
is not strictly necessary. Instead, data_files
could be passed to setup
, as per distutils
documentation on 'Installing Additional Files'.
e.g.
setup(
...
data_files = [
(conf_path, ['foo.cfg'])
]
)
where conf_path
is calculated as per your own requirements. i.e. construct it by testing sys.prefix
(instead of self.prefix
), like @weakish did above.
It seems there is no easy way. The problem is that config files are special data files and they deserve special treatment.
So, write our own class:
class myinstall(distutils.command.install.install):
if self.prefix == '/usr':
self.conf_prefix = '/etc'
else:
self.conf_prefix = self.prefix + '/etc'
install.finalize_options(self)
def install_conf(self):
self.mkpath((self.root or '') + self.conf_prefix)
for file in self.distribution.conf_files:
dest = (self.root or '') + self.conf_prefix + '/' +
os.path.basename(file)
self.copy_file(file, dest)
# blah blah blah
Then:
setup(# blah blah blah
conf_files = ['foo.cfg']
cmdclass = {'install': myinstall,
# blah blah blah
}
)
精彩评论