blob: 9709f7f04c3879d7a62839be8c997f953dac0094 [file] [log] [blame]
Mike Frysingerf6013762019-06-13 02:30:51 -04001# -*- coding:utf-8 -*-
Shawn O. Pearce27b07322009-04-10 16:02:48 -07002#
3# Copyright (C) 2009 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
Sarah Owenscecd1d82012-11-01 22:59:27 -070017from __future__ import print_function
Shawn O. Pearce27b07322009-04-10 16:02:48 -070018import sys
19from color import Coloring
20from command import Command
21
David Pursehouse819827a2020-02-12 15:20:19 +090022
Shawn O. Pearce27b07322009-04-10 16:02:48 -070023class BranchColoring(Coloring):
24 def __init__(self, config):
25 Coloring.__init__(self, config, 'branch')
26 self.current = self.printer('current', fg='green')
David Pursehouse54a4e602020-02-12 14:31:05 +090027 self.local = self.printer('local')
Shawn O. Pearce27b07322009-04-10 16:02:48 -070028 self.notinproject = self.printer('notinproject', fg='red')
29
David Pursehouse819827a2020-02-12 15:20:19 +090030
Shawn O. Pearce27b07322009-04-10 16:02:48 -070031class BranchInfo(object):
32 def __init__(self, name):
33 self.name = name
34 self.current = 0
35 self.published = 0
36 self.published_equal = 0
37 self.projects = []
38
39 def add(self, b):
40 if b.current:
41 self.current += 1
42 if b.published:
43 self.published += 1
44 if b.revision == b.published:
45 self.published_equal += 1
46 self.projects.append(b)
47
48 @property
49 def IsCurrent(self):
50 return self.current > 0
51
52 @property
Etan Cohen588142d2014-07-09 21:33:31 -070053 def IsSplitCurrent(self):
54 return self.current != 0 and self.current != len(self.projects)
55
56 @property
Shawn O. Pearce27b07322009-04-10 16:02:48 -070057 def IsPublished(self):
58 return self.published > 0
59
60 @property
61 def IsPublishedEqual(self):
62 return self.published_equal == len(self.projects)
63
64
65class Branches(Command):
66 common = True
67 helpSummary = "View current topic branches"
68 helpUsage = """
69%prog [<project>...]
70
71Summarizes the currently available topic branches.
Shawn O. Pearce7da73d62009-06-12 17:35:43 -070072
Mike Frysingerb8f7bb02018-10-10 01:05:11 -040073# Branch Display
Shawn O. Pearce7da73d62009-06-12 17:35:43 -070074
75The branch display output by this command is organized into four
76columns of information; for example:
77
78 *P nocolor | in repo
79 repo2 |
80
81The first column contains a * if the branch is the currently
82checked out branch in any of the specified projects, or a blank
83if no project has the branch checked out.
84
85The second column contains either blank, p or P, depending upon
86the upload status of the branch.
87
88 (blank): branch not yet published by repo upload
89 P: all commits were published by repo upload
90 p: only some commits were published by repo upload
91
92The third column contains the branch name.
93
94The fourth column (after the | separator) lists the projects that
95the branch appears in, or does not appear in. If no project list
96is shown, then the branch appears in all projects.
97
Shawn O. Pearce27b07322009-04-10 16:02:48 -070098"""
99
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700100 def Execute(self, opt, args):
101 projects = self.GetProjects(args)
102 out = BranchColoring(self.manifest.manifestProject.config)
David Pursehouse5c6eeac2012-10-11 16:44:48 +0900103 all_branches = {}
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700104 project_cnt = len(projects)
105
106 for project in projects:
Chirayu Desai217ea7d2013-03-01 19:14:38 +0530107 for name, b in project.GetBranches().items():
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700108 b.project = project
David Pursehouse5c6eeac2012-10-11 16:44:48 +0900109 if name not in all_branches:
110 all_branches[name] = BranchInfo(name)
111 all_branches[name].add(b)
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700112
Chirayu Desai217ea7d2013-03-01 19:14:38 +0530113 names = list(sorted(all_branches))
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700114
Shawn O. Pearce4e3d6732009-04-18 15:18:35 -0700115 if not names:
Sarah Owenscecd1d82012-11-01 22:59:27 -0700116 print(' (no branches)', file=sys.stderr)
Shawn O. Pearce4e3d6732009-04-18 15:18:35 -0700117 return
118
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700119 width = 25
120 for name in names:
121 if width < len(name):
122 width = len(name)
123
124 for name in names:
David Pursehouse5c6eeac2012-10-11 16:44:48 +0900125 i = all_branches[name]
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700126 in_cnt = len(i.projects)
127
128 if i.IsCurrent:
129 current = '*'
130 hdr = out.current
131 else:
132 current = ' '
133 hdr = out.local
134
135 if i.IsPublishedEqual:
136 published = 'P'
137 elif i.IsPublished:
138 published = 'p'
139 else:
140 published = ' '
141
142 hdr('%c%c %-*s' % (current, published, width, name))
143 out.write(' |')
144
Pär Åsfältff6929d2009-09-05 23:10:56 +0200145 if in_cnt < project_cnt:
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700146 fmt = out.write
147 paths = []
Etan Cohen588142d2014-07-09 21:33:31 -0700148 non_cur_paths = []
149 if i.IsSplitCurrent or (in_cnt < project_cnt - in_cnt):
David Pursehouse8a68ff92012-09-24 12:15:13 +0900150 in_type = 'in'
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700151 for b in i.projects:
Etan Cohen588142d2014-07-09 21:33:31 -0700152 if not i.IsSplitCurrent or b.current:
153 paths.append(b.project.relpath)
154 else:
155 non_cur_paths.append(b.project.relpath)
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700156 else:
157 fmt = out.notinproject
David Pursehouse8a68ff92012-09-24 12:15:13 +0900158 in_type = 'not in'
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700159 have = set()
160 for b in i.projects:
161 have.add(b.project)
162 for p in projects:
David Pursehouseeeff3532020-02-12 11:24:10 +0900163 if p not in have:
Pär Åsfältff6929d2009-09-05 23:10:56 +0200164 paths.append(p.relpath)
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700165
David Pursehouse8a68ff92012-09-24 12:15:13 +0900166 s = ' %s %s' % (in_type, ', '.join(paths))
Etan Cohen588142d2014-07-09 21:33:31 -0700167 if not i.IsSplitCurrent and (width + 7 + len(s) < 80):
168 fmt = out.current if i.IsCurrent else fmt
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700169 fmt(s)
170 else:
David Pursehouse8a68ff92012-09-24 12:15:13 +0900171 fmt(' %s:' % in_type)
Etan Cohen588142d2014-07-09 21:33:31 -0700172 fmt = out.current if i.IsCurrent else out.write
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700173 for p in paths:
174 out.nl()
David Pursehouse54a4e602020-02-12 14:31:05 +0900175 fmt(width * ' ' + ' %s' % p)
Etan Cohen588142d2014-07-09 21:33:31 -0700176 fmt = out.write
177 for p in non_cur_paths:
178 out.nl()
David Pursehouse54a4e602020-02-12 14:31:05 +0900179 fmt(width * ' ' + ' %s' % p)
Pär Åsfältff6929d2009-09-05 23:10:56 +0200180 else:
181 out.write(' in all projects')
Shawn O. Pearce27b07322009-04-10 16:02:48 -0700182 out.nl()