2 # Copyright 2012 The Chromium Authors
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Copies test data files or directories into a given output directory."""
14 class WrongNumberOfArgumentsException(Exception):
18 """Returns a path with spaces escaped."""
19 return path.replace(" ", "\\ ")
21 def ListFilesForPath(path):
22 """Returns a list of all the files under a given path."""
24 # Ignore revision control metadata directories.
25 if (os.path.basename(path).startswith('.git') or
26 os.path.basename(path).startswith('.svn')):
29 # Files get returned without modification.
30 if not os.path.isdir(path):
34 # Directories get recursively expanded.
35 contents = os.listdir(path)
37 full_path = os.path.join(path, item)
38 output.extend(ListFilesForPath(full_path))
41 def CalcInputs(inputs):
42 """Computes the full list of input files for a set of command-line arguments.
44 # |inputs| is a list of paths, which may be directories.
47 output.extend(ListFilesForPath(input))
50 def CopyFiles(relative_filenames, output_basedir):
51 """Copies files to the given output directory."""
52 for file in relative_filenames:
53 relative_dirname = os.path.dirname(file)
54 output_dir = os.path.join(output_basedir, relative_dirname)
55 output_filename = os.path.join(output_basedir, file)
57 # In cases where a directory has turned into a file or vice versa, delete it
58 # before copying it below.
59 if os.path.exists(output_dir) and not os.path.isdir(output_dir):
61 if os.path.exists(output_filename) and os.path.isdir(output_filename):
62 shutil.rmtree(output_filename)
64 if not os.path.exists(output_dir):
65 os.makedirs(output_dir)
66 shutil.copy(file, output_filename)
69 parser = optparse.OptionParser()
70 usage = 'Usage: %prog -o <output_dir> [--inputs] [--outputs] <input_files>'
71 parser.set_usage(usage)
72 parser.add_option('-o', dest='output_dir')
73 parser.add_option('--inputs', action='store_true', dest='list_inputs')
74 parser.add_option('--outputs', action='store_true', dest='list_outputs')
75 options, arglist = parser.parse_args(argv)
78 raise WrongNumberOfArgumentsException('<input_files> required.')
80 files_to_copy = CalcInputs(arglist)
81 escaped_files = [EscapePath(x) for x in CalcInputs(arglist)]
82 if options.list_inputs:
83 return '\n'.join(escaped_files)
85 if not options.output_dir:
86 raise WrongNumberOfArgumentsException('-o required.')
88 if options.list_outputs:
89 outputs = [os.path.join(options.output_dir, x) for x in escaped_files]
90 return '\n'.join(outputs)
92 CopyFiles(files_to_copy, options.output_dir)
97 result = DoMain(argv[1:])
98 except WrongNumberOfArgumentsException as e:
99 print(e, file=sys.stderr)
105 if __name__ == '__main__':
106 sys.exit(main(sys.argv))