diff options
Diffstat (limited to 'subcmds/diffmanifests.py')
-rw-r--r-- | subcmds/diffmanifests.py | 374 |
1 files changed, 212 insertions, 162 deletions
diff --git a/subcmds/diffmanifests.py b/subcmds/diffmanifests.py index 4f9f5b0f..b446dbd8 100644 --- a/subcmds/diffmanifests.py +++ b/subcmds/diffmanifests.py | |||
@@ -18,24 +18,24 @@ from manifest_xml import RepoClient | |||
18 | 18 | ||
19 | 19 | ||
20 | class _Coloring(Coloring): | 20 | class _Coloring(Coloring): |
21 | def __init__(self, config): | 21 | def __init__(self, config): |
22 | Coloring.__init__(self, config, "status") | 22 | Coloring.__init__(self, config, "status") |
23 | 23 | ||
24 | 24 | ||
25 | class Diffmanifests(PagedCommand): | 25 | class Diffmanifests(PagedCommand): |
26 | """ A command to see logs in projects represented by manifests | 26 | """A command to see logs in projects represented by manifests |
27 | 27 | ||
28 | This is used to see deeper differences between manifests. Where a simple | 28 | This is used to see deeper differences between manifests. Where a simple |
29 | diff would only show a diff of sha1s for example, this command will display | 29 | diff would only show a diff of sha1s for example, this command will display |
30 | the logs of the project between both sha1s, allowing user to see diff at a | 30 | the logs of the project between both sha1s, allowing user to see diff at a |
31 | deeper level. | 31 | deeper level. |
32 | """ | 32 | """ |
33 | 33 | ||
34 | COMMON = True | 34 | COMMON = True |
35 | helpSummary = "Manifest diff utility" | 35 | helpSummary = "Manifest diff utility" |
36 | helpUsage = """%prog manifest1.xml [manifest2.xml] [options]""" | 36 | helpUsage = """%prog manifest1.xml [manifest2.xml] [options]""" |
37 | 37 | ||
38 | helpDescription = """ | 38 | helpDescription = """ |
39 | The %prog command shows differences between project revisions of manifest1 and | 39 | The %prog command shows differences between project revisions of manifest1 and |
40 | manifest2. if manifest2 is not specified, current manifest.xml will be used | 40 | manifest2. if manifest2 is not specified, current manifest.xml will be used |
41 | instead. Both absolute and relative paths may be used for manifests. Relative | 41 | instead. Both absolute and relative paths may be used for manifests. Relative |
@@ -65,159 +65,209 @@ synced and their revisions won't be found. | |||
65 | 65 | ||
66 | """ | 66 | """ |
67 | 67 | ||
68 | def _Options(self, p): | 68 | def _Options(self, p): |
69 | p.add_option('--raw', | 69 | p.add_option( |
70 | dest='raw', action='store_true', | 70 | "--raw", dest="raw", action="store_true", help="display raw diff" |
71 | help='display raw diff') | 71 | ) |
72 | p.add_option('--no-color', | 72 | p.add_option( |
73 | dest='color', action='store_false', default=True, | 73 | "--no-color", |
74 | help='does not display the diff in color') | 74 | dest="color", |
75 | p.add_option('--pretty-format', | 75 | action="store_false", |
76 | dest='pretty_format', action='store', | 76 | default=True, |
77 | metavar='<FORMAT>', | 77 | help="does not display the diff in color", |
78 | help='print the log using a custom git pretty format string') | 78 | ) |
79 | 79 | p.add_option( | |
80 | def _printRawDiff(self, diff, pretty_format=None, local=False): | 80 | "--pretty-format", |
81 | _RelPath = lambda p: p.RelPath(local=local) | 81 | dest="pretty_format", |
82 | for project in diff['added']: | 82 | action="store", |
83 | self.printText("A %s %s" % (_RelPath(project), project.revisionExpr)) | 83 | metavar="<FORMAT>", |
84 | self.out.nl() | 84 | help="print the log using a custom git pretty format string", |
85 | 85 | ) | |
86 | for project in diff['removed']: | 86 | |
87 | self.printText("R %s %s" % (_RelPath(project), project.revisionExpr)) | 87 | def _printRawDiff(self, diff, pretty_format=None, local=False): |
88 | self.out.nl() | 88 | _RelPath = lambda p: p.RelPath(local=local) |
89 | 89 | for project in diff["added"]: | |
90 | for project, otherProject in diff['changed']: | 90 | self.printText( |
91 | self.printText("C %s %s %s" % (_RelPath(project), project.revisionExpr, | 91 | "A %s %s" % (_RelPath(project), project.revisionExpr) |
92 | otherProject.revisionExpr)) | 92 | ) |
93 | self.out.nl() | ||
94 | self._printLogs(project, otherProject, raw=True, color=False, pretty_format=pretty_format) | ||
95 | |||
96 | for project, otherProject in diff['unreachable']: | ||
97 | self.printText("U %s %s %s" % (_RelPath(project), project.revisionExpr, | ||
98 | otherProject.revisionExpr)) | ||
99 | self.out.nl() | ||
100 | |||
101 | def _printDiff(self, diff, color=True, pretty_format=None, local=False): | ||
102 | _RelPath = lambda p: p.RelPath(local=local) | ||
103 | if diff['added']: | ||
104 | self.out.nl() | ||
105 | self.printText('added projects : \n') | ||
106 | self.out.nl() | ||
107 | for project in diff['added']: | ||
108 | self.printProject('\t%s' % (_RelPath(project))) | ||
109 | self.printText(' at revision ') | ||
110 | self.printRevision(project.revisionExpr) | ||
111 | self.out.nl() | ||
112 | |||
113 | if diff['removed']: | ||
114 | self.out.nl() | ||
115 | self.printText('removed projects : \n') | ||
116 | self.out.nl() | ||
117 | for project in diff['removed']: | ||
118 | self.printProject('\t%s' % (_RelPath(project))) | ||
119 | self.printText(' at revision ') | ||
120 | self.printRevision(project.revisionExpr) | ||
121 | self.out.nl() | ||
122 | |||
123 | if diff['missing']: | ||
124 | self.out.nl() | ||
125 | self.printText('missing projects : \n') | ||
126 | self.out.nl() | ||
127 | for project in diff['missing']: | ||
128 | self.printProject('\t%s' % (_RelPath(project))) | ||
129 | self.printText(' at revision ') | ||
130 | self.printRevision(project.revisionExpr) | ||
131 | self.out.nl() | ||
132 | |||
133 | if diff['changed']: | ||
134 | self.out.nl() | ||
135 | self.printText('changed projects : \n') | ||
136 | self.out.nl() | ||
137 | for project, otherProject in diff['changed']: | ||
138 | self.printProject('\t%s' % (_RelPath(project))) | ||
139 | self.printText(' changed from ') | ||
140 | self.printRevision(project.revisionExpr) | ||
141 | self.printText(' to ') | ||
142 | self.printRevision(otherProject.revisionExpr) | ||
143 | self.out.nl() | ||
144 | self._printLogs(project, otherProject, raw=False, color=color, | ||
145 | pretty_format=pretty_format) | ||
146 | self.out.nl() | ||
147 | |||
148 | if diff['unreachable']: | ||
149 | self.out.nl() | ||
150 | self.printText('projects with unreachable revisions : \n') | ||
151 | self.out.nl() | ||
152 | for project, otherProject in diff['unreachable']: | ||
153 | self.printProject('\t%s ' % (_RelPath(project))) | ||
154 | self.printRevision(project.revisionExpr) | ||
155 | self.printText(' or ') | ||
156 | self.printRevision(otherProject.revisionExpr) | ||
157 | self.printText(' not found') | ||
158 | self.out.nl() | ||
159 | |||
160 | def _printLogs(self, project, otherProject, raw=False, color=True, | ||
161 | pretty_format=None): | ||
162 | |||
163 | logs = project.getAddedAndRemovedLogs(otherProject, | ||
164 | oneline=(pretty_format is None), | ||
165 | color=color, | ||
166 | pretty_format=pretty_format) | ||
167 | if logs['removed']: | ||
168 | removedLogs = logs['removed'].split('\n') | ||
169 | for log in removedLogs: | ||
170 | if log.strip(): | ||
171 | if raw: | ||
172 | self.printText(' R ' + log) | ||
173 | self.out.nl() | 93 | self.out.nl() |
174 | else: | 94 | |
175 | self.printRemoved('\t\t[-] ') | 95 | for project in diff["removed"]: |
176 | self.printText(log) | 96 | self.printText( |
97 | "R %s %s" % (_RelPath(project), project.revisionExpr) | ||
98 | ) | ||
99 | self.out.nl() | ||
100 | |||
101 | for project, otherProject in diff["changed"]: | ||
102 | self.printText( | ||
103 | "C %s %s %s" | ||
104 | % ( | ||
105 | _RelPath(project), | ||
106 | project.revisionExpr, | ||
107 | otherProject.revisionExpr, | ||
108 | ) | ||
109 | ) | ||
110 | self.out.nl() | ||
111 | self._printLogs( | ||
112 | project, | ||
113 | otherProject, | ||
114 | raw=True, | ||
115 | color=False, | ||
116 | pretty_format=pretty_format, | ||
117 | ) | ||
118 | |||
119 | for project, otherProject in diff["unreachable"]: | ||
120 | self.printText( | ||
121 | "U %s %s %s" | ||
122 | % ( | ||
123 | _RelPath(project), | ||
124 | project.revisionExpr, | ||
125 | otherProject.revisionExpr, | ||
126 | ) | ||
127 | ) | ||
128 | self.out.nl() | ||
129 | |||
130 | def _printDiff(self, diff, color=True, pretty_format=None, local=False): | ||
131 | _RelPath = lambda p: p.RelPath(local=local) | ||
132 | if diff["added"]: | ||
133 | self.out.nl() | ||
134 | self.printText("added projects : \n") | ||
177 | self.out.nl() | 135 | self.out.nl() |
136 | for project in diff["added"]: | ||
137 | self.printProject("\t%s" % (_RelPath(project))) | ||
138 | self.printText(" at revision ") | ||
139 | self.printRevision(project.revisionExpr) | ||
140 | self.out.nl() | ||
178 | 141 | ||
179 | if logs['added']: | 142 | if diff["removed"]: |
180 | addedLogs = logs['added'].split('\n') | ||
181 | for log in addedLogs: | ||
182 | if log.strip(): | ||
183 | if raw: | ||
184 | self.printText(' A ' + log) | ||
185 | self.out.nl() | 143 | self.out.nl() |
186 | else: | 144 | self.printText("removed projects : \n") |
187 | self.printAdded('\t\t[+] ') | ||
188 | self.printText(log) | ||
189 | self.out.nl() | 145 | self.out.nl() |
146 | for project in diff["removed"]: | ||
147 | self.printProject("\t%s" % (_RelPath(project))) | ||
148 | self.printText(" at revision ") | ||
149 | self.printRevision(project.revisionExpr) | ||
150 | self.out.nl() | ||
190 | 151 | ||
191 | def ValidateOptions(self, opt, args): | 152 | if diff["missing"]: |
192 | if not args or len(args) > 2: | 153 | self.out.nl() |
193 | self.OptionParser.error('missing manifests to diff') | 154 | self.printText("missing projects : \n") |
194 | if opt.this_manifest_only is False: | 155 | self.out.nl() |
195 | raise self.OptionParser.error( | 156 | for project in diff["missing"]: |
196 | '`diffmanifest` only supports the current tree') | 157 | self.printProject("\t%s" % (_RelPath(project))) |
197 | 158 | self.printText(" at revision ") | |
198 | def Execute(self, opt, args): | 159 | self.printRevision(project.revisionExpr) |
199 | self.out = _Coloring(self.client.globalConfig) | 160 | self.out.nl() |
200 | self.printText = self.out.nofmt_printer('text') | 161 | |
201 | if opt.color: | 162 | if diff["changed"]: |
202 | self.printProject = self.out.nofmt_printer('project', attr='bold') | 163 | self.out.nl() |
203 | self.printAdded = self.out.nofmt_printer('green', fg='green', attr='bold') | 164 | self.printText("changed projects : \n") |
204 | self.printRemoved = self.out.nofmt_printer('red', fg='red', attr='bold') | 165 | self.out.nl() |
205 | self.printRevision = self.out.nofmt_printer('revision', fg='yellow') | 166 | for project, otherProject in diff["changed"]: |
206 | else: | 167 | self.printProject("\t%s" % (_RelPath(project))) |
207 | self.printProject = self.printAdded = self.printRemoved = self.printRevision = self.printText | 168 | self.printText(" changed from ") |
208 | 169 | self.printRevision(project.revisionExpr) | |
209 | manifest1 = RepoClient(self.repodir) | 170 | self.printText(" to ") |
210 | manifest1.Override(args[0], load_local_manifests=False) | 171 | self.printRevision(otherProject.revisionExpr) |
211 | if len(args) == 1: | 172 | self.out.nl() |
212 | manifest2 = self.manifest | 173 | self._printLogs( |
213 | else: | 174 | project, |
214 | manifest2 = RepoClient(self.repodir) | 175 | otherProject, |
215 | manifest2.Override(args[1], load_local_manifests=False) | 176 | raw=False, |
216 | 177 | color=color, | |
217 | diff = manifest1.projectsDiff(manifest2) | 178 | pretty_format=pretty_format, |
218 | if opt.raw: | 179 | ) |
219 | self._printRawDiff(diff, pretty_format=opt.pretty_format, | 180 | self.out.nl() |
220 | local=opt.this_manifest_only) | 181 | |
221 | else: | 182 | if diff["unreachable"]: |
222 | self._printDiff(diff, color=opt.color, pretty_format=opt.pretty_format, | 183 | self.out.nl() |
223 | local=opt.this_manifest_only) | 184 | self.printText("projects with unreachable revisions : \n") |
185 | self.out.nl() | ||
186 | for project, otherProject in diff["unreachable"]: | ||
187 | self.printProject("\t%s " % (_RelPath(project))) | ||
188 | self.printRevision(project.revisionExpr) | ||
189 | self.printText(" or ") | ||
190 | self.printRevision(otherProject.revisionExpr) | ||
191 | self.printText(" not found") | ||
192 | self.out.nl() | ||
193 | |||
194 | def _printLogs( | ||
195 | self, project, otherProject, raw=False, color=True, pretty_format=None | ||
196 | ): | ||
197 | logs = project.getAddedAndRemovedLogs( | ||
198 | otherProject, | ||
199 | oneline=(pretty_format is None), | ||
200 | color=color, | ||
201 | pretty_format=pretty_format, | ||
202 | ) | ||
203 | if logs["removed"]: | ||
204 | removedLogs = logs["removed"].split("\n") | ||
205 | for log in removedLogs: | ||
206 | if log.strip(): | ||
207 | if raw: | ||
208 | self.printText(" R " + log) | ||
209 | self.out.nl() | ||
210 | else: | ||
211 | self.printRemoved("\t\t[-] ") | ||
212 | self.printText(log) | ||
213 | self.out.nl() | ||
214 | |||
215 | if logs["added"]: | ||
216 | addedLogs = logs["added"].split("\n") | ||
217 | for log in addedLogs: | ||
218 | if log.strip(): | ||
219 | if raw: | ||
220 | self.printText(" A " + log) | ||
221 | self.out.nl() | ||
222 | else: | ||
223 | self.printAdded("\t\t[+] ") | ||
224 | self.printText(log) | ||
225 | self.out.nl() | ||
226 | |||
227 | def ValidateOptions(self, opt, args): | ||
228 | if not args or len(args) > 2: | ||
229 | self.OptionParser.error("missing manifests to diff") | ||
230 | if opt.this_manifest_only is False: | ||
231 | raise self.OptionParser.error( | ||
232 | "`diffmanifest` only supports the current tree" | ||
233 | ) | ||
234 | |||
235 | def Execute(self, opt, args): | ||
236 | self.out = _Coloring(self.client.globalConfig) | ||
237 | self.printText = self.out.nofmt_printer("text") | ||
238 | if opt.color: | ||
239 | self.printProject = self.out.nofmt_printer("project", attr="bold") | ||
240 | self.printAdded = self.out.nofmt_printer( | ||
241 | "green", fg="green", attr="bold" | ||
242 | ) | ||
243 | self.printRemoved = self.out.nofmt_printer( | ||
244 | "red", fg="red", attr="bold" | ||
245 | ) | ||
246 | self.printRevision = self.out.nofmt_printer("revision", fg="yellow") | ||
247 | else: | ||
248 | self.printProject = ( | ||
249 | self.printAdded | ||
250 | ) = self.printRemoved = self.printRevision = self.printText | ||
251 | |||
252 | manifest1 = RepoClient(self.repodir) | ||
253 | manifest1.Override(args[0], load_local_manifests=False) | ||
254 | if len(args) == 1: | ||
255 | manifest2 = self.manifest | ||
256 | else: | ||
257 | manifest2 = RepoClient(self.repodir) | ||
258 | manifest2.Override(args[1], load_local_manifests=False) | ||
259 | |||
260 | diff = manifest1.projectsDiff(manifest2) | ||
261 | if opt.raw: | ||
262 | self._printRawDiff( | ||
263 | diff, | ||
264 | pretty_format=opt.pretty_format, | ||
265 | local=opt.this_manifest_only, | ||
266 | ) | ||
267 | else: | ||
268 | self._printDiff( | ||
269 | diff, | ||
270 | color=opt.color, | ||
271 | pretty_format=opt.pretty_format, | ||
272 | local=opt.this_manifest_only, | ||
273 | ) | ||