mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 12:57:42 +00:00
Invoke copy_tree.py only once to collect all input file lists.
fixes #30105 R=rmacnak@google.com Review-Url: https://codereview.chromium.org/2992353002 .
This commit is contained in:
parent
bcaff5e269
commit
63b9312e1b
|
@ -10,11 +10,13 @@ _dart_root = rebase_path("..")
|
|||
# Optional parameters:
|
||||
# exclude - A comma separated list that is passed to shutil.ignore_patterns()
|
||||
# in tools/copy_tree.py.
|
||||
template("copy_tree") {
|
||||
template("_copy_tree") {
|
||||
assert(defined(invoker.source), "copy_tree must define 'source'")
|
||||
assert(defined(invoker.dest), "copy_tree must define 'dest'")
|
||||
assert(defined(invoker.inputs), "copy_tree must define 'inputs'")
|
||||
source = invoker.source
|
||||
dest = invoker.dest
|
||||
inputs = invoker.inputs
|
||||
action(target_name) {
|
||||
if (defined(invoker.visibility)) {
|
||||
visibility = invoker.visibility
|
||||
|
@ -38,12 +40,7 @@ template("copy_tree") {
|
|||
]
|
||||
}
|
||||
|
||||
dry_run_args = common_args + [ "--dry-run" ]
|
||||
input_files = exec_script("$_dart_root/tools/copy_tree.py",
|
||||
dry_run_args,
|
||||
"list lines")
|
||||
inputs = input_files
|
||||
relative_files = rebase_path(input_files, rebase_path(source))
|
||||
relative_files = rebase_path(inputs, rebase_path(source))
|
||||
|
||||
output_files = []
|
||||
foreach(input, relative_files) {
|
||||
|
@ -55,3 +52,54 @@ template("copy_tree") {
|
|||
args = common_args
|
||||
}
|
||||
}
|
||||
|
||||
# copy_trees() arranges to invoke copy_tree.py only once to gather the list of
|
||||
# input source files for every _copy_tree() target. It takes a list of scopes as
|
||||
# a parameter. The scopes should contain the following mappings.
|
||||
#
|
||||
# target: The target name for the _copy_tree() target.
|
||||
# visibility: The visibility for the _copy_tree() target.
|
||||
# source: The source directory relative to this directory.
|
||||
# dest: The destination directory for the _copy_tree() target.
|
||||
# deps: Any deps needed for the _copy_tree() target.
|
||||
# ignore_patterns: Patterns to ignore when walking the directory tree.
|
||||
# This should be '{}' if nothing should be ignored.
|
||||
#
|
||||
# copy_trees() will then make sure each invocation of _copy_tree() has the
|
||||
# correct 'inputs' parameter
|
||||
template("copy_trees") {
|
||||
assert(defined(invoker.sources), "$target_name must define 'source'")
|
||||
sources = invoker.sources
|
||||
copy_tree_source_paths = []
|
||||
foreach(copy_tree_spec, sources) {
|
||||
copy_tree_source_paths += [
|
||||
rebase_path(copy_tree_spec.source),
|
||||
copy_tree_spec.ignore_patterns
|
||||
]
|
||||
}
|
||||
|
||||
# Evaluate script output as GN, producing a scope containing a single value
|
||||
# "sources"
|
||||
copy_tree_inputs_scope = exec_script("$_dart_root/tools/copy_tree.py",
|
||||
["--gn"] + copy_tree_source_paths,
|
||||
"scope")
|
||||
|
||||
# A list of lists of input source files for copy_tree.
|
||||
copy_tree_inputs = copy_tree_inputs_scope.sources
|
||||
copy_tree_inputs_index = 0
|
||||
foreach(copy_tree_spec, sources) {
|
||||
_copy_tree(copy_tree_spec.target) {
|
||||
visibility = copy_tree_spec.visibility
|
||||
source = copy_tree_spec.source
|
||||
dest = copy_tree_spec.dest
|
||||
inputs = copy_tree_inputs[copy_tree_inputs_index]
|
||||
if (defined(copy_tree_spec.deps)) {
|
||||
deps = copy_tree_spec.deps
|
||||
}
|
||||
if (copy_tree_spec.ignore_patterns != "{}") {
|
||||
exclude = copy_tree_spec.ignore_patterns
|
||||
}
|
||||
}
|
||||
copy_tree_inputs_index = copy_tree_inputs_index + 1
|
||||
}
|
||||
}
|
||||
|
|
173
sdk/BUILD.gn
173
sdk/BUILD.gn
|
@ -210,6 +210,103 @@ _analyzer_source_dirs = [
|
|||
"kernel",
|
||||
]
|
||||
|
||||
# From here down to the copy_trees() invocation, we collect all the information
|
||||
# about trees that need to be copied in the list of scopes, copy_tree_specs.
|
||||
copy_tree_specs = []
|
||||
|
||||
# This loop generates rules for copying analyzer sources into lib/
|
||||
foreach(analyzer_source_dir, _analyzer_source_dirs) {
|
||||
copy_tree_specs += [{
|
||||
target = "copy_${analyzer_source_dir}_source_dir"
|
||||
visibility = [ ":copy_analyzer_sources" ]
|
||||
source = "../pkg/$analyzer_source_dir"
|
||||
dest = "$root_out_dir/dart-sdk/lib/$analyzer_source_dir"
|
||||
ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore,packages,test,testcases"
|
||||
}]
|
||||
}
|
||||
|
||||
# This rule copies dartdoc templates to
|
||||
# bin/snapshots/resources/dartdoc/templates
|
||||
copy_tree_specs += [{
|
||||
target = "copy_dartdoc_templates"
|
||||
visibility = [ ":copy_dartdoc_files" ]
|
||||
source = "../third_party/pkg/dartdoc/lib/templates"
|
||||
dest = "$root_out_dir/dart-sdk/bin/snapshots/resources/dartdoc/templates"
|
||||
ignore_patterns = "{}"
|
||||
}]
|
||||
|
||||
# This rule copies dartdoc resources to
|
||||
# bin/snapshots/resources/dartdoc/resources
|
||||
copy_tree_specs += [{
|
||||
target = "copy_dartdoc_resources"
|
||||
visibility = [ ":copy_dartdoc_files" ]
|
||||
source = "../third_party/pkg/dartdoc/lib/resources"
|
||||
dest = "$root_out_dir/dart-sdk/bin/snapshots/resources/dartdoc/resources"
|
||||
ignore_patterns = "{}"
|
||||
}]
|
||||
|
||||
# This rule copies js needed by ddc to lib/dev_compiler
|
||||
copy_tree_specs += [{
|
||||
target = "copy_dev_compiler_js"
|
||||
visibility = [
|
||||
":copy_dev_compiler_sdk",
|
||||
":copy_dev_compiler_require_js",
|
||||
":copy_dev_compiler_tools",
|
||||
]
|
||||
source = "../pkg/dev_compiler/lib/js"
|
||||
dest = "$root_out_dir/dart-sdk/lib/dev_compiler"
|
||||
ignore_patterns = "{}"
|
||||
}]
|
||||
|
||||
# This rule copies pub assets to lib/_internal/pub/asset
|
||||
copy_tree_specs += [{
|
||||
target = "copy_pub_assets"
|
||||
visibility = [
|
||||
":create_common_sdk",
|
||||
":copy_7zip",
|
||||
]
|
||||
deps = [
|
||||
":copy_libraries",
|
||||
]
|
||||
source = "../third_party/pkg/pub/lib/src/asset"
|
||||
dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset"
|
||||
ignore_patterns = "{}"
|
||||
}]
|
||||
|
||||
# This loop generates rules to copy libraries to lib/
|
||||
foreach(library, _full_sdk_libraries) {
|
||||
copy_tree_specs += [{
|
||||
target = "copy_${library}_library"
|
||||
visibility = [
|
||||
":copy_platform_sdk_libraries",
|
||||
":copy_full_sdk_libraries",
|
||||
]
|
||||
source = "lib/$library"
|
||||
dest = "$root_out_dir/dart-sdk/lib/$library"
|
||||
ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
|
||||
}]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
copy_tree_specs += [{
|
||||
target = "copy_7zip"
|
||||
visibility = [ ":create_common_sdk" ]
|
||||
deps = [
|
||||
":copy_libraries",
|
||||
":copy_pub_assets",
|
||||
]
|
||||
source = "../third_party/7zip"
|
||||
dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip"
|
||||
ignore_patterns = ".svn"
|
||||
}]
|
||||
}
|
||||
|
||||
# This generates targets for everything in copy_tree_specs. The targets have the
|
||||
# same name as the "target" fields in the scopes of copy_tree_specs.
|
||||
copy_trees("copy_trees") {
|
||||
sources = copy_tree_specs
|
||||
}
|
||||
|
||||
# Copies the Dart VM binary into bin/
|
||||
copy("copy_dart") {
|
||||
visibility = [ ":create_common_sdk" ]
|
||||
|
@ -372,16 +469,6 @@ group("copy_full_sdk_snapshots") {
|
|||
}
|
||||
}
|
||||
|
||||
# This loop generates rules for copying analyzer sources into lib/
|
||||
foreach(analyzer_source_dir, _analyzer_source_dirs) {
|
||||
copy_tree("copy_${analyzer_source_dir}_source_dir") {
|
||||
visibility = [ ":copy_analyzer_sources" ]
|
||||
source = "../pkg/$analyzer_source_dir"
|
||||
dest = "$root_out_dir/dart-sdk/lib/$analyzer_source_dir"
|
||||
exclude = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore,packages,test,testcases"
|
||||
}
|
||||
}
|
||||
|
||||
# This is the main rule for copying analyzer sources to lib/
|
||||
group("copy_analyzer_sources") {
|
||||
visibility = [ ":create_common_sdk" ]
|
||||
|
@ -391,22 +478,6 @@ group("copy_analyzer_sources") {
|
|||
}
|
||||
}
|
||||
|
||||
# This rule copies dartdoc templates to
|
||||
# bin/snapshots/resources/dartdoc/templates
|
||||
copy_tree("copy_dartdoc_templates") {
|
||||
visibility = [ ":copy_dartdoc_files" ]
|
||||
source = "../third_party/pkg/dartdoc/lib/templates"
|
||||
dest = "$root_out_dir/dart-sdk/bin/snapshots/resources/dartdoc/templates"
|
||||
}
|
||||
|
||||
# This rule copies dartdoc resources to
|
||||
# bin/snapshots/resources/dartdoc/resources
|
||||
copy_tree("copy_dartdoc_resources") {
|
||||
visibility = [ ":copy_dartdoc_files" ]
|
||||
source = "../third_party/pkg/dartdoc/lib/resources"
|
||||
dest = "$root_out_dir/dart-sdk/bin/snapshots/resources/dartdoc/resources"
|
||||
}
|
||||
|
||||
# This rule writes the .packages file for dartdoc resources.
|
||||
write_file("$root_out_dir/dart-sdk/bin/snapshots/resources/dartdoc/.packages",
|
||||
"dartdoc:.")
|
||||
|
@ -481,17 +552,6 @@ copy("copy_dev_compiler_summary") {
|
|||
]
|
||||
}
|
||||
|
||||
# This rule copies js needed by ddc to lib/dev_compiler
|
||||
copy_tree("copy_dev_compiler_js") {
|
||||
visibility = [
|
||||
":copy_dev_compiler_sdk",
|
||||
":copy_dev_compiler_require_js",
|
||||
":copy_dev_compiler_tools",
|
||||
]
|
||||
source = "../pkg/dev_compiler/lib/js"
|
||||
dest = "$root_out_dir/dart-sdk/lib/dev_compiler"
|
||||
}
|
||||
|
||||
# This rule copies require.js to lib/dev_compiler/amd
|
||||
copy("copy_dev_compiler_require_js") {
|
||||
visibility = [ ":copy_dev_compiler_sdk" ]
|
||||
|
@ -562,32 +622,6 @@ copy("copy_platform_files") {
|
|||
]
|
||||
}
|
||||
|
||||
# This rule copies pub assets to lib/_internal/pub/asset
|
||||
copy_tree("copy_pub_assets") {
|
||||
visibility = [
|
||||
":create_common_sdk",
|
||||
":copy_7zip",
|
||||
]
|
||||
deps = [
|
||||
":copy_libraries",
|
||||
]
|
||||
source = "../third_party/pkg/pub/lib/src/asset"
|
||||
dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset"
|
||||
}
|
||||
|
||||
# This loop generates rules to copy libraries to lib/
|
||||
foreach(library, _full_sdk_libraries) {
|
||||
copy_tree("copy_${library}_library") {
|
||||
visibility = [
|
||||
":copy_platform_sdk_libraries",
|
||||
":copy_full_sdk_libraries",
|
||||
]
|
||||
source = "lib/$library"
|
||||
dest = "$root_out_dir/dart-sdk/lib/$library"
|
||||
exclude = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
|
||||
}
|
||||
}
|
||||
|
||||
# This is the main rule to copy libraries in _platform_sdk_libraries to lib/
|
||||
group("copy_platform_sdk_libraries") {
|
||||
visibility = [
|
||||
|
@ -624,19 +658,6 @@ group("copy_libraries") {
|
|||
}
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
copy_tree("copy_7zip") {
|
||||
visibility = [ ":create_common_sdk" ]
|
||||
deps = [
|
||||
":copy_libraries",
|
||||
":copy_pub_assets",
|
||||
]
|
||||
source = "../third_party/7zip"
|
||||
dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip"
|
||||
exclude = ".svn"
|
||||
}
|
||||
}
|
||||
|
||||
# This rule writes the version file.
|
||||
action("write_version_file") {
|
||||
visibility = [ ":create_common_sdk" ]
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import argparse
|
||||
import gn_helpers
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
@ -14,43 +15,57 @@ def ParseArgs(args):
|
|||
parser = argparse.ArgumentParser(
|
||||
description='A script to copy a file tree somewhere')
|
||||
|
||||
parser.add_argument('--dry-run', '-d',
|
||||
dest='dryrun',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help='Print the paths of the source files, but do not copy anything.')
|
||||
parser.add_argument('--exclude_patterns', '-e',
|
||||
type=str,
|
||||
help='Patterns to exclude [passed to shutil.copytree]')
|
||||
parser.add_argument('--from', '-f',
|
||||
dest="copy_from",
|
||||
type=str,
|
||||
required=True,
|
||||
help='Source directory')
|
||||
parser.add_argument('--gn', '-g',
|
||||
dest='gn',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help='Output for GN for multiple sources, but do not copy anything.')
|
||||
parser.add_argument('gn_paths',
|
||||
metavar='name path ignore_pattern',
|
||||
type=str,
|
||||
nargs='*',
|
||||
default=None,
|
||||
help='When --gn is given, the specification of source paths to list.')
|
||||
parser.add_argument('--to', '-t',
|
||||
type=str,
|
||||
required=True,
|
||||
help='Destination directory')
|
||||
|
||||
return parser.parse_args(args)
|
||||
|
||||
|
||||
def ValidateArgs(args):
|
||||
if not os.path.isdir(args.copy_from):
|
||||
if args.gn:
|
||||
if args.exclude_patterns or args.copy_from or args.to:
|
||||
print "--gn mode does not accept other switches"
|
||||
return False
|
||||
if not args.gn_paths:
|
||||
print "--gn mode requires a list of source specifications"
|
||||
return False
|
||||
return True
|
||||
if not args.copy_from or not os.path.isdir(args.copy_from):
|
||||
print "--from argument must refer to a directory"
|
||||
return False
|
||||
if not args.to:
|
||||
print "--to is required"
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def CopyTree(src, dst, dryrun=False, symlinks=False, ignore=None):
|
||||
def CopyTree(src, dst, ignore=None):
|
||||
names = os.listdir(src)
|
||||
if ignore is not None:
|
||||
ignored_names = ignore(src, names)
|
||||
else:
|
||||
ignored_names = set()
|
||||
|
||||
if not dryrun:
|
||||
os.makedirs(dst)
|
||||
os.makedirs(dst)
|
||||
errors = []
|
||||
for name in names:
|
||||
if name in ignored_names:
|
||||
|
@ -59,12 +74,9 @@ def CopyTree(src, dst, dryrun=False, symlinks=False, ignore=None):
|
|||
dstname = os.path.join(dst, name)
|
||||
try:
|
||||
if os.path.isdir(srcname):
|
||||
CopyTree(srcname, dstname, dryrun, symlinks, ignore)
|
||||
CopyTree(srcname, dstname, ignore)
|
||||
else:
|
||||
if dryrun:
|
||||
print srcname
|
||||
else:
|
||||
shutil.copy(srcname, dstname)
|
||||
shutil.copy(srcname, dstname)
|
||||
except (IOError, os.error) as why:
|
||||
errors.append((srcname, dstname, str(why)))
|
||||
# catch the Error from the recursive CopyTree so that we can
|
||||
|
@ -72,8 +84,7 @@ def CopyTree(src, dst, dryrun=False, symlinks=False, ignore=None):
|
|||
except Error as err:
|
||||
errors.extend(err.args[0])
|
||||
try:
|
||||
if not dryrun:
|
||||
shutil.copystat(src, dst)
|
||||
shutil.copystat(src, dst)
|
||||
except WindowsError:
|
||||
# can't copy file access times on Windows
|
||||
pass
|
||||
|
@ -83,19 +94,62 @@ def CopyTree(src, dst, dryrun=False, symlinks=False, ignore=None):
|
|||
raise Error(errors)
|
||||
|
||||
|
||||
def ListTree(src, ignore=None):
|
||||
names = os.listdir(src)
|
||||
if ignore is not None:
|
||||
ignored_names = ignore(src, names)
|
||||
else:
|
||||
ignored_names = set()
|
||||
|
||||
srcnames = []
|
||||
for name in names:
|
||||
if name in ignored_names:
|
||||
continue
|
||||
srcname = os.path.join(src, name)
|
||||
if os.path.isdir(srcname):
|
||||
srcnames.extend(ListTree(srcname, ignore))
|
||||
else:
|
||||
srcnames.append(srcname)
|
||||
return srcnames
|
||||
|
||||
|
||||
# source_dirs is organized such that sources_dirs[n] is the path for the source
|
||||
# directory, and source_dirs[n+1] is a list of ignore patterns.
|
||||
def SourcesToGN(source_dirs):
|
||||
if len(source_dirs) % 2 != 0:
|
||||
print "--gn list length should be a multiple of 2."
|
||||
return False
|
||||
data = []
|
||||
for i in xrange(0, len(source_dirs), 2):
|
||||
path = source_dirs[i]
|
||||
ignores = source_dirs[i + 1]
|
||||
if ignores in ["{}"]:
|
||||
sources = ListTree(path)
|
||||
else:
|
||||
patterns = ignores.split(',')
|
||||
sources = ListTree(path, ignore=shutil.ignore_patterns(*patterns))
|
||||
data.append(sources)
|
||||
scope_data = {"sources": data}
|
||||
print gn_helpers.ToGNString(scope_data)
|
||||
return True
|
||||
|
||||
|
||||
def Main(argv):
|
||||
args = ParseArgs(argv)
|
||||
if not ValidateArgs(args):
|
||||
return -1
|
||||
|
||||
if os.path.exists(args.to) and not args.dryrun:
|
||||
if args.gn:
|
||||
SourcesToGN(args.gn_paths)
|
||||
return 0
|
||||
|
||||
if os.path.exists(args.to):
|
||||
shutil.rmtree(args.to)
|
||||
if args.exclude_patterns == None:
|
||||
CopyTree(args.copy_from, args.to, dryrun=args.dryrun)
|
||||
CopyTree(args.copy_from, args.to)
|
||||
else:
|
||||
patterns = args.exclude_patterns.split(',')
|
||||
CopyTree(args.copy_from, args.to, dryrun=args.dryrun,
|
||||
ignore=shutil.ignore_patterns(*patterns))
|
||||
CopyTree(args.copy_from, args.to, ignore=shutil.ignore_patterns(*patterns))
|
||||
return 0
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue