2021-04-15 10:10:20 +00:00
|
|
|
#!/usr/bin/env python3
|
2011-10-05 04:52:33 +00:00
|
|
|
# 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.
|
|
|
|
"""Used to merge and copy dart source files for deployment to AppEngine"""
|
|
|
|
|
|
|
|
import fileinput
|
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
import re
|
2014-07-25 11:47:59 +00:00
|
|
|
from os.path import basename, dirname, exists, isabs, join
|
2011-10-05 04:52:33 +00:00
|
|
|
from glob import glob
|
|
|
|
|
2019-08-05 20:34:31 +00:00
|
|
|
re_directive = re.compile(r'^(library|import|part|native|resource)\s+(.*);$')
|
|
|
|
re_comment = re.compile(r'^(///|/\*| \*).*$')
|
|
|
|
|
2011-10-05 04:52:33 +00:00
|
|
|
|
|
|
|
class Library(object):
|
2019-08-05 20:34:31 +00:00
|
|
|
|
|
|
|
def __init__(self, name, imports, sources, natives, code, comment):
|
|
|
|
self.name = name
|
|
|
|
self.imports = imports
|
|
|
|
self.sources = sources
|
|
|
|
self.natives = natives
|
|
|
|
self.code = code
|
|
|
|
self.comment = comment
|
|
|
|
|
2011-10-05 04:52:33 +00:00
|
|
|
|
|
|
|
def parseLibrary(library):
|
2019-08-05 20:34:31 +00:00
|
|
|
""" Parses a .dart source file that is the root of a library, and returns
|
2011-10-05 04:52:33 +00:00
|
|
|
information about it: the name, the imports, included sources, and any
|
|
|
|
code in the file.
|
|
|
|
"""
|
2019-08-05 20:34:31 +00:00
|
|
|
libraryname = None
|
|
|
|
imports = []
|
|
|
|
sources = []
|
|
|
|
natives = []
|
|
|
|
inlinecode = []
|
|
|
|
librarycomment = []
|
|
|
|
if exists(library):
|
|
|
|
# TODO(sigmund): stop parsing when import/source
|
|
|
|
for line in fileinput.input(library):
|
|
|
|
match = re_directive.match(line)
|
|
|
|
if match:
|
|
|
|
directive = match.group(1)
|
|
|
|
if directive == 'library':
|
|
|
|
assert libraryname is None
|
|
|
|
libraryname = match.group(2)
|
|
|
|
elif directive == 'part':
|
|
|
|
suffix = match.group(2)
|
|
|
|
if not suffix.startswith('of '):
|
|
|
|
sources.append(match.group(2).strip('"\''))
|
|
|
|
elif directive == 'import':
|
|
|
|
imports.append(match.group(2))
|
|
|
|
else:
|
|
|
|
raise Exception(
|
|
|
|
'unknown directive %s in %s' % (directive, line))
|
|
|
|
else:
|
|
|
|
# Check for library comment.
|
|
|
|
if not libraryname and re_comment.match(line):
|
|
|
|
librarycomment.append(line)
|
|
|
|
else:
|
|
|
|
inlinecode.append(line)
|
|
|
|
fileinput.close()
|
|
|
|
return Library(libraryname, imports, sources, natives, inlinecode,
|
|
|
|
librarycomment)
|
|
|
|
|
2011-10-05 04:52:33 +00:00
|
|
|
|
|
|
|
def normjoin(*args):
|
2019-08-05 20:34:31 +00:00
|
|
|
return os.path.normpath(os.path.join(*args))
|
|
|
|
|
2011-10-05 04:52:33 +00:00
|
|
|
|
|
|
|
def mergefiles(srcs, dstfile):
|
2019-08-05 20:34:31 +00:00
|
|
|
for src in srcs:
|
|
|
|
with open(src, 'r') as s:
|
|
|
|
for line in s:
|
|
|
|
if not line.startswith('part of '):
|
|
|
|
dstfile.write(line)
|
|
|
|
|
|
|
|
|
|
|
|
def main(outdir=None, *inputs):
|
|
|
|
if not outdir or not inputs:
|
2021-04-15 10:10:20 +00:00
|
|
|
print("""Usage: %s OUTDIR INPUTS
|
|
|
|
OUTDIR is the war directory to copy to
|
|
|
|
INPUTS is a list of files or patterns used to specify the input
|
|
|
|
.dart files
|
|
|
|
This script should be run from the client root directory.
|
|
|
|
Files will be merged and copied to: OUTDIR/relative-path-of-file,
|
|
|
|
except for dart files with absolute paths, which will be copied to
|
|
|
|
OUTDIR/absolute-path-as-directories""" % sys.argv[0])
|
2019-08-05 20:34:31 +00:00
|
|
|
return 1
|
|
|
|
|
|
|
|
entry_libraries = []
|
|
|
|
for i in inputs:
|
|
|
|
entry_libraries.extend(glob(i))
|
|
|
|
|
|
|
|
for entrypoint in entry_libraries:
|
|
|
|
# Get the transitive set of dart files this entrypoint depends on, merging
|
|
|
|
# each library along the way.
|
|
|
|
worklist = [os.path.normpath(entrypoint)]
|
|
|
|
seen = set()
|
|
|
|
while len(worklist) > 0:
|
|
|
|
lib = worklist.pop()
|
|
|
|
if lib in seen:
|
|
|
|
continue
|
|
|
|
|
|
|
|
seen.add(lib)
|
|
|
|
|
|
|
|
if (dirname(dirname(lib)).endswith('dom/generated/src') or
|
|
|
|
dirname(lib).endswith('dom/src')):
|
|
|
|
continue
|
|
|
|
|
|
|
|
library = parseLibrary(lib)
|
|
|
|
|
|
|
|
# Ensure output directory exists
|
|
|
|
outpath = join(outdir, lib[1:] if isabs(lib) else lib)
|
|
|
|
dstpath = dirname(outpath)
|
|
|
|
if not exists(dstpath):
|
|
|
|
os.makedirs(dstpath)
|
|
|
|
|
|
|
|
# Create file containing all imports, and inlining all sources
|
|
|
|
with open(outpath, 'w') as f:
|
2019-11-06 23:59:33 +00:00
|
|
|
prefix = os.environ.get('DART_HTML_PREFIX')
|
|
|
|
if prefix:
|
|
|
|
f.write(prefix + '\n')
|
2019-08-05 20:34:31 +00:00
|
|
|
if library.name:
|
|
|
|
if library.comment:
|
|
|
|
f.write('%s' % (''.join(library.comment)))
|
|
|
|
f.write("library %s;\n\n" % library.name)
|
|
|
|
else:
|
|
|
|
f.write("library %s;\n\n" % basename(lib))
|
|
|
|
for importfile in library.imports:
|
|
|
|
f.write("import %s;\n" % importfile)
|
|
|
|
f.write('%s' % (''.join(library.code)))
|
|
|
|
mergefiles([normjoin(dirname(lib), s) for s in library.sources],
|
|
|
|
f)
|
|
|
|
|
|
|
|
for suffix in library.imports:
|
|
|
|
m = re.match(r'[\'"]([^\'"]+)[\'"](\s+as\s+\w+)?.*$', suffix)
|
|
|
|
uri = m.group(1)
|
|
|
|
if not uri.startswith('dart:'):
|
|
|
|
worklist.append(normjoin(dirname(lib), uri))
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
2011-10-05 04:52:33 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2019-08-05 20:34:31 +00:00
|
|
|
sys.exit(main(*sys.argv[1:]))
|