5 from subprocess
import *
7 success_target
= '<success_target>'
9 class LMException(Exception):
10 def __init__(self
, msg
, obj
):
11 self
.msg
, self
.obj
= msg
, obj
14 return "LMException: %s: %s"%(self
.msg
, self
.obj
)
16 def nil_action(env
, target
, deps
, all_deps
, log
):
20 def __init__(self
, target
=None, depends
=None, action
=None):
21 self
.target
, self
.depends
, self
.action
= target
, depends
, action
22 if type(self
.action
) == str: self
.action
= [self
.action
]
23 if type(self
.depends
) == str:
24 self
.depends
= [self
.depends
]
26 def get_deps(self
, target
):
29 def do(self
, lm
, target
, all_deps
, log
):
30 deps
= self
.get_deps(target
)
31 if self
._need
_update
(target
, deps
, all_deps
):
32 if callable(self
.action
):
33 self
.action(lm
, target
, deps
, all_deps
, log
)
34 elif type(self
.action
) == list:
35 lm
.sh(self
.action
, log
, target
=target
, deps
=deps
,all_deps
=all_deps
)
37 raise LMException("Wrong Action", self
.action
)
40 return "%s <= %s"%(self
.target
, self
.depends
)
43 def _need_update(target
, deps
, all_deps
):
44 if not os
.path
.exists(target
):
46 mtime
= os
.path
.getmtime(target
)
48 if not os
.path
.exists(dep
):
50 if os
.path
.getmtime(dep
) > mtime
:
54 class ExistFileRule(Rule
):
56 Rule
.__init
__(self
, action
=nil_action
)
58 def get_deps(self
, target
):
59 if os
.path
.exists(target
):
60 return [success_target
]
63 class StaticRule(Rule
):
64 def __init__(self
, target
, depends
=[success_target
], action
=nil_action
):
65 Rule
.__init
__(self
, target
, depends
, action
)
67 def get_deps(self
, target
):
68 if target
== self
.target
:
72 class RegexpRule(Rule
):
73 def __init__(self
, target
, depends
=[success_target
], action
=nil_action
):
74 Rule
.__init
__(self
, target
, depends
, action
)
76 def get_deps(self
, target
):
77 if not re
.match(self
.target
, target
):
79 return [re
.sub(self
.target
, dep
, target
) for dep
in self
.depends
]
82 def __init__(self
, name
='default', env
={}, rules
=[], log
=BlockStream()):
83 Env
.__init
__(self
, env
)
84 self
.name
, self
.env
, self
.rules
, self
.log
= name
, env
, rules
, log
85 self
.add(ExistFileRule())
87 def add(self
, *rules
):
88 self
.rules
.extend(list_(rules
))
90 def sh(self
, cmd_list
, log
, **args
):
91 cmd_list
= list_(cmd_list
)
92 env
= dict(self
, **args
)
93 expanded_cmd
= [sub(cmd
, env
) for cmd
in cmd_list
]
94 for item
in expanded_cmd
:
95 log
<< "LazyMan $ %s"% (item
,)
96 if self
.dry_run
: continue
97 err
= call(item
, shell
=True)
98 if err
: raise LMException("Task Fail", item
)
100 def do(self
, target
, log
=None):
101 if target
== success_target
:
103 if log
==None: log
=self
.log
106 rules
, all_deps
= self
._select
_rule
(target
)
107 if not rules
: raise LMException("No Rule", target
)
109 self
.do(dep
, log
.new())
111 rule
.do(self
, target
, all_deps
, log
)
113 def _select_rule(self
, target
):
114 rules_deps
= [(rule
,rule
.get_deps(target
)) for rule
in self
.rules
]
115 rules_deps
= [(rule
, deps
) for rule
, deps
in rules_deps
if deps
]
116 rules
= [rule
for rule
, dep
in rules_deps
]
117 deps
= [dep
for rule
, dep
in rules_deps
]
118 all_deps
= list_(deps
)
122 if deps_set
.issuperset(set([dep
])):
126 return rules
, new_deps
128 def do_task(self
, target
=['default']):
129 target
= list_(target
)
130 if not target
: target
= ["default"]
134 except LMException
,e
:
138 return "LazyMan: %s\nrules:\n%s\n"%(self
.name
, '\n'.join([str(rule
) for rule
in self
.rules
]))