Make gn.py support root directories other than 'src'.

In https://codereview.chromium.org/341533006/ a change
was made so that gn.py is not looking for the .gn file
to identify the root of the checkout. This breaks
GN functionality for projects that uses gclient but
have a top directory named something else than 'src'.

This change adds support for arbitrarily named primary (the first)
solutions in the .gclient file.
It also adds a check for the generated GN path so a friendly
error message can be printed if the GN executable cannot be found.


BUG=389883
TESTED=Various cases of Chromium, WebRTC and custom checkouts
with .gclient containing empty solution list, solution missing the
'name' key and so on.

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@291819 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gclient_utils.py b/gclient_utils.py
index e8d916e..a21e65a 100644
--- a/gclient_utils.py
+++ b/gclient_utils.py
@@ -681,7 +681,10 @@
     if os.path.exists(os.path.join(top_dir, 'buildtools')):
       return os.path.join(top_dir, 'buildtools')
     return None
-  return os.path.join(gclient_root, 'src', 'buildtools')
+
+  # Some projects' top directory is not named 'src'.
+  source_dir_name = GetGClientPrimarySolutionName(gclient_root) or 'src'
+  return os.path.join(gclient_root, source_dir_name, 'buildtools')
 
 
 def GetBuildtoolsPlatformBinaryPath():
@@ -713,6 +716,17 @@
   return ''
 
 
+def GetGClientPrimarySolutionName(gclient_root_dir_path):
+  """Returns the name of the primary solution in the .gclient file specified."""
+  gclient_config_file = os.path.join(gclient_root_dir_path, '.gclient')
+  env = {}
+  execfile(gclient_config_file, env)
+  solutions = env.get('solutions', [])
+  if solutions:
+    return solutions[0].get('name')
+  return None
+
+
 def GetGClientRootAndEntries(path=None):
   """Returns the gclient root and the dict of entries."""
   config_file = '.gclient_entries'