[Distutils] installing data files and headers
Alexandre
Alexandre.Fayolle@logilab.fr
Fri Feb 28 11:17:02 2003
--zCKi3GIZzVBPywwA
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
On Fri, Feb 28, 2003 at 10:31:00AM -0500, Jeremy Hylton wrote:
> We often store data files in a package directory. Zope components
> sometimes have configuration files, presentation files like html and
> images, and other data. One common case is unit test packages, which
> often have test data in them. In all these cases, we find it useful to
> access the data files by loading them from the package directory. You
> get the package's __path__ attribute and look for data files in that
> directory.
>
> The problem is that distutils won't install these files for us. It ends
> up being a lot of work to get the files installed. You need to provide
> a custom distclass to copy the files at build and install time. It
> would be a lot more convenient if distutils would just install the files
> by default.
Attached to this mail is a Distutils extension I coded to install
twisted tml file, but it works fine to install any other file in a
python package. Feel free to use, modify and distribute.
--
Alexandre Fayolle
LOGILAB, Paris (France).
http://www.logilab.com http://www.logilab.fr http://www.logilab.org
Développement logiciel avancé - Intelligence Artificielle - Formations
--zCKi3GIZzVBPywwA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="twisted_distutils.py"
"""Distutils extensions for twisted framework.
This module enables the installation of plugins.tml files using standard
distutils syntax. It adds the following commands to the standard
setup.py commands:
* build_twisted_plugins: build (i.e. copy) plugins
* install_twisted_plugins: install plugins
Additionally, the following commands have been modified to deal with
plugins files:
* sdist
* build
* install
To use these extenstion, you should import the setup fonction from this
module, and use it normally. To list the plugins.tml files, use the
twisted_plugins keyword argument to the setup function:
from twisted_distutils import setup # you can also import Extension if needed
if __name__ == '__main__':
setup(name='my_twisted_app',
version='1.0',
author='me',
packages=['my_package'],
twisted_plugins = ['my_package/plugins.tml'])
Note that you can use this to install files that are not twisted plugins in any package directory of your application.
"""
#
# (c) 2002 Alexandre Fayolle <alexandre.fayolle@free.fr>
# This module is heavily based on code copied from the python distutils
# framework, especially distutils.command.build_script,
# distutils.command.install_script. Many thanks to the authors of these
# modules.
# This module is provided as is, I'm not responsible if anything bad
# happens to you or your python library while using this module. You may
# freely copy it, distribute it and use it in your library or to distribute
# your applications. I'd appreciate if you could drop me an email if you plan
# to do so <wink>.
#
# Happy twisting!
#
from distutils.core import Extension,Distribution,Command
from distutils.command.install import install
from distutils.command.build import build
from distutils.command.sdist import sdist
from distutils.dep_util import newer
from distutils.util import convert_path
import os
class twisted_sdist(sdist):
def add_defaults(self):
sdist.add_defaults(self)
if self.distribution.has_twisted_plugins():
build_twisted_plugins = self.get_finalized_command('build_twisted_plugins')
self.filelist.extend(build_twisted_plugins.get_source_files())
class twisted_install(install):
def initialize_options (self):
install.initialize_options(self)
self.twisted_plugins = None
def has_twisted_plugins(self):
return self.distribution.has_twisted_plugins()
sub_commands = []
sub_commands.extend(install.sub_commands)
sub_commands.append(('install_twisted_plugins', has_twisted_plugins))
class twisted_build(build):
def initialize_options (self):
build.initialize_options(self)
self.twisted_plugins = None
def has_twisted_plugins(self):
return self.distribution.has_twisted_plugins()
sub_commands = []
sub_commands.extend(build.sub_commands)
sub_commands.append(('build_twisted_plugins', has_twisted_plugins))
class build_twisted_plugins (Command):
description = "\"build\" twisted plugins (copy)"
user_options = [
('build-dir=', 'd', "directory to \"build\" (copy) to"),
('force', 'f', "forcibly build everything (ignore file timestamps"),
]
boolean_options = ['force']
def initialize_options (self):
self.build_dir = None
self.twisted_plugins = None
self.force = None
self.outfiles = None
def get_source_files(self):
return self.twisted_plugins
def finalize_options (self):
self.set_undefined_options('build',
('build_lib', 'build_dir'),
('force', 'force'))
self.twisted_plugins = self.distribution.twisted_plugins
def run (self):
if not self.twisted_plugins:
return
self.copy_twisted_plugins()
def copy_twisted_plugins (self):
"""Copy each plugin listed in 'self.twisted_plugins'.
"""
self.mkpath(self.build_dir)
for plugin in self.twisted_plugins:
adjust = 0
plugin = convert_path(plugin)
outfile = os.path.join(self.build_dir, plugin)
if not self.force and not newer(plugin, outfile):
self.announce("not copying %s (up-to-date)" % plugin)
continue
# Always open the file, but ignore failures in dry-run mode --
# that way, we'll get accurate feedback if we can read the
# plugin.
try:
f = open(plugin, "r")
except IOError:
if not self.dry_run:
raise
f = None
else:
f.close()
self.copy_file(plugin, outfile)
class install_twisted_plugins(Command):
description = "install twisted plugins"
user_options = [
('install-dir=', 'd', "directory to install scripts to"),
('build-dir=','b', "build directory (where to install from)"),
('force', 'f', "force installation (overwrite existing files)"),
('skip-build', None, "skip the build steps"),
]
boolean_options = ['force', 'skip-build']
def initialize_options (self):
self.install_dir = None
self.force = 0
self.build_dir = None
self.skip_build = None
def finalize_options (self):
self.set_undefined_options('build', ('build_lib', 'build_dir'))
self.set_undefined_options('install',
('install_lib', 'install_dir'),
('force', 'force'),
('skip_build', 'skip_build'),
)
def run (self):
if not self.skip_build:
self.run_command('build_twisted_plugins')
self.outfiles = self.copy_tree(self.build_dir, self.install_dir)
def get_inputs (self):
return self.distribution.twisted_plugins or []
def get_outputs(self):
return self.outfiles or []
class TwistedDistribution(Distribution):
def __init__(self,attrs=None):
self.twisted_plugins = None
Distribution.__init__(self,attrs)
self.cmdclass = {'install':twisted_install,
'install_twisted_plugins':install_twisted_plugins,
'build':twisted_build,
'build_twisted_plugins':build_twisted_plugins,
'sdist':twisted_sdist,
}
def has_twisted_plugins(self):
return self.twisted_plugins and len(self.twisted_plugins) > 0
def setup(**attrs):
from distutils.core import setup
attrs['distclass'] = TwistedDistribution
setup(**attrs)
--zCKi3GIZzVBPywwA--