blob: 1754436296568d988e02a4a852c36dafa22e33a5 [file] [log] [blame]
#!/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))