Do not write gclient_gn_args_file too early.

Previously, gclient would attempt to write an args file after
a dependency was checked out, but before any sub-dependencies
had been checked out. If the args file path pointed at something
inside a sub-dependency, this wouldn't work, because the directory
might not yet exist. This most obviously happened for buildspec
clobber builds.

The fix is to wait until after the sub-dependencies have been
checked out to write the file.

R=phajdan.jr@chromium.org, mmoss@chromium.org
BUG=773933

Change-Id: I0cf4564204f7dabd9f843dc7904db7050fcc0d23
Reviewed-on: https://chromium-review.googlesource.com/714644
Reviewed-by: Paweł Hajdan Jr. <phajdan.jr@chromium.org>
Commit-Queue: Dirk Pranke <dpranke@chromium.org>
diff --git a/gclient.py b/gclient.py
index d80f99d..35e0597 100755
--- a/gclient.py
+++ b/gclient.py
@@ -893,8 +893,6 @@
 
     # Always parse the DEPS file.
     self.ParseDepsFile()
-    if self._gn_args_file and command == 'update':
-      self.WriteGNArgsFile()
     self._run_is_done(file_list or [], parsed_url)
     if command in ('update', 'revert') and not options.noprehooks:
       self.RunPreDepsHooks()
@@ -961,6 +959,9 @@
         else:
           print('Skipped missing %s' % cwd, file=sys.stderr)
 
+  def HasGNArgsFile(self):
+    return self._gn_args_file is not None
+
   def WriteGNArgsFile(self):
     lines = ['# Generated from %r' % self.deps_file]
     variables = self.get_vars()
@@ -1006,6 +1007,12 @@
       result.extend(s.GetHooks(options))
     return result
 
+  def WriteGNArgsFilesRecursively(self, dependencies):
+    for dep in dependencies:
+      if dep.HasGNArgsFile():
+        dep.WriteGNArgsFile()
+      self.WriteGNArgsFilesRecursively(dep.dependencies)
+
   def RunHooksRecursively(self, options):
     assert self.hooks_ran == False
     self._hooks_ran = True
@@ -1478,8 +1485,11 @@
       print('Please fix your script, having invalid --revision flags will soon '
             'considered an error.', file=sys.stderr)
 
-    # Once all the dependencies have been processed, it's now safe to run the
-    # hooks.
+    # Once all the dependencies have been processed, it's now safe to write
+    # out any gn_args_files and run the hooks.
+    if command == 'update':
+      self.WriteGNArgsFilesRecursively(self.dependencies)
+
     if not self._options.nohooks:
       self.RunHooksRecursively(self._options)