2012-07-18 7 views
7

Ho attraversato un sacco di progetti "make for Python", ma non riesco a trovarli con la semplicità di uno cake file. Quello che sto cercando è un Python equivalente che mi permetta di:Esiste un equivalente Cake per Python?

  1. Mantenere i comandi di compilazione in un unico file nel mio progetto principale
  2. Definire ogni compito come una semplice funzione con una descrizione che sarà automaticamente visualizzato quando il file di "fare" viene eseguito senza argomenti
  3. importare i miei moduli Python

sto immaginando qualcosa di simile:

from pymake import task, main 

@task('reset_tables', 'Drop and recreate all MySQL tables') 
def reset_tables(): 
    # ... 

@task('build_stylus', 'Build the stylus files to public/css/*') 
def build_stylus(): 
    from myproject import stylus_builder 
    # ... 

@task('build_cscript', 'Build the coffee-script files to public/js/*') 
def build_cscript(): 
    # ... 

@task('build', 'Build everything buildable') 
def build(): 
    build_cscript() 
    build_stylus() 

# etc... 

# Function that parses command line args etc... 
main() 

Ho cercato e cercato ma non ho trovato nulla del genere. Se non esiste, lo farò da solo e probabilmente risponderò a questa domanda.

Grazie per il vostro aiuto!

+0

Vedere http://farmdev.com/thoughts/46/the-python-make-tool/; ci sono molte opzioni. –

+0

@MartijnPieters: Sì, ci sono molte opzioni di strumenti di make, ma sono tutte o morte o eccessivamente complicate e complesse. Non ho davvero bisogno di altro che l'esempio che ho fornito, e non ho ancora trovato uno strumento di compilazione per Python che abbia anche l'opzione di essere così semplice. – Hubro

+0

Non guardarmi poi; Io uso zc.buildout (ogni giorno) per tutte le mie attività di distribuzione.Probabilmente non è lo stesso caso d'uso di ciò che stai cercando. –

risposta

5

Non è così difficile costruire una soluzione semplice da soli:

import sys 

tasks = {} 
def task (f): 
    tasks[f.__name__] = f 
    return f 

def showHelp(): 
    print('Available tasks:') 
    for name, task in tasks.items(): 
     print(' {0}: {1}'.format(name, task.__doc__)) 

def main(): 
    if len(sys.argv) < 2 or sys.argv[1] not in tasks: 
     showHelp() 
     return 

    print('Executing task {0}.'.format(sys.argv[1])) 
    tasks[sys.argv[1]]() 

E poi un piccolo campione:

from pymake import task, main 

@task 
def print_foo(): 
    '''Prints foo''' 
    print('foo') 

@task 
def print_hello_world(): 
    '''Prints hello world''' 
    print('Hello World!') 

@task 
def print_both(): 
    '''Prints both''' 
    print_foo() 
    print_hello_world() 

if __name__ == '__main__': 
    main() 

E quello che sembra quando viene utilizzato:

 
> .\test.py 
Available tasks: 
    print_hello_world: Prints hello world 
    print_foo: Prints foo 
    print_both: Prints both 
> .\test.py print_hello_world 
Executing task print_hello_world. 
Hello World! 
+0

Mi riferivo alla parte del sottocomando di argparse. Avere un buon modo di usare i decoratori per definire i sottocomandi è ciò che avevo in mente. –

+0

+1 - Bella risposta, e ho già fatto una soluzione come questa per il mio progetto attuale :-) Mi stavo chiedendo se esistesse già una soluzione simile, presumibilmente con un po 'più di funzionalità, prima che mi fossi messo alla prova il mio in un pacchetto riutilizzabile. Un bel tocco con l'uso dei nomi delle funzioni e delle stringhe doc! – Hubro

+0

Sto dichiarando la risposta corretta. Questo perché la libreria * fabric * è in realtà piuttosto grande, non solo un piccolo strumento di creazione come stavo cercando – Hubro

4

Hai esaminato l'utilizzo di fabric?

Per attuare il tuo esempio di usarlo, si era appena necessario aggiungere questo in un file denominato fabfile.py:

def reset_tables(): 
    ''' Drop and recreate all MySQL tables ''' 
    # ... 

def build_stylus(): 
    ''' Build the stylus files to public/css/ ''' 
    from myproject import stylus_builder 
    # ... 

def build_cscript(): 
    ''' Build the coffee-script files to public/js/* ''' 
    # ... 

def build(): 
    ''' Build everything buildable ''' 
    build_cscript() 
    build_stylus() 

Poi basta eseguire fab build per costruire. Ed è possibile eseguire fab -l per visualizzare i comandi disponibili insieme alle relative descrizioni.

Indovinate che vale la pena menzionare che fabric fornisce alcune altre funzionalità che è possibile (o meno) trovare utili. Tra le altre cose ha alcune funzioni che aiutano nella distribuzione di file su server remoti e altre che consentono di eseguire comandi remoti tramite ssh. Dal momento che sembra che tu stia sviluppando un progetto basato sul web, potresti trovarlo utile per creare script di distribuzione o simili.

0

Vorrei creare un Makefile standard piuttosto che trovare qualcosa di specifico della lingua. In alcuni dei miei progetti, make db, make test, ecc., Si associano a script scritti in Python, ma potrebbero essere altrettanto facilmente in qualsiasi linguaggio i cui script siano eseguibili dalla riga di comando.

+0

Ho votato questa risposta * non utile * perché non affronta la preoccupazione numero 1 nella mia domanda: Mantenere tutte le Costruisci il codice in un file – Hubro

+0

Abbastanza corretto. Curioso sul motivo che ti spinge a volere un singolo file, ma se è una priorità, è una priorità. Il tessuto è davvero una buona opzione per una cosa del genere. – JoshMock

2

Divertente, c'è uno strumento di creazione Python chiamato Cake che utilizza quasi la stessa sintassi del tuo esempio. Vedi lo here.

+0

Wow, questo è ... incredibilmente confuso: S – Hubro