| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """Helper script for printing differences between tags.""" | 7 """Helper script for printing differences between tags.""" |
| 8 | 8 |
| 9 import cgi | 9 import cgi |
| 10 from datetime import datetime | 10 from datetime import datetime |
| 11 import operator |
| 12 import optparse |
| 11 import os | 13 import os |
| 12 import re | 14 import re |
| 13 import sys | 15 import sys |
| 14 | 16 |
| 15 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../lib')) | 17 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../lib')) |
| 16 from cros_build_lib import RunCommand | 18 from cros_build_lib import RunCommand |
| 17 | 19 |
| 18 DEFAULT_TRACKER = 'chromium-os' | 20 DEFAULT_TRACKER = 'chromium-os' |
| 19 | 21 |
| 20 | 22 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 return (cmp(self.projectname, other.projectname) or | 131 return (cmp(self.projectname, other.projectname) or |
| 130 cmp(self.commit_date, other.commit_date)) | 132 cmp(self.commit_date, other.commit_date)) |
| 131 | 133 |
| 132 | 134 |
| 133 def _GrabChanges(path, tag1, tag2): | 135 def _GrabChanges(path, tag1, tag2): |
| 134 """Return list of commits to path between tag1 and tag2.""" | 136 """Return list of commits to path between tag1 and tag2.""" |
| 135 | 137 |
| 136 cmd = 'cd %s && git config --get remote.cros.projectname' % path | 138 cmd = 'cd %s && git config --get remote.cros.projectname' % path |
| 137 projectname = _GrabOutput(cmd).strip() | 139 projectname = _GrabOutput(cmd).strip() |
| 138 log_fmt = '%x00%H\t%ce\t%cd\t%s\t%b' | 140 log_fmt = '%x00%H\t%ce\t%cd\t%s\t%b' |
| 139 cmd_fmt = 'cd %s && git log --format="%s" --date=local %s..%s' | 141 cmd_fmt = 'cd %s && git log --format="%s" --date=local "%s..%s"' |
| 140 cmd = cmd_fmt % (path, log_fmt, tag1, tag2) | 142 cmd = cmd_fmt % (path, log_fmt, tag1, tag2) |
| 141 output = _GrabOutput(cmd) | 143 output = _GrabOutput(cmd) |
| 142 commits = [] | 144 commits = [] |
| 143 for log_data in output.split('\0')[1:]: | 145 for log_data in output.split('\0')[1:]: |
| 144 commit, commit_email, commit_date, subject, body = log_data.split('\t', 4) | 146 commit, commit_email, commit_date, subject, body = log_data.split('\t', 4) |
| 145 change = Commit(commit, projectname, commit_email, commit_date, subject, | 147 change = Commit(commit, projectname, commit_email, commit_date, subject, |
| 146 body) | 148 body) |
| 147 commits.append(change) | 149 commits.append(change) |
| 148 return commits | 150 return commits |
| 149 | 151 |
| 152 def _ParseArgs(): |
| 153 parser = optparse.OptionParser() |
| 154 parser.add_option("--sort-by-date", dest="sort_by_date", default=False, |
| 155 action='store_true', help="Sort commits by date.") |
| 156 return parser.parse_args() |
| 157 |
| 150 | 158 |
| 151 def main(): | 159 def main(): |
| 152 tags = _GrabTags() | 160 tags = _GrabTags() |
| 153 tag1 = None | 161 tag1 = None |
| 154 if len(sys.argv) == 3: | 162 options, args = _ParseArgs() |
| 155 tag1 = sys.argv[1] | 163 if len(args) == 2: |
| 156 tag2 = sys.argv[2] | 164 tag1, tag2 = args |
| 157 elif len(sys.argv) == 2: | 165 elif len(args) == 1: |
| 158 tag2 = sys.argv[1] | 166 tag2, = args |
| 167 if tag2 in tags: |
| 168 tag1 = tags[tags.index(tag2) + 1] |
| 169 else: |
| 170 print >>sys.stderr, 'Unrecognized tag: %s' % tag2 |
| 171 sys.exit(1) |
| 159 else: | 172 else: |
| 160 print >>sys.stderr, 'Usage: %s [tag1] tag2' % sys.argv[0] | 173 print >>sys.stderr, 'Usage: %s [tag1] tag2' % sys.argv[0] |
| 161 print >>sys.stderr, 'If only one tag is specified, we view the differences' | 174 print >>sys.stderr, 'If only one tag is specified, we view the differences' |
| 162 print >>sys.stderr, 'between that tag and the previous tag. You can also' | 175 print >>sys.stderr, 'between that tag and the previous tag. You can also' |
| 163 print >>sys.stderr, 'specify cros/master to show differences with' | 176 print >>sys.stderr, 'specify cros/master to show differences with' |
| 164 print >>sys.stderr, 'tip-of-tree.' | 177 print >>sys.stderr, 'tip-of-tree.' |
| 165 sys.exit(1) | 178 print >>sys.stderr, 'E.g. %s %s cros/master' % (sys.argv[0], tags[0]) |
| 166 if not tag2.startswith('cros/') and tag2 not in tags: | |
| 167 print >>sys.stderr, 'Unrecognized tag: %s' % tag2 | |
| 168 sys.exit(1) | |
| 169 if not tag1: | |
| 170 tag1 = tags[tags.index(tag2) + 1] | |
| 171 if not tag1.startswith('cros/') and tag1 not in tags: | |
| 172 print >>sys.stderr, 'Unrecognized tag: %s' % tag1 | |
| 173 sys.exit(1) | 179 sys.exit(1) |
| 174 | 180 |
| 175 print >>sys.stderr, 'Finding differences between %s and %s' % (tag1, tag2) | 181 print >>sys.stderr, 'Finding differences between %s and %s' % (tag1, tag2) |
| 176 paths = _GrabDirs() | 182 paths = _GrabDirs() |
| 177 changes = [] | 183 changes = [] |
| 178 for path in paths: | 184 for path in paths: |
| 179 changes.extend(_GrabChanges(path, tag1, tag2)) | 185 changes.extend(_GrabChanges(path, tag1, tag2)) |
| 180 | 186 |
| 181 title = 'Changelog for %s to %s' % (tag1, tag2) | 187 title = 'Changelog for %s to %s' % (tag1, tag2) |
| 182 print '<html>' | 188 print '<html>' |
| 183 print '<head><title>%s</title></head>' % title | 189 print '<head><title>%s</title></head>' % title |
| 184 print '<h1>%s</h1>' % title | 190 print '<h1>%s</h1>' % title |
| 185 cols = ['Project', 'Date', 'Commit', 'Committer', 'Bugs', 'Subject'] | 191 cols = ['Project', 'Date', 'Commit', 'Committer', 'Bugs', 'Subject'] |
| 186 print '<table border="1" cellpadding="4">' | 192 print '<table border="1" cellpadding="4">' |
| 187 print '<tr><th>%s</th>' % ('</th><th>'.join(cols)) | 193 print '<tr><th>%s</th>' % ('</th><th>'.join(cols)) |
| 188 for change in sorted(changes): | 194 if options.sort_by_date: |
| 195 changes.sort(key=operator.attrgetter("commit_date")) |
| 196 else: |
| 197 changes.sort() |
| 198 for change in changes: |
| 189 print change.AsHTMLTableRow() | 199 print change.AsHTMLTableRow() |
| 190 print '</table>' | 200 print '</table>' |
| 191 print '</html>' | 201 print '</html>' |
| 192 | 202 |
| 193 | 203 |
| 194 if __name__ == '__main__': | 204 if __name__ == '__main__': |
| 195 main() | 205 main() |
| OLD | NEW |