2011-11-09 18 views
12

Dato il seguente (dimostrazione) layout del progetto:creare diversi tipi di distribuzione con setup.py

MyProject/ 
    README 
    LICENSE 
    setup.py 
    myproject/ 
     ... # packages 
    extrastuff/ 
     ... # some extra data 

Come (e dove) posso dichiaro diversi tipi di distribuzione? Soprattutto ho bisogno di queste due opzioni:

  1. Una distribuzione che contiene solo la fonte

  2. Una distribuzione che contiene il tutti i file di dati sotto (extrastuff)

Idealmente sorgente e, come faccio dichiarare la configurazione superiore due mentre la seconda dipende dalla prima?

+1

Perché non creare diversi file 'setup.py'? La distribuzione di origine è disponibile come 'sdist'. –

+0

@Brian: sono a conoscenza di 'sdist', grazie. Sono un manutentore di un progetto open source di medie dimensioni e mi piacerebbe aderire a convenzioni comuni (come avere un 'setup.py' che gestisce l'imballaggio/l'installazione). Voglio davvero vedere una soluzione che utilizza solo uno script di installazione. – Constantinius

+0

Non posso fornire dettagli perché non ho mai avuto questo tipo di problema. Un approccio potrebbe fornire il proprio comando 'sdist' che chiama semplicemente' sdist' con diversi metadati che dipendono dalla distribuzione di destinazione. La distribuzione può essere fornita come opzione dalla riga di comando o usando 'platform.linux_distribution' per ottenere la stessa distribuzione di destinazione di quella nella macchina che chiama' setup.py' di default. – jcollado

risposta

11

Ho implementato qualcosa di simile prima ... il comando sdist può essere esteso per gestire ulteriori argomenti della riga di comando e per manipolare i file di dati in base a questi. Se esegui python setup.py sdist --help, includerà gli argomenti della riga di comando personalizzati nella guida, che è piacevole. Utilizzare la seguente ricetta:

from distutils import log 
from distutils.core import setup 
from distutils.command.sdist import sdist 

class CustomSdist(sdist): 

    user_options = [ 
     ('packaging=', None, "Some option to indicate what should be packaged") 
    ] + sdist.user_options 

    def __init__(self, *args, **kwargs): 
     sdist.__init__(self, *args, **kwargs) 

     self.packaging = "default value for this option" 

    def get_file_list(self): 

     log.info("Chosen packaging option: {self.packaging}".format(self=self)) 

     # Change the data_files list here based on the packaging option 
     self.distribution.data_files = list(
      ('folder', ['file1', 'file2']) 
     ) 
     sdist.get_file_list(self) 

if __name__ == "__main__": 

    setup(
     name = "name", 
     version = "version", 
     author = "author", 
     author_email = "author_email", 
     url = "url", 
     py_modules = [ 
      # ... 
     ], 
     packages = [ 
      # ... 
     ], 
#  data_files = default data files for commands other than sdist if you wish 
     cmdclass={ 
      'sdist': CustomSdist 
     } 
    ) 
+0

Grazie mille per questa soluzione, penso che andrò per quello. – Constantinius

3

È possibile estendere setup.py per includere anche l'analisi della riga di comando personalizzata. È quindi possibile prendere un argomento personalizzato e spogliarlo in modo che non abbia effetto su setuptools.

È possibile accedere all'argomento della riga di comando in sys.argv. Per quanto riguarda la modifica della chiamata a setuptools.setup(), vi consiglio di creare un dizionario di argomenti da passare, modificando il dizionario in base agli argomenti della riga di comando, e quindi chiamando setup() utilizzando la notazione **dict, in questo modo:

from setuptools import setup 
import sys 

basic = {'name': 'my program'} 
extra = {'bonus': 'content'} 

if '--extras' in sys.argv: 
    basic.update(extra) 
    sys.argv.remove('--extras') 

setup(**basic) 

Per più approfondita L'analisi della riga di comando potrebbe anche utilizzare getopt module o il più recente argparse module se si sta mirando solo a Python 2.7 e versioni successive.

EDIT: Ho trovato anche una sezione nella documentazione di distutils dal titolo Creating a new Distutils command. Potrebbe anche essere una risorsa utile.

+1

Ho scoperto che il comando 'sdist' (da distutils) si lamenta degli argomenti della riga di comando sconosciuti se provi questo genere di cose. – wutz

+0

Ho appena provato questo usando il file setup.py del progetto feedparser usando l'opzione '--extras' per cambiare il nome del progetto (e di conseguenza il nome file di output). Ha funzionato senza errori. Hai provato a modificare 'sys.argv' prima di chiamare la funzione' setup() '? –

+0

Questa è una soluzione semplice e carina, quindi +1 per quello. Penso che Wutz abbia menzionato prima, che sia possibile creare comandi personalizzati di distutils. Grazie comunque! – Constantinius