Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Unified Diff: chromite/bin/cros_changelog

Issue 6371018: Remove chromite from crosutils.git. It's been moved to chromite.git. (Closed) Base URL: http://git.chromium.org/git/crosutils.git@master
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chromite/bin/cros_build_packages ('k') | chromite/chromite » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromite/bin/cros_changelog
diff --git a/chromite/bin/cros_changelog b/chromite/bin/cros_changelog
deleted file mode 100755
index f75ceab6a830468dd5f607cd99f66dce9d5c7fa5..0000000000000000000000000000000000000000
--- a/chromite/bin/cros_changelog
+++ /dev/null
@@ -1,366 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Helper script for printing differences between tags."""
-
-import cgi
-from datetime import datetime
-import operator
-import optparse
-import os
-import re
-import sys
-
-sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../lib'))
-from cros_build_lib import RunCommand
-
-
-# TODO(dianders):
-# We use GData to access the tracker on code.google.com. Eventually, we
-# want to create an ebuild and add the ebuild to hard-host-depends
-# For now, we'll just include instructions for installing it.
-INSTRS_FOR_GDATA = """
-To access the tracker you need the GData library. To install in your home dir:
-
- GDATA_INSTALL_DIR=~/gdatalib
- mkdir -p "$GDATA_INSTALL_DIR"
-
- TMP_DIR=`mktemp -d`
- pushd $TMP_DIR
- wget http://gdata-python-client.googlecode.com/files/gdata-2.0.12.zip
- unzip gdata-2.0.12.zip
- cd gdata-2.0.12/
- python setup.py install --home="$GDATA_INSTALL_DIR"
- popd
-
- export PYTHONPATH="$GDATA_INSTALL_DIR/lib/python:$PYTHONPATH"
-
-You should add the PYTHONPATH line to your .bashrc file (or equivalent)."""
-
-
-DEFAULT_TRACKER = 'chromium-os'
-
-
-def _GrabOutput(cmd):
- """Returns output from specified command."""
- return RunCommand(cmd, shell=True, print_cmd=False,
- redirect_stdout=True).output
-
-
-def _GrabTags():
- """Returns list of tags from current git repository."""
- # TODO(dianders): replace this with the python equivalent.
- cmd = ("git for-each-ref refs/tags | awk '{print $3}' | "
- "sed 's,refs/tags/,,g' | sort -t. -k3,3rn -k4,4rn")
- return _GrabOutput(cmd).split()
-
-
-def _GrabDirs():
- """Returns list of directories managed by repo."""
- return _GrabOutput('repo forall -c "pwd"').split()
-
-
-class Issue(object):
- """Class for holding info about issues (aka bugs)."""
-
- def __init__(self, project_name, issue_id, tracker_acc):
- """Constructor for Issue object.
-
- Args:
- project_name: The tracker project to query.
- issue_id: The ID of the issue to query
- tracker_acc: A TrackerAccess object, or None.
- """
- self.project_name = project_name
- self.issue_id = issue_id
- self.milestone = ''
- self.priority = ''
-
- if tracker_acc is not None:
- keyed_labels = tracker_acc.GetKeyedLabels(project_name, issue_id)
- if 'Mstone' in keyed_labels:
- self.milestone = keyed_labels['Mstone']
- if 'Pri' in keyed_labels:
- self.priority = keyed_labels['Pri']
-
- def GetUrl(self):
- """Returns the URL to access the issue."""
- bug_url_fmt = 'http://code.google.com/p/%s/issues/detail?id=%s'
-
- # Get bug URL. We use short URLs to make the URLs a bit more readable.
- if self.project_name == 'chromium-os':
- bug_url = 'http://crosbug.com/%s' % self.issue_id
- elif self.project_name == 'chrome-os-partner':
- bug_url = 'http://crosbug.com/p/%s' % self.issue_id
- else:
- bug_url = bug_url_fmt % (self.project_name, self.issue_id)
-
- return bug_url
-
- def __str__(self):
- """Provides a string representation of the issue.
-
- Returns:
- A string that looks something like:
-
- project:id (milestone, priority)
- """
- if self.milestone and self.priority:
- info_str = ' (%s, P%s)' % (self.milestone, self.priority)
- elif self.milestone:
- info_str = ' (%s)' % self.milestone
- elif self.priority:
- info_str = ' (P%s)' % self.priority
- else:
- info_str = ''
-
- return '%s:%s%s' % (self.project_name, self.issue_id, info_str)
-
- def __cmp__(self, other):
- """Compare two Issue objects."""
- return cmp((self.project_name.lower(), self.issue_id),
- (other.project_name.lower(), other.issue_id))
-
-
-class Commit(object):
- """Class for tracking git commits."""
-
- def __init__(self, commit, projectname, commit_email, commit_date, subject,
- body, tracker_acc):
- """Create commit logs.
-
- Args:
- commit: The commit hash (sha) from git.
- projectname: The project name, from:
- git config --get remote.cros.projectname
- commit_email: The email address associated with the commit (%ce in git
- log)
- commit_date: The date of the commit, like "Mon Nov 1 17:34:14 2010 -0500"
- (%cd in git log))
- subject: The subject of the commit (%s in git log)
- body: The body of the commit (%b in git log)
- tracker_acc: A tracker_access.TrackerAccess object.
- """
- self.commit = commit
- self.projectname = projectname
- self.commit_email = commit_email
- fmt = '%a %b %d %H:%M:%S %Y'
- self.commit_date = datetime.strptime(commit_date, fmt)
- self.subject = subject
- self.body = body
- self._tracker_acc = tracker_acc
- self._issues = self._GetIssues()
-
- def _GetIssues(self):
- """Get bug info from commit logs and issue tracker.
-
- This should be called as the last step of __init__, since it
- assumes that our member variables are already setup.
-
- Returns:
- A list of Issue objects, each of which holds info about a bug.
- """
- # NOTE: most of this code is copied from bugdroid:
- # <http://src.chromium.org/viewvc/chrome/trunk/tools/bugdroid/bugdroid.py?revision=59229&view=markup>
-
- # Get a list of bugs. Handle lots of possibilities:
- # - Multiple "BUG=" lines, with varying amounts of whitespace.
- # - For each BUG= line, bugs can be split by commas _or_ by whitespace (!)
- entries = []
- for line in self.body.split('\n'):
- match = re.match(r'^ *BUG *=(.*)', line)
- if match:
- for i in match.group(1).split(','):
- entries.extend(filter(None, [x.strip() for x in i.split()]))
-
- # Try to parse the bugs. Handle lots of different formats:
- # - The whole URL, from which we parse the project and bug.
- # - A simple string that looks like "project:bug"
- # - A string that looks like "bug", which will always refer to the previous
- # tracker referenced (defaulting to the default tracker).
- #
- # We will create an "Issue" object for each bug.
- issues = []
- last_tracker = DEFAULT_TRACKER
- regex = (r'http://code.google.com/p/(\S+)/issues/detail\?id=([0-9]+)'
- r'|(\S+):([0-9]+)|(\b[0-9]+\b)')
-
- for new_item in entries:
- bug_numbers = re.findall(regex, new_item)
- for bug_tuple in bug_numbers:
- if bug_tuple[0] and bug_tuple[1]:
- issues.append(Issue(bug_tuple[0], bug_tuple[1], self._tracker_acc))
- last_tracker = bug_tuple[0]
- elif bug_tuple[2] and bug_tuple[3]:
- issues.append(Issue(bug_tuple[2], bug_tuple[3], self._tracker_acc))
- last_tracker = bug_tuple[2]
- elif bug_tuple[4]:
- issues.append(Issue(last_tracker, bug_tuple[4], self._tracker_acc))
-
- # Sort the issues and return...
- issues.sort()
- return issues
-
- def AsHTMLTableRow(self):
- """Returns HTML for this change, for printing as part of a table.
-
- Columns: Project, Date, Commit, Committer, Bugs, Subject.
-
- Returns:
- A string usable as an HTML table row, like:
-
- <tr><td>Blah</td><td>Blah blah</td></tr>
- """
-
- bugs = []
- link_fmt = '<a href="%s">%s</a>'
- for issue in self._issues:
- bugs.append(link_fmt % (issue.GetUrl(), str(issue)))
-
- url_fmt = 'http://chromiumos-git/git/?p=%s.git;a=commitdiff;h=%s'
- url = url_fmt % (self.projectname, self.commit)
- commit_desc = link_fmt % (url, self.commit[:8])
- bug_str = '<br>'.join(bugs)
- if not bug_str:
- if (self.projectname == 'kernel-next' or
- self.commit_email == 'chrome-bot@chromium.org'):
- bug_str = 'not needed'
- else:
- bug_str = '<font color="red">none</font>'
-
- cols = [
- cgi.escape(self.projectname),
- str(self.commit_date),
- commit_desc,
- cgi.escape(self.commit_email),
- bug_str,
- cgi.escape(self.subject[:100]),
- ]
- return '<tr><td>%s</td></tr>' % ('</td><td>'.join(cols))
-
- def __cmp__(self, other):
- """Compare two Commit objects first by project name, then by date."""
- return (cmp(self.projectname, other.projectname) or
- cmp(self.commit_date, other.commit_date))
-
-
-def _GrabChanges(path, tag1, tag2, tracker_acc):
- """Return list of commits to path between tag1 and tag2.
-
- Args:
- path: One of the directories managed by repo.
- tag1: The first of the two tags to pass to git log.
- tag2: The second of the two tags to pass to git log.
- tracker_acc: A tracker_access.TrackerAccess object.
-
- Returns:
- A list of "Commit" objects.
- """
-
- cmd = 'cd %s && git config --get remote.cros.projectname' % path
- projectname = _GrabOutput(cmd).strip()
- log_fmt = '%x00%H\t%ce\t%cd\t%s\t%b'
- cmd_fmt = 'cd %s && git log --format="%s" --date=local "%s..%s"'
- cmd = cmd_fmt % (path, log_fmt, tag1, tag2)
- output = _GrabOutput(cmd)
- commits = []
- for log_data in output.split('\0')[1:]:
- commit, commit_email, commit_date, subject, body = log_data.split('\t', 4)
- change = Commit(commit, projectname, commit_email, commit_date, subject,
- body, tracker_acc)
- commits.append(change)
- return commits
-
-
-def _ParseArgs():
- """Parse command-line arguments.
-
- Returns:
- An optparse.OptionParser object.
- """
- parser = optparse.OptionParser()
- parser.add_option(
- '--sort-by-date', dest='sort_by_date', default=False,
- action='store_true', help='Sort commits by date.')
- parser.add_option(
- '--tracker-user', dest='tracker_user', default=None,
- help='Specify a username to login to code.google.com.')
- parser.add_option(
- '--tracker-pass', dest='tracker_pass', default=None,
- help='Specify a password to go w/ user.')
- parser.add_option(
- '--tracker-passfile', dest='tracker_passfile', default=None,
- help='Specify a file containing a password to go w/ user.')
- return parser.parse_args()
-
-
-def main():
- tags = _GrabTags()
- tag1 = None
- options, args = _ParseArgs()
- if len(args) == 2:
- tag1, tag2 = args
- elif len(args) == 1:
- tag2, = args
- if tag2 in tags:
- tag2_index = tags.index(tag2)
- if tag2_index == len(tags) - 1:
- print >>sys.stderr, 'No previous tag for %s' % tag2
- sys.exit(1)
- tag1 = tags[tag2_index + 1]
- else:
- print >>sys.stderr, 'Unrecognized tag: %s' % tag2
- sys.exit(1)
- else:
- print >>sys.stderr, 'Usage: %s [tag1] tag2' % sys.argv[0]
- print >>sys.stderr, 'If only one tag is specified, we view the differences'
- print >>sys.stderr, 'between that tag and the previous tag. You can also'
- print >>sys.stderr, 'specify cros/master to show differences with'
- print >>sys.stderr, 'tip-of-tree.'
- print >>sys.stderr, 'E.g. %s %s cros/master' % (sys.argv[0], tags[0])
- sys.exit(1)
-
- if options.tracker_user is not None:
- # TODO(dianders): Once we install GData automatically, move the import
- # to the top of the file where it belongs. It's only here to allow
- # people to run the script without GData.
- try:
- import tracker_access
- except ImportError:
- print >>sys.stderr, INSTRS_FOR_GDATA
- sys.exit(1)
- if options.tracker_passfile is not None:
- options.tracker_pass = open(options.tracker_passfile, 'r').read().strip()
- tracker_acc = tracker_access.TrackerAccess(options.tracker_user,
- options.tracker_pass)
- else:
- tracker_acc = None
-
- print >>sys.stderr, 'Finding differences between %s and %s' % (tag1, tag2)
- paths = _GrabDirs()
- changes = []
- for path in paths:
- changes.extend(_GrabChanges(path, tag1, tag2, tracker_acc))
-
- title = 'Changelog for %s to %s' % (tag1, tag2)
- print '<html>'
- print '<head><title>%s</title></head>' % title
- print '<h1>%s</h1>' % title
- cols = ['Project', 'Date', 'Commit', 'Committer', 'Bugs', 'Subject']
- print '<table border="1" cellpadding="4">'
- print '<tr><th>%s</th>' % ('</th><th>'.join(cols))
- if options.sort_by_date:
- changes.sort(key=operator.attrgetter('commit_date'))
- else:
- changes.sort()
- for change in changes:
- print change.AsHTMLTableRow()
- print '</table>'
- print '</html>'
-
-
-if __name__ == '__main__':
- main()
« no previous file with comments | « chromite/bin/cros_build_packages ('k') | chromite/chromite » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698