| Index: tools/copy_tree.py
|
| diff --git a/tools/copy_tree.py b/tools/copy_tree.py
|
| index 6e524713aa641d7a9da68a424479379ad984d0fc..893fcc1082c3ee4de1461b1b84c02af889b0cdc7 100755
|
| --- a/tools/copy_tree.py
|
| +++ b/tools/copy_tree.py
|
| @@ -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
|
|
|
|
|
|
|