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.
you must have a valid setup.py file apart from setup. cfg and pyproject. toml . You can use the same dummy setup file I shared in the previous section that makes just a single call to the setup() method.
The setup.py and setup. cfg files are artefacts of the setuptools module which is designed to help with the packaging process. It is used by pip whose purpose is to install a package either locally or remotely.
distutils. cfg | python mingw win32 build | C:\Python27\Lib\distutils · GitHub.
With the latest version of setuptools, the python setup.py install command is being deprecated (see https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html for more info). It is suggested that you can just pip install . to install a package from source, but this does not compile any Cython code.
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
}
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With