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