gclient_utils: Add temporary_file method.

Useful when passing information to a subcommand via a temporary file.

Bug: 1051631
Change-Id: I0b8deda921effd24a37109544e1e7ca22e00ba4e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2068942
Reviewed-by: Josip Sokcevic <sokcevic@google.com>
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
diff --git a/gclient_utils.py b/gclient_utils.py
index 9f4de36..4d9e986 100644
--- a/gclient_utils.py
+++ b/gclient_utils.py
@@ -170,8 +170,8 @@
     return s
 
 
-def FileWrite(filename, content, mode='w'):
-  with codecs.open(filename, mode=mode, encoding='utf-8') as f:
+def FileWrite(filename, content, mode='w', encoding='utf-8'):
+  with codecs.open(filename, mode=mode, encoding=encoding) as f:
     f.write(content)
 
 
@@ -185,6 +185,35 @@
       rmtree(tdir)
 
 
+@contextlib.contextmanager
+def temporary_file():
+  """Creates a temporary file.
+
+  On Windows, a file must be closed before it can be opened again. This function
+  allows to write something like:
+
+    with gclient_utils.temporary_file() as tmp:
+      gclient_utils.FileWrite(tmp, foo)
+      useful_stuff(tmp)
+
+  Instead of something like:
+
+    with tempfile.NamedTemporaryFile(delete=False) as tmp:
+      tmp.write(foo)
+      tmp.close()
+      try:
+        useful_stuff(tmp)
+      finally:
+        os.remove(tmp.name)
+  """
+  handle, name = tempfile.mkstemp()
+  os.close(handle)
+  try:
+    yield name
+  finally:
+    os.remove(name)
+
+
 def safe_rename(old, new):
   """Renames a file reliably.