2010-07-24 8 views
9

Supongamos que tenemos un programa llamado foo.¿Cómo manejar los archivos de configuración con distutils para respetar la FHS de Unixen?

Si el uso ruta absoluta:

setup(..., 
     data_files=[..., 
       ('/etc', ['foo.cfg'])] 
) 

Entonces foo$ python setup.py --prefix=/usr/local y tendremos /etc/foo.cfg. Pero deberíamos tener /usr/local/etc/foo.cfg en lugar de acuerdo con FHS.

¿Qué pasa si utilizamos una ruta relativa?

setup(..., 
     data_files=[..., 
       ('etc', ['foo.cfg'])] 
) 

Entonces, si usamos la ruta de instalación predeterminada, es decir, instalar en/usr, tendremos /usr/etc/foo.cfg. Mala suerte de nuevo.

Entonces, ¿cómo hacerlo bien?

P.S. Para evitar que el problema sea más complicado, suponemos que este programa foo no se puede ejecutar en un entorno que no sea unix.

Respuesta

5

Sub-clasificando distutils.command.install.install no es estrictamente necesario. En cambio, data_files se puede pasar a setup, según la documentación distutils en 'Installing Additional Files'.

p. Ej.

setup(
    ... 
    data_files = [ 
     (conf_path, ['foo.cfg']) 
    ] 
) 

donde conf_path se calcula según sus propios requisitos. es decir, construirlo probando sys.prefix (en lugar de self.prefix), como @weakish hizo anteriormente.

5

Parece que no hay una manera fácil. El problema es que los archivos de configuración son archivos de datos especiales y merecen un tratamiento especial.

Por lo tanto, escribir nuestra propia clase:

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 

continuación:

setup(# blah blah blah 
    conf_files = ['foo.cfg'] 
    cmdclass = {'install': myinstall, 
     # blah blah blah 
    } 
) 
Cuestiones relacionadas