|  | #!/usr/bin/env python | 
|  | # Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file | 
|  | # for details. All rights reserved. Use of this source code is governed by a | 
|  | # BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | from __future__ import with_statement | 
|  | import StringIO | 
|  | import os | 
|  | import sys | 
|  | import re | 
|  | from collections import deque | 
|  |  | 
|  | class GenerateError(Exception): | 
|  |  | 
|  | def __init__(self, value): | 
|  | self.value = value | 
|  |  | 
|  | def __str__(self): | 
|  | return repr(self.value) | 
|  |  | 
|  |  | 
|  | class Generator: | 
|  |  | 
|  | def __init__(self, base_directory, name, output, path, *includes): | 
|  | self.base_directory = base_directory | 
|  | self.name = name | 
|  | self.output = output | 
|  | self.path = path | 
|  | self.includes = set() | 
|  | for x in includes: | 
|  | self.includes.add(x) | 
|  | self.sources = [] | 
|  | self.resources = [] | 
|  |  | 
|  | def _list_files(self): | 
|  | drain = deque() | 
|  | drain.extend(self.includes) | 
|  | while len(drain) > 0: | 
|  | target = drain.popleft() | 
|  | # Avoid circular dependencies | 
|  | if target in self.resources: | 
|  | continue | 
|  | if (target.startswith("dart:")): | 
|  | continue | 
|  | self.resources.append(target) | 
|  | if (target.endswith(".dart")): | 
|  | with open(os.path.join(self.base_directory,self.path,target),"r") as fobj: | 
|  | text = fobj.read() | 
|  | file_sources = re.findall(r"#source\(['\"](?P<name>.*)['\"]\);",text) | 
|  | file_native = re.findall(r"#native\(['\"](?P<name>.*)['\"]\);",text) | 
|  | file_imports = re.findall(r"#import\(['\"](?P<name>.*)['\"]\);",text) | 
|  | self.resources.extend(file_sources) | 
|  | self.resources.extend(file_native) | 
|  | drain.extend(file_imports) | 
|  | self.sources.sort() | 
|  | self.resources.sort() | 
|  |  | 
|  | def _print_gypi_files(self, out, name, files): | 
|  | out.write("    '%s': [\n" % name) | 
|  | for filename in files: | 
|  | out.write("      '%s/%s',\n" % (self.path, filename)) | 
|  | out.write("    ],\n") | 
|  |  | 
|  | def _print_ant_files(self, out, name, files): | 
|  | out.write("  <filelist id='%s' dir='%s'>\n" % (name, self.path)) | 
|  | for filename in files: | 
|  | out.write("    <file name='%s'/>\n" % filename) | 
|  | out.write("  </filelist>\n") | 
|  | out.write("  <pathconvert pathsep=',' property='%s' refid='%s'>\n" | 
|  | % (name, name)) | 
|  | out.write("    <map from='${basedir}/%s/' to=''/>\n" % self.path) | 
|  | out.write("  </pathconvert>\n") | 
|  |  | 
|  | def _make_output(self, file_name): | 
|  | if os.path.exists(file_name): | 
|  | return StringIO.StringIO() | 
|  | else: | 
|  | return file(file_name, 'w') | 
|  |  | 
|  | def _close(self, file_name, output): | 
|  | if not isinstance(output, StringIO.StringIO): | 
|  | output.close() | 
|  | return | 
|  | new_text = output.getvalue() | 
|  | output.close() | 
|  | with open(file_name, 'r') as f: | 
|  | old_text = f.read() | 
|  | if old_text == new_text: | 
|  | return | 
|  | sys.stderr.write('Updating %s\n' % file_name) | 
|  | with open(file_name, 'w') as f: | 
|  | f.write(new_text) | 
|  |  | 
|  | def generate(self): | 
|  | self._list_files() | 
|  | file_name = self.output + '.gypi'; | 
|  | gypi = self._make_output(file_name) | 
|  | gypi.write("{\n  'variables': {\n") | 
|  | self._print_gypi_files(gypi, self.name + '_sources', self.sources) | 
|  | self._print_gypi_files(gypi, self.name + '_resources', self.resources) | 
|  | gypi.write("  },\n}\n") | 
|  | self._close(file_name, gypi) | 
|  | file_name = self.output + '.xml' | 
|  | ant = self._make_output(file_name) | 
|  | ant.write("<project>\n") | 
|  | self._print_ant_files(ant, self.name + '_sources', self.sources) | 
|  | self._print_ant_files(ant, self.name + '_resources', self.resources) | 
|  | ant.write("</project>\n") | 
|  | self._close(file_name, ant) | 
|  |  | 
|  |  | 
|  | def Main(script_name = None, name = None, output = None, path = None, | 
|  | *rest): | 
|  | if not path: | 
|  | raise GenerateError("usage: %s NAME OUTPUT PATH EXCLUDE_DIR_NAME ..." | 
|  | % script_name) | 
|  | base_directory = os.path.dirname(output) | 
|  | Generator(base_directory, name, output, path, *rest).generate() | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | sys.exit(Main(*sys.argv)) |