Home | History | Annotate | Download | only in bin
      1 # Copyright 2015 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 # TODO(dtu): Merge this file with its counterparts in catapult_build/ when
      6 # dashboard and PI migrate to Google Cloud SDK.
      7 
      8 import contextlib
      9 import os
     10 import re
     11 import shutil
     12 import subprocess
     13 import tempfile
     14 import sys
     15 
     16 sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
     17 from base import constants
     18 
     19 
     20 def Modules(root_dir):
     21   """Yields module names in root_dir."""
     22   for root, _, files in os.walk(root_dir):
     23     for file_name in files:
     24       if os.path.splitext(file_name)[1] == '.yaml':
     25         yield os.path.basename(root)
     26         break
     27 
     28 
     29 def Yamls(root_dir):
     30   """Yields yaml files in root_dir."""
     31   for root, _, files in os.walk(root_dir):
     32     for file_name in files:
     33       if os.path.splitext(file_name)[1] == '.yaml':
     34         yield os.path.join(root, file_name)
     35 
     36 
     37 @contextlib.contextmanager
     38 def TempAppDir(root_dir, symlinks):
     39   """Sets up and tears down a directory for deploying or running an app.
     40 
     41   Args:
     42     root_dir: The root directory of the app.
     43     symlinks: If true, use symbolic links instead of copying files. This allows
     44         the dev server to detect file changes in the repo, and is faster.
     45 
     46   Yields:
     47     The path to the temporary directory.
     48   """
     49   if symlinks:
     50     link = os.symlink
     51   else:
     52     def Link(src, dest):
     53       if os.path.isdir(src):
     54         return shutil.copytree(src, dest)
     55       else:
     56         return shutil.copy2(src, dest)
     57     link = Link
     58 
     59   gcloud_lib_dir = _GcloudLibDir()
     60   temp_app_dir = tempfile.mkdtemp(prefix='app-')
     61   try:
     62     for module in Modules(root_dir):
     63       module_source_dir = os.path.join(root_dir, module)
     64       module_dest_dir = os.path.join(temp_app_dir, module)
     65       os.mkdir(module_dest_dir)
     66 
     67       # Copy/symlink module into app directory.
     68       for node in os.listdir(module_source_dir):
     69         link(os.path.join(module_source_dir, node),
     70              os.path.join(module_dest_dir, node))
     71 
     72       # Copy/symlink base/ into module directory.
     73       link(os.path.join(root_dir, 'base'),
     74            os.path.join(module_dest_dir, 'base'))
     75 
     76       # Copy/symlink Gcloud library dependencies into module directory.
     77       third_party_dest_dir = os.path.join(module_dest_dir, 'third_party')
     78       os.mkdir(third_party_dest_dir)
     79       open(os.path.join(third_party_dest_dir, '__init__.py'), 'w').close()
     80       for library in constants.GCLOUD_THIRD_PARTY_LIBRARIES:
     81         link(os.path.join(gcloud_lib_dir, library),
     82              os.path.join(third_party_dest_dir, library))
     83 
     84     yield temp_app_dir
     85   finally:
     86     shutil.rmtree(temp_app_dir)
     87 
     88 
     89 def _GcloudLibDir():
     90   process = subprocess.Popen(['gcloud', 'info'], stdout=subprocess.PIPE)
     91   stdout, _ = process.communicate()
     92   gcloud_root_dir = re.search(r'^Installation Root: \[(.*)\]$', stdout,
     93                               flags=re.MULTILINE).groups()[0]
     94   return os.path.join(gcloud_root_dir, 'lib', 'third_party')
     95