branches.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. Branch Display
  55. --------------
  56. The branch display output by this command is organized into four
  57. columns of information; for example:
  58. *P nocolor | in repo
  59. repo2 |
  60. The first column contains a * if the branch is the currently
  61. checked out branch in any of the specified projects, or a blank
  62. if no project has the branch checked out.
  63. The second column contains either blank, p or P, depending upon
  64. the upload status of the branch.
  65. (blank): branch not yet published by repo upload
  66. P: all commits were published by repo upload
  67. p: only some commits were published by repo upload
  68. The third column contains the branch name.
  69. The fourth column (after the | separator) lists the projects that
  70. the branch appears in, or does not appear in. If no project list
  71. is shown, then the branch appears in all projects.
  72. """
  73. def Execute(self, opt, args):
  74. projects = self.GetProjects(args)
  75. out = BranchColoring(self.manifest.manifestProject.config)
  76. all_branches = {}
  77. project_cnt = len(projects)
  78. for project in projects:
  79. for name, b in project.GetBranches().iteritems():
  80. b.project = project
  81. if name not in all_branches:
  82. all_branches[name] = BranchInfo(name)
  83. all_branches[name].add(b)
  84. names = all_branches.keys()
  85. names.sort()
  86. if not names:
  87. print >>sys.stderr, ' (no branches)'
  88. return
  89. width = 25
  90. for name in names:
  91. if width < len(name):
  92. width = len(name)
  93. for name in names:
  94. i = all_branches[name]
  95. in_cnt = len(i.projects)
  96. if i.IsCurrent:
  97. current = '*'
  98. hdr = out.current
  99. else:
  100. current = ' '
  101. hdr = out.local
  102. if i.IsPublishedEqual:
  103. published = 'P'
  104. elif i.IsPublished:
  105. published = 'p'
  106. else:
  107. published = ' '
  108. hdr('%c%c %-*s' % (current, published, width, name))
  109. out.write(' |')
  110. if in_cnt < project_cnt:
  111. fmt = out.write
  112. paths = []
  113. if in_cnt < project_cnt - in_cnt:
  114. in_type = 'in'
  115. for b in i.projects:
  116. paths.append(b.project.relpath)
  117. else:
  118. fmt = out.notinproject
  119. in_type = 'not in'
  120. have = set()
  121. for b in i.projects:
  122. have.add(b.project)
  123. for p in projects:
  124. if not p in have:
  125. paths.append(p.relpath)
  126. s = ' %s %s' % (in_type, ', '.join(paths))
  127. if width + 7 + len(s) < 80:
  128. fmt(s)
  129. else:
  130. fmt(' %s:' % in_type)
  131. for p in paths:
  132. out.nl()
  133. fmt(width*' ' + ' %s' % p)
  134. else:
  135. out.write(' in all projects')
  136. out.nl()