1 # Copyright 2013 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.
6 from tvcm import resource as resource_module
7 from tvcm import resource_loader
9 def _FindAllFilesRecursive(source_paths):
11 for source_path in source_paths:
12 for dirpath, dirnames, filenames in os.walk(source_path):
16 x = os.path.abspath(os.path.join(dirpath, f))
20 def _IsFilenameAModule(loader, x):
21 if x.endswith('.html'):
27 def _IsFilenameATest(loader, x):
28 if x.endswith('_test.js'):
31 if x.endswith('_test.html'):
34 if x.endswith('_unittest.js'):
37 if x.endswith('_unittest.html'):
40 # TODO(nduca): Add content test?
43 class AbsFilenameList(object):
44 def __init__(self, willDirtyCallback):
45 self._willDirtyCallback = willDirtyCallback
47 self._filenames_set = set()
49 def _WillBecomeDirty(self):
50 if self._willDirtyCallback:
51 self._willDirtyCallback()
53 def append(self, filename):
54 assert os.path.isabs(filename)
55 self._WillBecomeDirty()
56 self._filenames.append(filename)
57 self._filenames_set.add(filename)
59 def extend(self, iter):
60 self._WillBecomeDirty()
62 assert os.path.isabs(filename)
63 self._filenames.append(filename)
64 self._filenames_set.add(filename)
66 def appendRel(self, basedir, filename):
67 assert os.path.isabs(basedir)
68 self._WillBecomeDirty()
69 n = os.path.abspath(os.path.join(basedir, filename))
70 self._filenames.append(n)
71 self._filenames_set.add(n)
73 def extendRel(self, basedir, iter):
74 self._WillBecomeDirty()
75 assert os.path.isabs(basedir)
77 n = os.path.abspath(os.path.join(basedir, filename))
78 self._filenames.append(n)
79 self._filenames_set.add(n)
81 def __contains__(self, x):
82 return x in self._filenames_set
85 return self._filenames.__len__()
88 return iter(self._filenames)
91 return repr(self._filenames)
94 return str(self._filenames)
97 class Project(object):
98 tvcm_path = os.path.abspath(os.path.join(
99 os.path.dirname(__file__), '..'))
101 tvcm_src_path = os.path.abspath(os.path.join(
104 tvcm_third_party_path = os.path.abspath(os.path.join(
105 tvcm_path, 'third_party'))
107 def __init__(self, source_paths=None, include_tvcm_paths=True, non_module_html_files=None):
109 source_paths: A list of top-level directories in which modules and raw scripts can be found.
110 Module paths are relative to these directories.
114 self.source_paths = AbsFilenameList(self._WillPartOfPathChange)
115 self.non_module_html_files = AbsFilenameList(self._WillPartOfPathChange)
117 if include_tvcm_paths:
118 self.source_paths.append(self.tvcm_src_path)
119 self.source_paths.extendRel(self.tvcm_third_party_path, [
120 'Promises/polyfill/src',
125 self.non_module_html_files.extendRel(self.tvcm_third_party_path, [
126 'gl-matrix/jsdoc-template/static/header.html',
127 'gl-matrix/jsdoc-template/static/index.html',
128 'Promises/polyfill/tests/test.html',
129 'Promises/reworked_APIs/IndexedDB/example/after.html',
130 'Promises/reworked_APIs/IndexedDB/example/before.html',
131 'Promises/reworked_APIs/WebCrypto/example/after.html',
132 'Promises/reworked_APIs/WebCrypto/example/before.html'
135 if source_paths != None:
136 self.source_paths.extend(source_paths)
138 if non_module_html_files != None:
139 self.non_module_html_files.extend(non_module_html_files)
144 def _WillPartOfPathChange(self):
146 raise Exception('The project is frozen. You cannot edit it now')
151 return Project(d['source_paths'],
152 include_tvcm_paths=False,
153 non_module_html_files=d.get('non_module_html_files', None))
157 'source_paths': list(self.source_paths),
158 'non_module_html_files': list(self.non_module_html_files)
162 return "Project(%s)" % repr(self.source_paths)
164 def AddSourcePath(self, path):
165 self.source_paths.append(path)
169 if self._loader == None:
170 self._loader = resource_loader.ResourceLoader(self)
173 def ResetLoader(self):
176 def _FindAllModuleFilenames(self, source_paths):
177 all_filenames = _FindAllFilesRecursive(source_paths)
178 return [x for x in all_filenames if
179 x not in self.non_module_html_files and
180 _IsFilenameAModule(self.loader, x)]
182 def _FindTestModuleFilenames(self, source_paths):
183 all_filenames = _FindAllFilesRecursive(source_paths)
184 return [x for x in all_filenames if
185 x not in self.non_module_html_files and
186 _IsFilenameATest(self.loader, x)]
188 def FindAllTestModuleResources(self, start_path=None):
189 if start_path == None:
190 test_module_filenames = self._FindTestModuleFilenames(self.source_paths)
192 test_module_filenames = self._FindTestModuleFilenames([start_path])
193 test_module_filenames.sort()
195 # Find the equivalent resources.
196 return [self.loader.FindResourceGivenAbsolutePath(x)
197 for x in test_module_filenames]
199 def FindAllModuleFilenames(self):
200 return self._FindAllModuleFilenames(self.source_paths)
202 def CalcLoadSequenceForAllModules(self):
203 filenames = self.FindAllModuleFilenames()
204 return self.CalcLoadSequenceForModuleFilenames(filenames)
206 def _Load(self, filenames):
207 return [self.loader.LoadModule(module_filename=filename) for
208 filename in filenames]
210 def CalcLoadSequenceForModuleFilenames(self, filenames):
211 modules = self._Load(filenames)
212 return self.CalcLoadSequenceForModules(modules)
214 def CalcLoadSequenceForModuleNames(self, module_names):
215 modules = [self.loader.LoadModule(module_name=name) for
216 name in module_names]
217 return self.CalcLoadSequenceForModules(modules)
219 def CalcLoadSequenceForModules(self, modules):
220 already_loaded_set = set()
223 m.ComputeLoadSequenceRecursive(load_sequence, already_loaded_set)