2009-11-10 12 views
22

Tengo una biblioteca llamada "ejemplo" que estoy instalando en mi directorio global de paquetes de sitio. Sin embargo, me gustaría poder instalar dos versiones, una para producción y otra para prueba (tengo una aplicación web y otras cosas que están versionadas de esta manera).Comandos de distutils personalizados

¿Hay alguna manera de especificar, por ejemplo "python setup.py stage", que no solo instalará un huevo diferente en site-packages, sino que también cambiará el nombre de "example" a "example_stage" o algo similar?

Si distutils no puede hacer esto, ¿hay alguna otra herramienta que pueda?

Respuesta

13

Claro, puede extender distutils con nuevos comandos. En el archivo de configuración distutil, añadir:

[global] 
command-packages=foo.bar 

esto puede ser en distutils.cfg en el paquete distutils sí, ..pydistutils.cfg en su directorio personal (sin líder punto en Windows), o setup.cfg en el directorio actual.

Luego necesita un paquete foo.bar en el directorio de paquetes de sitio de Python.

Entonces en ese paquete se agrega la clases que implementan nuevos comandos deseados, tales como stage, la subclasificación distutils.cmd - los documentos son débiles, pero hay un montón de ejemplos ya que todos los comandos existentes distutils también se construyen de esa manera.

+2

Responde a la pregunta, pero virtualenv es una mejor respuesta al problema. –

3

Consulte Alex's answer si quiere una forma de hacer esto con distutils, pero creo que Paver es mejor para este tipo de cosas. Hace que sea mucho más fácil hacer comandos personalizados o anular los existentes. Además, la transición no es terriblemente difícil si estás acostumbrado a distutils o setuptools.

+0

Paver ofrece muchas funcionalidades útiles y atajos. Por otro lado, agrega otro paradigma (y arquitectura) además de distutils. Preferiría un archivo simple setup.py que sea autónomo y haga todo lo que se necesita hacer. –

49

Esto se puede hacer fácilmente con distutils mediante la subclasificación de distutils.core.Command dentro de setup.py.

Por ejemplo:

from distutils.core import setup, Command 
import os, sys 

class CleanCommand(Command): 
    description = "custom clean command that forcefully removes dist/build directories" 
    user_options = [] 
    def initialize_options(self): 
     self.cwd = None 
    def finalize_options(self): 
     self.cwd = os.getcwd() 
    def run(self): 
     assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd 
     os.system('rm -rf ./build ./dist') 

Para habilitar el comando que hay que hacer referencia a ella en la configuración():

setup(
    # stuff omitted for conciseness. 
    cmdclass={ 
     'clean': CleanCommand 
} 

Tenga en cuenta que puede anular comandos integrados de esta manera también, como lo Lo hice con 'limpio'. (No me gusta la forma en la versión incorporada dejado atrás el 'dist' y directorios 'construir'.)

% python setup.py --help-commands | grep clean 
    clean   custom clean command that forcefully removes dist/build dirs. 

Hay una serie de convenciones que se utilizan:

  • Se especifica cualquier argumento de la línea de comandos con user_options.
  • Declara cualquier variable que usaría con el método initialize_options(), que se invoca después de la inicialización para configurar su espacio de nombres personalizado para la subclase.
  • El método finalize_options() se llama justo antes de ejecutar().
  • Las agallas del comando se producirán en run(), así que asegúrese de hacer cualquier otro trabajo de preparación antes de eso.

El mejor ejemplo de uso es sólo para mirar el código fuente de una de las órdenes por defecto encontrado en PYTHON_DIR/distutils/comando como install.py o build.py.

+0

Utilice [las fuentes] (https://bitbucket.org/pypy/pypy/src/9d88b4875d6e12570a635848524bb7f5283ee558/lib-python/2.7/distutils/command?at=translation-cleanup), Luke. –

+0

Y [lea los documentos] (https://docs.python.org/2/distutils/apiref.html#creating-a-new-distutils-command). –

Cuestiones relacionadas