How can I add post-install scripts to easy_install / setuptools / distutils?

orestis picture orestis · Oct 30, 2008 · Viewed 9.9k times · Source

I would like to be able to add a hook to my setup.py that will be run post-install (either when easy_install'ing or when doing python setup.py install).

In my project, PySmell, I have some support files for Vim and Emacs. When a user installs PySmell the usual way, these files get copied in the actual egg, and the user has to fish them out and place them in his .vim or .emacs directories. What I want is either asking the user, post-installation, where would he like these files copied, or even just a message printing the location of the files and what should he do with them.

What is the best way to do this?

Thanks

My setup.py looks like so:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from setuptools import setup

version = __import__('pysmell.pysmell').pysmell.__version__

setup(
    name='pysmell',
    version = version,
    description = 'An autocompletion library for Python',
    author = 'Orestis Markou',
    author_email = '[email protected]',
    packages = ['pysmell'],
    entry_points = {
        'console_scripts': [ 'pysmell = pysmell.pysmell:main' ]
    },
    data_files = [
        ('vim', ['pysmell.vim']),
        ('emacs', ['pysmell.el']),
    ],
    include_package_data = True,
    keywords = 'vim autocomplete',
    url = 'http://code.google.com/p/pysmell',
    long_description =
"""\
PySmell is a python IDE completion helper. 

It tries to statically analyze Python source code, without executing it,
and generates information about a project's structure that IDE tools can
use.

The first target is Vim, because that's what I'm using and because its
completion mechanism is very straightforward, but it's not limited to it.
""",
    classifiers = [
        'Development Status :: 5 - Production/Stable',
        'Environment :: Console',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Topic :: Software Development',
        'Topic :: Utilities',
        'Topic :: Text Editors',
    ]


)

EDIT:

Here's a stub which demonstrates the python setup.py install:

from setuptools.command.install import install as _install

class install(_install):
    def run(self):
        _install.run(self)
        print post_install_message

setup(
    cmdclass={'install': install},
    ...

No luck with the easy_install route yet.

Answer

Martin v. Löwis picture Martin v. Löwis · Oct 31, 2008

It depends on how the user installs your package. If the user actually runs "setup.py install", it's fairly easy: Just add another subcommand to the install command (say, install_vim), whose run() method will copy the files you want in the places where you want them. You can add your subcommand to install.sub_commands, and pass the command into setup().

If you want a post-install script in a binary, it depends on the type of binary you are creating. For example, bdist_rpm, bdist_wininst, and bdist_msi have support for post-install scripts, because the underlying packing formats support post-install scripts.

bdist_egg doesn't support a post-install mechanism by design:

http://bugs.python.org/setuptools/issue41