1# Copyright 2013 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""A module for the Builder base class.""" 6 7import difflib 8 9import cr 10 11 12class Builder(cr.Action, cr.Plugin.Type): 13 """Base class for implementing builders. 14 15 Builder implementations must override the Build and Clean methods at a 16 minimum to build a target and clean up back to a pristine state respectively. 17 They can also override Rebuild if they are able to handle it in a more 18 efficient way that a Clean Build sequence. 19 They should override the GetTargets method to return the set of valid targets 20 the build system knows about, and override IsTarget if they can implement it 21 more efficiently than checking from presents in the result of GetTargets. 22 """ 23 24 SELECTOR_ARG = '--builder' 25 SELECTOR = 'CR_BUILDER' 26 SELECTOR_HELP = 'Sets the builder to use to update dependencies.' 27 28 @cr.Plugin.activemethod 29 def Build(self, targets, arguments): 30 raise NotImplementedError('Must be overridden.') 31 32 @cr.Plugin.activemethod 33 def Clean(self, targets, arguments): 34 """Clean temporary files built by a target.""" 35 raise NotImplementedError('Must be overridden.') 36 37 @cr.Plugin.activemethod 38 def Rebuild(self, targets, arguments): 39 """Make a target build even if it is up to date. 40 41 Default implementation is to do a Clean and Build sequence. 42 Do not call the base version if you implement a more efficient one. 43 """ 44 self.Clean(targets, []) 45 self.Build(targets, arguments) 46 47 @cr.Plugin.activemethod 48 def GetTargets(self): 49 """Gets the full set of targets supported by this builder. 50 51 Used in automatic target name transformations, and also in offering the 52 user choices. 53 """ 54 return [] 55 56 @cr.Plugin.activemethod 57 def IsTarget(self, target_name): 58 """Check if a target name is on the builder knows about.""" 59 return target_name in self.GetTargets() 60 61 @cr.Plugin.activemethod 62 def GuessTargets(self, target_name): 63 """Returns a list of closest matching targets for a named target.""" 64 return difflib.get_close_matches(target_name, self.GetTargets(), 10, 0.4) 65 66 67class SkipBuilder(Builder): 68 """The "skip" version of a Builder, causes the build step to be skipped.""" 69 70 @property 71 def priority(self): 72 return super(SkipBuilder, self).priority - 1 73 74 def Build(self, targets, arguments): 75 pass 76 77 def Clean(self, targets, arguments): 78 pass 79 80