#!/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.*)['\"]\);",text) file_native = re.findall(r"#native\(['\"](?P.*)['\"]\);",text) file_imports = re.findall(r"#import\(['\"](?P.*)['\"]\);",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(" \n" % (name, self.path)) for filename in files: out.write(" \n" % filename) out.write(" \n") out.write(" \n" % (name, name)) out.write(" \n" % self.path) out.write(" \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("\n") self._print_ant_files(ant, self.name + '_sources', self.sources) self._print_ant_files(ant, self.name + '_resources', self.resources) ant.write("\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))