git_cl: description fetching from code review servers.

BUG=

Review URL: https://codereview.chromium.org/1901733003

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@300207 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/git_cl.py b/git_cl.py
index d7c9636..7d3c105 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -3264,19 +3264,36 @@
   return 0
 
 
+@subcommand.usage('[codereview url or issue id]')
 def CMDdescription(parser, args):
   """Brings up the editor for the current CL's description."""
   parser.add_option('-d', '--display', action='store_true',
                     help='Display the description instead of opening an editor')
+
+  _add_codereview_select_options(parser)
   auth.add_auth_options(parser)
-  options, _ = parser.parse_args(args)
+  options, args = parser.parse_args(args)
+  _process_codereview_select_options(parser, options)
+
+  target_issue = None
+  if len(args) > 0:
+    issue_arg = ParseIssueNumberArgument(args[0])
+    if not issue_arg.valid:
+      parser.print_help()
+      return 1
+    target_issue = issue_arg.issue
+
   auth_config = auth.extract_auth_config_from_options(options)
-  cl = Changelist(auth_config=auth_config)
+
+  cl = Changelist(
+      auth_config=auth_config, issue=target_issue,
+      codereview=options.forced_codereview)
+
   if not cl.GetIssue():
     DieWithError('This branch has no associated changelist.')
   description = ChangeDescription(cl.GetDescription())
   if options.display:
-    print description.description
+    print >> sys.stdout, description.description
     return 0
   description.prompt()
   if cl.GetDescription() != description.description:
diff --git a/tests/git_cl_test.py b/tests/git_cl_test.py
index 8b00ac7..571be65 100755
--- a/tests/git_cl_test.py
+++ b/tests/git_cl_test.py
@@ -1381,6 +1381,48 @@
     # super tedious.
     self.assertEqual(0, git_cl.main(['set-commit', '-d']))
 
+  def test_description_display(self):
+    out = StringIO.StringIO()
+    self.mock(git_cl.sys, 'stdout', out)
+
+    class MockChangelist():
+      def __init__(self, **kwargs):
+        pass
+      def GetIssue(self):
+        return 1
+      def GetDescription(self):
+        return 'foo'
+
+    self.mock(git_cl, 'Changelist', MockChangelist)
+
+    self.assertEqual(0, git_cl.main(['description', '-d']))
+    self.assertEqual('foo\n', out.getvalue())
+
+  def test_description_rietveld(self):
+    out = StringIO.StringIO()
+    self.mock(git_cl.sys, 'stdout', out)
+    self.mock(git_cl.Changelist, 'GetDescription',
+              lambda *args: 'foobar')
+
+    self.calls = [
+        ((['git', 'config', 'rietveld.autoupdate'],), ''),
+        ((['git', 'config', 'rietveld.server'],), ''),
+        ((['git', 'config', 'rietveld.server'],), ''),
+    ]
+    self.assertEqual(0, git_cl.main([
+        'description', 'https://code.review.org/123123', '-d', '--rietveld']))
+    self.assertEqual('foobar\n', out.getvalue())
+
+  def test_description_gerrit(self):
+    out = StringIO.StringIO()
+    self.mock(git_cl.sys, 'stdout', out)
+    self.mock(git_cl.Changelist, 'GetDescription',
+              lambda *args: 'foobar')
+
+    self.assertEqual(0, git_cl.main([
+        'description', 'https://code.review.org/123123', '-d', '--gerrit']))
+    self.assertEqual('foobar\n', out.getvalue())
+
 
 if __name__ == '__main__':
   git_cl.logging.basicConfig(