blob: a4f8d36095718514ff0c4547d1639eb8663b1a9e [file] [log] [blame]
Shawn O. Pearce27b07322009-04-10 16:02:48 -07001#
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
16import sys
17from color import Coloring
18from command import Command
19
20class BranchColoring(Coloring):
21 def __init__(self, config):
22 Coloring.__init__(self, config, 'branch')
23 self.current = self.printer('current', fg='green')
24 self.local = self.printer('local')
25 self.notinproject = self.printer('notinproject', fg='red')
26
27class BranchInfo(object):
28 def __init__(self, name):
29 self.name = name
30 self.current = 0
31 self.published = 0
32 self.published_equal = 0
33 self.projects = []
34
35 def add(self, b):
36 if b.current:
37 self.current += 1
38 if b.published:
39 self.published += 1
40 if b.revision == b.published:
41 self.published_equal += 1
42 self.projects.append(b)
43
44 @property
45 def IsCurrent(self):
46 return self.current > 0
47
48 @property
49 def IsPublished(self):
50 return self.published > 0
51
52 @property
53 def IsPublishedEqual(self):
54 return self.published_equal == len(self.projects)
55
56
57class Branches(Command):
58 common = True
59 helpSummary = "View current topic branches"
60 helpUsage = """
61%prog [<project>...]
62
63Summarizes the currently available topic branches.
Shawn O. Pearce7da73d62009-06-12 17:35:43 -070064
65Branch Display
66--------------
67
68The branch display output by this command is organized into four
69columns of information; for example:
70
71 *P nocolor | in repo
72 repo2 |
73
74The first column contains a * if the branch is the currently
75checked out branch in any of the specified projects, or a blank
76if no project has the branch checked out.
77
78The second column contains either blank, p or P, depending upon
79the upload status of the branch.
80
81 (blank): branch not yet published by repo upload
82 P: all commits were published by repo upload
83 p: only some commits were published by repo upload
84
85The third column contains the branch name.
86
87The fourth column (after the | separator) lists the projects that
88the branch appears in, or does not appear in. If no project list
89is shown, then the branch appears in all projects.
90
Shawn O. Pearce27b07322009-04-10 16:02:48 -070091"""
92
Shawn O. Pearce27b07322009-04-10 16:02:48 -070093 def Execute(self, opt, args):
94 projects = self.GetProjects(args)
95 out = BranchColoring(self.manifest.manifestProject.config)
96 all = {}
97 project_cnt = len(projects)
98
99 for project in projects:
100 for name, b in project.GetBranches().iteritems():
101 b.project = project
102 if name not in all:
103 all[name] = BranchInfo(name)
104 all[name].add(b)
105
106 names = all.keys()
107 names.sort()
108
Shawn O. Pearce4e3d6732009-04-18 15:18:35 -0700109 if not names:
110 print >>sys.stderr, ' (no branches)'
111 return
112
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700113 width = 25
114 for name in names:
115 if width < len(name):
116 width = len(name)
117
118 for name in names:
119 i = all[name]
120 in_cnt = len(i.projects)
121
122 if i.IsCurrent:
123 current = '*'
124 hdr = out.current
125 else:
126 current = ' '
127 hdr = out.local
128
129 if i.IsPublishedEqual:
130 published = 'P'
131 elif i.IsPublished:
132 published = 'p'
133 else:
134 published = ' '
135
136 hdr('%c%c %-*s' % (current, published, width, name))
137 out.write(' |')
138
Pär Åsfältff6929d2009-09-05 23:10:56 +0200139 if in_cnt < project_cnt:
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700140 fmt = out.write
141 paths = []
142 if in_cnt < project_cnt - in_cnt:
143 type = 'in'
144 for b in i.projects:
145 paths.append(b.project.relpath)
146 else:
147 fmt = out.notinproject
148 type = 'not in'
149 have = set()
150 for b in i.projects:
151 have.add(b.project)
152 for p in projects:
Pär Åsfältff6929d2009-09-05 23:10:56 +0200153 if not p in have:
154 paths.append(p.relpath)
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700155
156 s = ' %s %s' % (type, ', '.join(paths))
157 if width + 7 + len(s) < 80:
158 fmt(s)
159 else:
Pär Åsfältff6929d2009-09-05 23:10:56 +0200160 fmt(' %s:' % type)
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700161 for p in paths:
162 out.nl()
Pär Åsfältff6929d2009-09-05 23:10:56 +0200163 fmt(width*' ' + ' %s' % p)
164 else:
165 out.write(' in all projects')
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700166 out.nl()