• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
8import contextlib
9import os
10import re
11import shutil
12import subprocess
13import tempfile
14import sys
15
16sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
17from base import constants
18
19
20def 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
29def 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
38def 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
89def _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