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 |