cros_extract_deps: support writing dependencies to a file

cros_extract_deps imports parallel_emerge to generate the dependency
tree, and sometimes, undesirable lines were printed to stdout,
contaminating the dependencies. As a workaround, allow
cros_extract_deps to exlicitly write dependencies to a file.

Also update commands.ExtractDependencies to use this feature when raw
command result is not requested.

BUG=chromium:428824
TEST=`cbuildbot --remote winky-release`

Change-Id: Ia4f7788a33f67bfbdd5f39b8b218e9b2496954dd
Reviewed-on: https://chromium-review.googlesource.com/226671
Reviewed-by: Yu-Ju Hong <yjhong@chromium.org>
Commit-Queue: Yu-Ju Hong <yjhong@chromium.org>
Tested-by: Yu-Ju Hong <yjhong@chromium.org>
diff --git a/scripts/cros_extract_deps.py b/scripts/cros_extract_deps.py
index 1736c72..a27ae4e 100644
--- a/scripts/cros_extract_deps.py
+++ b/scripts/cros_extract_deps.py
@@ -160,7 +160,9 @@
                       help='The board to use when computing deps.')
   parser.add_argument('--format', default='deps',
                       choices=['deps', 'cpe'],
-                      help='Output either traditional deps or CPE-only JSON')
+                      help='Output either traditional deps or CPE-only JSON.')
+  parser.add_argument('--output-path', default=None,
+                      help='Write output to the given path.')
   # Even though this is really just a pass-through to DepGraphGenerator,
   # handling it as a known arg here allows us to specify a default more
   # elegantly than testing for its presence in the unknown_args later.
@@ -181,4 +183,10 @@
   deps_list = FlattenDepTree(deps_tree, get_cpe=(known_args.format == 'cpe'))
   if known_args.format == 'cpe':
     deps_list = ExtractCPEList(deps_list)
-  print(json.dumps(deps_list, sort_keys=True, indent=2))
+
+  deps_output = json.dumps(deps_list, sort_keys=True, indent=2)
+  if known_args.output_path:
+    with open(known_args.output_path, 'w') as f:
+      f.write(deps_output)
+  else:
+    print(deps_output)