branches.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #
  2. # Copyright (C) 2009 The Android Open Source Project
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import sys
  16. from color import Coloring
  17. from command import Command
  18. class BranchColoring(Coloring):
  19. def __init__(self, config):
  20. Coloring.__init__(self, config, 'branch')
  21. self.current = self.printer('current', fg='green')
  22. self.local = self.printer('local')
  23. self.notinproject = self.printer('notinproject', fg='red')
  24. class BranchInfo(object):
  25. def __init__(self, name):
  26. self.name = name
  27. self.current = 0
  28. self.published = 0
  29. self.published_equal = 0
  30. self.projects = []
  31. def add(self, b):
  32. if b.current:
  33. self.current += 1
  34. if b.published:
  35. self.published += 1
  36. if b.revision == b.published:
  37. self.published_equal += 1
  38. self.projects.append(b)
  39. @property
  40. def IsCurrent(self):
  41. return self.current > 0
  42. @property
  43. def IsPublished(self):
  44. return self.published > 0
  45. @property
  46. def IsPublishedEqual(self):
  47. return self.published_equal == len(self.projects)
  48. class Branches(Command):
  49. common = True
  50. helpSummary = "View current topic branches"
  51. helpUsage = """
  52. %prog [<project>...]
  53. Summarizes the currently available topic branches.
  54. """
  55. def _Options(self, p):
  56. p.add_option('-a', '--all',
  57. dest='all', action='store_true',
  58. help='show all branches, not just the majority')
  59. def Execute(self, opt, args):
  60. projects = self.GetProjects(args)
  61. out = BranchColoring(self.manifest.manifestProject.config)
  62. all = {}
  63. project_cnt = len(projects)
  64. for project in projects:
  65. for name, b in project.GetBranches().iteritems():
  66. b.project = project
  67. if name not in all:
  68. all[name] = BranchInfo(name)
  69. all[name].add(b)
  70. names = all.keys()
  71. names.sort()
  72. if not opt.all and not args:
  73. # No -a and no specific projects listed; try to filter the
  74. # results down to only the majority of projects.
  75. #
  76. n = []
  77. for name in names:
  78. i = all[name]
  79. if i.IsCurrent \
  80. or 80 <= (100 * len(i.projects)) / project_cnt:
  81. n.append(name)
  82. names = n
  83. if not names:
  84. print >>sys.stderr, ' (no branches)'
  85. return
  86. width = 25
  87. for name in names:
  88. if width < len(name):
  89. width = len(name)
  90. for name in names:
  91. i = all[name]
  92. in_cnt = len(i.projects)
  93. if i.IsCurrent:
  94. current = '*'
  95. hdr = out.current
  96. else:
  97. current = ' '
  98. hdr = out.local
  99. if i.IsPublishedEqual:
  100. published = 'P'
  101. elif i.IsPublished:
  102. published = 'p'
  103. else:
  104. published = ' '
  105. hdr('%c%c %-*s' % (current, published, width, name))
  106. out.write(' |')
  107. if in_cnt < project_cnt and (in_cnt == 1 or opt.all):
  108. fmt = out.write
  109. paths = []
  110. if in_cnt < project_cnt - in_cnt:
  111. type = 'in'
  112. for b in i.projects:
  113. paths.append(b.project.relpath)
  114. else:
  115. fmt = out.notinproject
  116. type = 'not in'
  117. have = set()
  118. for b in i.projects:
  119. have.add(b.project)
  120. for p in projects:
  121. paths.append(p.relpath)
  122. s = ' %s %s' % (type, ', '.join(paths))
  123. if width + 7 + len(s) < 80:
  124. fmt(s)
  125. else:
  126. out.nl()
  127. fmt(' %s:' % type)
  128. for p in paths:
  129. out.nl()
  130. fmt(' %s' % p)
  131. out.nl()