def __new__(cls,targets,reqs,order_only=None,func=None,PHONY=False,shared=False): """selects and creates the appropriate rule class to use. All rule instances can also be used as decorators around build recipe functions (in this case leave func=None). targets - single target or sequence of targets reqs - single prerequisite or sequence of prerequisites order_only - single dependency or sequence of order only prerequisites func - the build function that should take one or no arguments. Will be passed this class instance when run in order to have access to its attributes. PHONY - a phony rule always runs irrespective of file modification times shared - shared rules run their build function a single time for all of their targets. targets and reqs may contain glob patterns (see fnmatch and glob modules). They may also contain the '%' wildcard for defining pattern rules (like make). """ targets = checkseq(targets) reqs = checkseq(reqs) order_only = checkseq(order_only) if shared: if not any(fpmatch.has_magic(target) for target in targets): targets = [fpmatch.strip_specials(target) for target in targets] if not any(fpmatch.has_magic(req) for req in itertools.chain(reqs,order_only)): reqs = [fpmatch.strip_specials(req) for req in reqs] newrule = ExplicitRule(targets,reqs,order_only,func,PHONY) else: newrule = ExplicitTargetRule(targets,reqs,order_only,func,PHONY) elif any(fpmatch.has_pattern(target) for target in targets): #in fact all targets should have a pattern wildcard but error checking will occur in class. newrule = PatternSharedRule(targets,reqs,order_only,func,PHONY) else: #wildcard targets newrule = WildSharedRule(targets,reqs,order_only,func,PHONY) else: if not any(fpmatch.has_magic(target) for target in targets): targets = [fpmatch.strip_specials(target) for target in targets] if not any(fpmatch.has_magic(req) for req in itertools.chain(reqs,order_only)): reqs = [fpmatch.strip_specials(req) for req in reqs] if len(targets)<=1: newrule = ExplicitRule(targets,reqs,order_only,func,PHONY) else: newrule = ManyRules(ExplicitRule(target,reqs,order_only,func,PHONY) for target in targets) #or maybe use WildRule?? else: if len(targets)<=1: newrule = ExplicitTargetRule(targets,reqs,order_only,func,PHONY) else: newrule = ManyRules(ExplicitTargetRule(target,reqs,order_only,func,PHONY) for target in targets) #or maybe use WildRule?? elif any(fpmatch.has_pattern(target) for target in targets): #in fact all targets should have a pattern wildcard but error checking will occur in class. newrule = PatternRule(targets,reqs,order_only,func,PHONY) else: #wildcard targets newrule = WildRule(targets,reqs,order_only,func,PHONY) return newrule
def __init__(self,targets,reqs,order_only=None,func=None,PHONY=False): """Note: All targets must have at least the same number of % wildcards as the prerequisite with the highest number of them.""" super(PatternRule,self).__init__(targets,reqs,order_only,func,PHONY) #Check parameters - PatternRules shouldn't have any entries in self.explicit_rules assert all(fpmatch.has_pattern(target) for target in self.targets) #counting number of % (excluding sets) numpat = fpmatch.count_patterns assert ( max([numpat(req) for req in self.allreqs]+[numpat(req) for req in self.order_only]) <= min(numpat(target) for target in self.targets) )