1# Copyright (c) 2014 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
5import sys
6import os
7import re
8
9
10def _AddToPathIfNeeded(path):
11  if path not in sys.path:
12    sys.path.insert(0, path)
13
14
15def UpdateSysPathIfNeeded():
16  p = TracingProject()
17  _AddToPathIfNeeded(p.catapult_path)
18  _AddToPathIfNeeded(p.py_vulcanize_path)
19  _AddToPathIfNeeded(p.vinn_path)
20
21  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'WebOb'))
22  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'Paste'))
23  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'six'))
24  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'webapp2'))
25
26
27def _FindAllFilesRecursive(source_paths):
28  assert isinstance(source_paths, list)
29  all_filenames = set()
30  for source_path in source_paths:
31    for dirpath, _, filenames in os.walk(source_path):
32      for f in filenames:
33        if f.startswith('.'):
34          continue
35        x = os.path.abspath(os.path.join(dirpath, f))
36        all_filenames.add(x)
37  return all_filenames
38
39def _IsFilenameATest(x):
40  if x.endswith('_test.js'):
41    return True
42
43  if x.endswith('_test.html'):
44    return True
45
46  if x.endswith('_unittest.js'):
47    return True
48
49  if x.endswith('_unittest.html'):
50    return True
51
52  # TODO(nduca): Add content test?
53  return False
54
55
56class TracingProject(object):
57  catapult_path = os.path.abspath(
58      os.path.join(os.path.dirname(__file__), os.path.pardir))
59
60  tracing_root_path = os.path.join(catapult_path, 'tracing')
61  tracing_src_path = os.path.join(tracing_root_path, 'tracing')
62  extras_path = os.path.join(tracing_src_path, 'extras')
63  ui_extras_path = os.path.join(tracing_src_path, 'ui', 'extras')
64
65  catapult_third_party_path = os.path.join(catapult_path, 'third_party')
66
67  tracing_third_party_path = os.path.join(tracing_root_path, 'third_party')
68  py_vulcanize_path = os.path.join(catapult_third_party_path, 'py_vulcanize')
69  vinn_path = os.path.join(catapult_third_party_path, 'vinn')
70
71  jszip_path = os.path.join(tracing_third_party_path, 'jszip')
72
73  glmatrix_path = os.path.join(
74      tracing_third_party_path, 'gl-matrix', 'dist')
75
76  ui_path = os.path.join(tracing_src_path, 'ui')
77  d3_path = os.path.join(tracing_third_party_path, 'd3')
78  chai_path = os.path.join(tracing_third_party_path, 'chai')
79  mocha_path = os.path.join(tracing_third_party_path, 'mocha')
80
81  mre_path = os.path.join(catapult_path, 'perf_insights')
82
83  value_ui_path = os.path.join(tracing_src_path, 'value', 'ui')
84  metrics_ui_path = os.path.join(tracing_src_path, 'metrics', 'ui')
85
86  test_data_path = os.path.join(tracing_root_path, 'test_data')
87  skp_data_path = os.path.join(tracing_root_path, 'skp_data')
88
89  rjsmin_path = os.path.join(
90      tracing_third_party_path, 'tvcm', 'third_party', 'rjsmin')
91  rcssmin_path = os.path.join(
92      tracing_third_party_path, 'tvcm', 'third_party', 'rcssmin')
93
94  def __init__(self):
95    self.source_paths = []
96    self.source_paths.append(self.tracing_root_path)
97    self.source_paths.append(self.tracing_third_party_path)
98    self.source_paths.append(self.mre_path)
99    self.source_paths.append(self.jszip_path)
100    self.source_paths.append(self.glmatrix_path)
101    self.source_paths.append(self.d3_path)
102    self.source_paths.append(self.chai_path)
103    self.source_paths.append(self.mocha_path)
104
105  def CreateVulcanizer(self):
106    from py_vulcanize import project as project_module
107    return project_module.Project(self.source_paths)
108
109  def IsD8CompatibleFile(self, filename):
110    if filename.startswith(self.ui_path):
111      return False
112
113    if filename.startswith(self.value_ui_path):
114      return False
115
116    if filename.startswith(self.metrics_ui_path):
117      return False
118
119    return True
120
121  def FindAllTestModuleRelPaths(self, pred=None):
122    if pred is None:
123      pred = lambda x: True
124
125    all_filenames = _FindAllFilesRecursive([self.tracing_src_path])
126    test_module_filenames = [x for x in all_filenames if
127                             _IsFilenameATest(x) and pred(x)]
128    test_module_filenames.sort()
129
130    return [os.path.relpath(x, self.tracing_root_path)
131            for x in test_module_filenames]
132
133  def FindAllD8TestModuleRelPaths(self):
134    return self.FindAllTestModuleRelPaths(pred=self.IsD8CompatibleFile)
135
136  def GetConfigNames(self):
137    config_files = [
138        os.path.join(self.ui_extras_path, x)
139        for x in os.listdir(self.ui_extras_path)
140        if x.endswith('_config.html')
141    ]
142
143    config_files = [x for x in config_files if os.path.isfile(x)]
144
145    config_basenames = [os.path.basename(x) for x in config_files]
146    config_names = [re.match('(.+)_config.html$', x).group(1)
147                    for x in config_basenames]
148    return config_names
149
150  def GetDefaultConfigName(self):
151    assert 'full' in self.GetConfigNames()
152    return 'full'
153
154  def AddConfigNameOptionToParser(self, parser):
155    choices = self.GetConfigNames()
156    parser.add_argument(
157        '--config', dest='config_name',
158        choices=choices, default=self.GetDefaultConfigName(),
159        help='Picks a browser config. Valid choices: %s' % ', '.join(choices))
160    return choices
161
162  def GetModuleNameForConfigName(self, config_name):
163    return 'tracing.ui.extras.%s_config' % config_name
164
165