Move code starting the editor into a common function.

Windows users wouldn't get the same behavior on git cl vs gcl.
Improve automatic CRLF<->LF conversion, some gcl users would be \n repeated in
their description depending on the editor used.

R=dpranke@chromium.org
BUG=
TEST=


Review URL: http://codereview.chromium.org/8360007

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@107106 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gclient_utils.py b/gclient_utils.py
index 1981f36..8709e08 100644
--- a/gclient_utils.py
+++ b/gclient_utils.py
@@ -11,6 +11,7 @@
 import re
 import stat
 import sys
+import tempfile
 import threading
 import time
 
@@ -687,3 +688,46 @@
         work_queue.ready_cond.notifyAll()
       finally:
         work_queue.ready_cond.release()
+
+
+def GetEditor(git):
+  """Returns the most plausible editor to use."""
+  if git:
+    editor = os.environ.get('GIT_EDITOR')
+  else:
+    editor = os.environ.get('SVN_EDITOR')
+  if not editor:
+    editor = os.environ.get('EDITOR')
+  if not editor:
+    if sys.platform.startswith('win'):
+      editor = 'notepad'
+    else:
+      editor = 'vim'
+  return editor
+
+
+def RunEditor(content, git):
+  """Opens up the default editor in the system to get the CL description."""
+  file_handle, filename = tempfile.mkstemp(text=True)
+  # Make sure CRLF is handled properly by requiring none.
+  if '\r' in content:
+    print >> sys.stderr, ('!! Please remove \\r from your content !!')
+  fileobj = os.fdopen(file_handle, 'w')
+  # Still remove \r if present.
+  fileobj.write(re.sub('\r?\n', '\n', content))
+  fileobj.close()
+
+  try:
+    cmd = '%s %s' % (GetEditor(git), filename)
+    if sys.platform == 'win32' and os.environ.get('TERM') == 'msys':
+      # Msysgit requires the usage of 'env' to be present.
+      cmd = 'env ' + cmd
+    try:
+      # shell=True to allow the shell to handle all forms of quotes in
+      # $EDITOR.
+      subprocess2.check_call(cmd, shell=True)
+    except subprocess2.CalledProcessError:
+      return None
+    return FileRead(filename)
+  finally:
+    os.remove(filename)