Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Cake equivalent for Python?

I've raked through a lot of "make for Python" projects, but I can't find any with the simplicity of a cake file. What I'm looking for is a Python equivalent that will let me:

  1. Keep the build commands in a single file in my project root
  2. Define each task as a simple function with a description that will automatically be displayed when the "make" file is run without arguments
  3. Import my Python modules

I'm picturing something like this:

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()

I've searched and searched but found nothing like it. If it doesn't exist, I will make it myself and probably answer this question with it.

Thanks for your help!

like image 596
Hubro Avatar asked Jul 18 '12 09:07

Hubro


3 Answers

It’s not that hard to build a simple solution yourself:

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]]()

And then a small sample:

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()

And what it looks like when used:

> .\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!
like image 87
poke Avatar answered Oct 05 '22 22:10

poke


Have you looked into using fabric?

To implement your example using it, you'd just need to add this to a file named 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()

Then you just need to run fab build to build. And you can run fab -l to see the avaliable commands along with their descriptions.

Guess it's also worth mentioning that fabric provides some other functionality that you may (or may not) find useful. Amongst other things it's got some functions to help with deploying files to remote servers and some others that allow you to run remote commands through ssh. Since it looks like you're developing a web-based project you may find this useful for creating deployment scripts or similar.

like image 44
obmarg Avatar answered Oct 06 '22 00:10

obmarg


Funny, there's a Python build tool called Cake that uses nearly the same syntax as you example. See it here.

like image 23
weddingcakes Avatar answered Oct 05 '22 22:10

weddingcakes