doit apac-2010-1.0

47
doit - automation tool 1 doit – automation tool Bringing the power of build-tools to execute any kind of task Eduardo Schettino

Upload: eduardo-schettino

Post on 18-Dec-2014

1.023 views

Category:

Technology


2 download

DESCRIPTION

doit presentationpycon - asia pacific 2010 singapore(http://python-doit.sourceforge.net/)

TRANSCRIPT

Page 1: Doit apac-2010-1.0

doit - automation tool 1

doit – automation tool

Bringing the power of build-tools to execute any kind of task

Eduardo Schettino

Page 2: Doit apac-2010-1.0

doit - automation tool 2

About me

Brazil Beijing – China Exoweb http://www.exoweb.net

Page 3: Doit apac-2010-1.0

doit - automation tool 3

Talk overview

build-tools (make) Who needs a build-tool? doit Questions & Answers

Page 4: Doit apac-2010-1.0

doit - automation tool 4

build-tools

manage repetitive tasks and their dependencies speed-up development (faster turn-around) 1977: Make (C & other compiled languages)

Anything worth repeating is worth automating

Page 5: Doit apac-2010-1.0

doit - automation tool 5

make model

RulesPrerequisite 1

Prerequisite 2 Commands

Prerequisite N

...

Targets

Page 6: Doit apac-2010-1.0

doit - automation tool 6

C project

defs.h

bar.c

foo.c

compile

compile bar.o

foo.o

link foobar

Page 7: Doit apac-2010-1.0

doit - automation tool 7

1 - compile foo

defs.h

bar.c

foo.c

compile

compile bar.o

foo.o

link foobar

Page 8: Doit apac-2010-1.0

doit - automation tool 8

2 - compile bar

defs.h

bar.c

foo.c

compile

compile bar.o

foo.o

link foobar

Page 9: Doit apac-2010-1.0

doit - automation tool 9

3 - foobar

defs.h

bar.c

foo.c

compile

compile bar.o

foo.o

link foobar

Page 10: Doit apac-2010-1.0

doit - automation tool 10

initial build

defs.h

bar.c

foo.c

compile

compile bar.o

foo.o

link foobar

All 3 operations executed

Page 11: Doit apac-2010-1.0

doit - automation tool 11

no-op rebuild

defs.h

bar.c

foo.c

compile

compile bar.o

foo.o

link foobar

No changes. No operation executed

Page 12: Doit apac-2010-1.0

doit - automation tool 12

incremental rebuild

defs.h

bar.c

foo.c

compile

compile bar.o

foo.o

link foobar

foo.c changed. 2 operations executed

Page 13: Doit apac-2010-1.0

doit - automation tool 13

how it works?

file time-stamp comparison if any of the prerequisite files were modified

after last modification on target => re-execute if target is up-to-date => skip execution

Page 14: Doit apac-2010-1.0

doit - automation tool 14

who needs a build-tool?

dynamic language => no compilation => static checkers + unit-tests

functional tests (DB + web) are slow maintenance tasks

Page 15: Doit apac-2010-1.0

doit - automation tool 15

python project

main.py

bar.py

foo.py unit-test

unit-test

unit-test

Page 16: Doit apac-2010-1.0

doit - automation tool 16

first run

main.py

bar.py

foo.py unit-test

unit-test

unit-test

Page 17: Doit apac-2010-1.0

doit - automation tool 17

no-op run???

main.py

bar.py

foo.py unit-test

unit-test

unit-test

no modifications on source code all tests are executed again! no targets to compare time-stamps...

Page 18: Doit apac-2010-1.0

doit - automation tool 18

make problems

ad-hoc language (hard to use, debug, ...) time-stamp based (fragile) restricted to operations that create files not good on dynamic creation of rules

Page 19: Doit apac-2010-1.0

doit - automation tool 19

doit goals

more flexible model than traditional build-tools “real” language => python get out of your way

Page 20: Doit apac-2010-1.0

doit - automation tool 20

doit model

based on “Tasks”, focus on “actions”

Tasksdependency 1

dependency 2 Actions

dependency N

...

Targets

Page 21: Doit apac-2010-1.0

doit - automation tool 21

how it works?

same principle but... use a “db” file to save info from successful

execution tasks are defined on a “dodo” file, a plain

python module i.e. does not require targets to check if task is

up-to-date

Page 22: Doit apac-2010-1.0

doit - automation tool 22

Hello World

def task_hello():

    return {'actions':        ['echo Hello World > hello.txt']}

Page 23: Doit apac-2010-1.0

doit - automation tool 23

Hello World

def task_hello():

    return {'actions':         ['echo Hello World > hello.txt']}

A task generator ...

Page 24: Doit apac-2010-1.0

doit - automation tool 24

Hello World

def task_hello():

    return {'actions':         ['echo Hello World > hello.txt']}

A task generator ...

... returns a dictionary with task meta-data

Page 25: Doit apac-2010-1.0

doit - automation tool 25

Hello World

def task_hello():

    return {'actions':         ['echo Hello World > hello.txt']}

A task generator ...

... returns a dictionary with task meta-data

strings are shell commands

Page 26: Doit apac-2010-1.0

doit - automation tool 26

python actions

def pyhello():    with open('hello.txt', 'w') as hello_file:        hello_file.write("Hello Python\n")

def task_hello():    return {'actions': [(pyhello,)]}

a plain python function

Page 27: Doit apac-2010-1.0

doit - automation tool 27

python actions

def pyhello():    with open('hello.txt', 'w') as hello_file:        hello_file.write("Hello Python\n")

def task_hello():    return {'actions': [(pyhello,)]}

a plain python function

tuple (callable, args, kwargs)

Page 28: Doit apac-2010-1.0

doit - automation tool 28

compile

def task_compile():    return {'actions': ["cc ­c main.c"],            'file_dep': ["main.c","defs.h"],            'targets': ["main.o"]            }

dependencies targets

Page 29: Doit apac-2010-1.0

doit - automation tool 29

sub-tasks

def task_create_file():    for i in range(3):        filename = "file%d.txt" % i

        yield {'name': filename,               'actions':                  ["touch %s" % filename]}

define task meta-data

Page 30: Doit apac-2010-1.0

doit - automation tool 30

sub-tasks

def task_create_file():    for i in range(3):        filename = "file%d.txt" % i

        yield {'name': filename,               'actions':                  ["touch %s" % filename]}

“yield” to create multiple tasks

define task meta-data

Page 31: Doit apac-2010-1.0

doit - automation tool 31

sub-tasks

def task_create_file():    for i in range(3):        filename = "file%d.txt" % i

        yield {'name': filename,               'actions':                  ["touch %s" % filename]}

“yield” to create multiple tasks

define task meta-data

required for sub-tasks

Page 32: Doit apac-2010-1.0

doit - automation tool 32

sub-tasks

def task_create_file():    for i in range(3):        filename = "file%d.txt" % i

        yield {'name': filename,               'actions':                  ["touch %s" % filename]}

“yield” to create multiple tasks

define task meta-data

required for sub-tasks

Page 33: Doit apac-2010-1.0

doit - automation tool 33

task dependency

def task_foo():    return {'actions': ["echo foo"]}def task_bar():    return {'actions': ["echo bar"]}

def task_mygroup():    return {'actions': None,            'task_dep': ['foo', 'bar']}

tasks that must be executed before this task

Page 34: Doit apac-2010-1.0

doit - automation tool 34

result dependency

def task_which_version():return {'actions': 

 ['bzr version­info ­­custom –template="{revno}\n"']}

def task_do_something():return {'actions': ['echo "TODO: send an email"'],        'result_dep': ['which_version']}

check result from another task instead of a file content

Page 35: Doit apac-2010-1.0

doit - automation tool 35

result dependency

def task_which_version():return {'actions': 

 ['bzr version­info ­­custom –template="{revno}\n"']}

def task_do_something():return {'actions': ['echo "TODO: send an email"'],        'result_dep': ['which_version']}

check result from another task instead of a file content

task “result” is string returned by action

Page 36: Doit apac-2010-1.0

doit - automation tool 36

execution

by default all tasks are executed controlled by DOIT_CONFIG default_tasks

DOIT_CONFIG = {'default_tasks': ['t3']}

$ doit.  task3$ doit task2 task1:foo.  task2.  task1:foo

Page 37: Doit apac-2010-1.0

doit - automation tool 37

up-to-date ?

no file dependencies were modified no result dependencies were modified all targets exist compares => timestamp, size, checksum

Page 38: Doit apac-2010-1.0

doit - automation tool 38

up-to-date output

$ doit.  compile

$ doit­­ compile

$ rm main.o$ doit.  compile

. (dot) => executed

-- (dashes) => skipped

Page 39: Doit apac-2010-1.0

doit - automation tool 39

environment setup

def task_start_server():    for name in ('serverX', 'serverY'):        yield {'name': name,               'actions': [(start, (name,))],               'teardown': [(stop, (name,))],               }

def task_test_A():    return {'actions':['echo fun_test_a'],            'setup': ['start_server:serverX'],           }

test_A requires serverX to be runningstart serverX only if test_A not up-to-date

Page 40: Doit apac-2010-1.0

doit - automation tool 40

environment setup

def task_start_server():    for name in ('serverX', 'serverY'):        yield {'name': name,               'actions': [(start, (name,))],               'teardown': [(stop, (name,))],               }

def task_test_A():    return {'actions':['echo fun_test_a'],            'setup': ['start_server:serverX'],           }

test_A requires serverX to be runningstart serverX only if test_A not up-to-date

stop serverX after all tasks finish running

Page 41: Doit apac-2010-1.0

doit - automation tool 41

calculated dependency

def task_mod_deps():    return {'actions': [(print_deps,)],            'calc_dep': ["get_dep"],           }

def get_dep(mod):    return {'file_dep': [‘a’, ‘b’, ‘c’]}def task_get_dep():    return {'actions':[(get_dep,)]}

dependencies are calculated on another task

Page 42: Doit apac-2010-1.0

doit - automation tool 42

calculated dependency

def task_mod_deps():    return {'actions': [(print_deps,)],            'calc_dep': ["get_dep"],           }

def get_dep(mod):    return {'file_dep': [‘a’, ‘b’, ‘c’]}def task_get_dep():    return {'actions':[(get_dep,)]}

dependencies are calculated on another task

returns dictionary with same keys as task-dict (file_dep, task_dep, result_dep, calc_dep)

Page 43: Doit apac-2010-1.0

doit - automation tool 43

other task features

clean => clean actions ($doit clean <tasks>) doc => ($doit list) params => get parameters from command line getargs => get values computed in different

tasks

Page 44: Doit apac-2010-1.0

doit - automation tool 44

other runner features

verbosity => capture/display stdout/stderr title => controls output (task name) custom_reporters => complete output control use wildcard to select tasks

Page 45: Doit apac-2010-1.0

doit - automation tool 45

parallel execution

parallel execution of tasks in multiple processes uses multiprocessing lib subject to same limitations...

Page 46: Doit apac-2010-1.0

doit - automation tool 46

auto execution

long running process watches for file modifications and automatically

re-execute outdated tasks works on linux and mac TDD, never leave the editor screen :)

Page 47: Doit apac-2010-1.0

doit - automation tool 47

thanks

Questions ?

website: http://python-doit.sourceforge.net