You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
box-o-sand/mktargets.py

156 lines
4.8 KiB

#!/usr/bin/env python
from __future__ import print_function
import os
import re
import sys
import glob
from fnmatch import fnmatch
from itertools import ifilter
from os.path import join as pathjoin, relpath, dirname, \
abspath, basename, splitext, sep as pathsep
HERE = dirname(abspath(__file__))
AUTOGEN_WARNING = ('# ******** AUTOGENERATED by {0} ' +
('*' * 20)).format(basename(sys.argv[0]))
DEP_SEP = ' \\\n '
RULE_SEP = '\n\n'
TARGET_FMT = '{target}:' + DEP_SEP + '{deps}'
RULE_FMT = '\\\n\t'.join([
'\t$(MXMLC) {primary_dep} ',
'$(MXMLC_FLAGS) -l+={parent_dir} ',
'-l+={package_base} -o {target}',
])
def main(sysargs=sys.argv[:]):
targets_mk = pathjoin(HERE, 'targets.mk')
os.chmod(targets_mk, 0600)
targetmaker = TargetMaker(outstream=open(targets_mk, 'wb'))
targetmaker.make()
os.chmod(targets_mk, 0444)
return 0
class TargetMaker(object):
_to_glob = (
pathjoin(HERE, '[0-9]*-*', '*.mxml'),
pathjoin(HERE, 'custom-*', '*.mxml'),
)
_source_fileexts = ('.mxml', '.as', '.css')
def __init__(self, outstream=sys.stdout):
self.outstream = outstream
self.targets = {}
def make(self):
self._glob_for_top_level_mxml_targets()
self._find_test_class_targets()
self._write_out_targets()
def _glob_for_top_level_mxml_targets(self):
for pattern in self._to_glob:
for mxml in glob.glob(pattern):
self._add_target_from_mxml(mxml)
def _find_test_class_targets(self):
for dirpath, dirnames, filenames in os.walk(HERE):
filter_generated_dirs(dirnames)
for filename in filenames:
if is_test_class(filename):
test_class = pathjoin(dirpath, filename)
self._add_target_from_test_class(test_class)
def _add_target_from_test_class(self, test_class):
rel_class = relpath(test_class, HERE)
as_swf = re.sub('(.*)\.as$', '\\1.swf', rel_class)
self.targets[as_swf] = set([rel_class])
def _add_target_from_mxml(self, mxml):
rel_mxml = relpath(mxml, HERE)
as_swf = re.sub('(.*)\.mxml$', '\\1.swf', rel_mxml)
self.targets[as_swf] = set([rel_mxml])
self._add_deps_from_alt_source_file_extensions(as_swf, rel_mxml)
def _add_deps_from_alt_source_file_extensions(self, as_swf, rel_mxml):
basedir = dirname(rel_mxml)
for dirpath, dirnames, filenames in os.walk(basedir):
filter_generated_dirs(dirnames)
filter_test_classes(filenames)
for filename in filenames:
if ext(filename) in self._source_fileexts:
rel_source = relpath(pathjoin(dirpath, filename), HERE)
self.targets[as_swf].add(rel_source)
def _write_out_targets(self):
print(AUTOGEN_WARNING, file=self.outstream)
for target in sorted(self.targets.iterkeys()):
deps = self._get_deps_for_target(target)
primary_dep = self._get_primary_dep(target, deps)
pattern_rule_kwargs = \
self._get_pattern_rule_kwargs(primary_dep, target)
print(TARGET_FMT.format(target=target,
deps=DEP_SEP.join(deps)), file=self.outstream)
print(RULE_FMT.format(**pattern_rule_kwargs) +
RULE_SEP, file=self.outstream)
def _get_deps_for_target(self, target):
deps = []
for dep in reversed(sorted(list(self.targets[target]), key=ext)):
deps.append(dep)
return deps
def _get_primary_dep(self, target, deps):
primary_dep = deps[0]
for dependency in deps:
if fnmatch(target, namebase(dependency) + '.*'):
primary_dep = dependency
return primary_dep
def _get_pattern_rule_kwargs(self, primary_dep, target):
ret = dict(
primary_dep=primary_dep,
parent_dir=dirname(primary_dep),
package_base=primary_dep.strip('./').split(pathsep)[0],
target=target
)
return ret
def ext(filename):
return splitext(filename)[-1]
def namebase(filename):
return splitext(filename)[0]
def filter_generated_dirs(dirnames):
for i, directory in enumerate(dirnames[:]):
if directory == 'generated':
dirnames[i] = None
dirnames[:] = list(ifilter(None, dirnames))
def filter_test_classes(filenames):
for i, filename in enumerate(filenames[:]):
if is_test_class(filename):
filenames[i] = None
filenames[:] = list(ifilter(None, filenames))
def is_test_class(filename):
base_filename = basename(filename)
return base_filename.startswith('Test') and \
ext(filename) == '.as'
if __name__ == '__main__':
sys.exit(main())
# vim:filetype=python