| #!/usr/bin/env python | 
 | # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 | # Use of this source code is governed by a BSD-style license that can be | 
 | # found in the LICENSE file. | 
 |  | 
 | """Copies test data files or directories into a given output directory.""" | 
 |  | 
 | import optparse | 
 | import os | 
 | import shutil | 
 | import sys | 
 |  | 
 | class WrongNumberOfArgumentsException(Exception): | 
 |   pass | 
 |  | 
 | def EscapePath(path): | 
 |   """Returns a path with spaces escaped.""" | 
 |   return path.replace(" ", "\\ ") | 
 |  | 
 | def ListFilesForPath(path): | 
 |   """Returns a list of all the files under a given path.""" | 
 |   output = [] | 
 |   # Ignore revision control metadata directories. | 
 |   if (os.path.basename(path).startswith('.git') or | 
 |       os.path.basename(path).startswith('.svn')): | 
 |     return output | 
 |  | 
 |   # Files get returned without modification. | 
 |   if not os.path.isdir(path): | 
 |     output.append(path) | 
 |     return output | 
 |  | 
 |   # Directories get recursively expanded. | 
 |   contents = os.listdir(path) | 
 |   for item in contents: | 
 |     full_path = os.path.join(path, item) | 
 |     output.extend(ListFilesForPath(full_path)) | 
 |   return output | 
 |  | 
 | def CalcInputs(inputs): | 
 |   """Computes the full list of input files for a set of command-line arguments. | 
 |   """ | 
 |   # |inputs| is a list of paths, which may be directories. | 
 |   output = [] | 
 |   for input in inputs: | 
 |     output.extend(ListFilesForPath(input)) | 
 |   return output | 
 |  | 
 | def CopyFiles(relative_filenames, output_basedir): | 
 |   """Copies files to the given output directory.""" | 
 |   for file in relative_filenames: | 
 |     relative_dirname = os.path.dirname(file) | 
 |     output_dir = os.path.join(output_basedir, relative_dirname) | 
 |     output_filename = os.path.join(output_basedir, file) | 
 |  | 
 |     # In cases where a directory has turned into a file or vice versa, delete it | 
 |     # before copying it below. | 
 |     if os.path.exists(output_dir) and not os.path.isdir(output_dir): | 
 |       os.remove(output_dir) | 
 |     if os.path.exists(output_filename) and os.path.isdir(output_filename): | 
 |       shutil.rmtree(output_filename) | 
 |  | 
 |     if not os.path.exists(output_dir): | 
 |       os.makedirs(output_dir) | 
 |     shutil.copy(file, output_filename) | 
 |  | 
 | def DoMain(argv): | 
 |   parser = optparse.OptionParser() | 
 |   usage = 'Usage: %prog -o <output_dir> [--inputs] [--outputs] <input_files>' | 
 |   parser.set_usage(usage) | 
 |   parser.add_option('-o', dest='output_dir') | 
 |   parser.add_option('--inputs', action='store_true', dest='list_inputs') | 
 |   parser.add_option('--outputs', action='store_true', dest='list_outputs') | 
 |   options, arglist = parser.parse_args(argv) | 
 |  | 
 |   if len(arglist) == 0: | 
 |     raise WrongNumberOfArgumentsException('<input_files> required.') | 
 |  | 
 |   files_to_copy = CalcInputs(arglist) | 
 |   escaped_files = [EscapePath(x) for x in CalcInputs(arglist)] | 
 |   if options.list_inputs: | 
 |     return '\n'.join(escaped_files) | 
 |  | 
 |   if not options.output_dir: | 
 |     raise WrongNumberOfArgumentsException('-o required.') | 
 |  | 
 |   if options.list_outputs: | 
 |     outputs = [os.path.join(options.output_dir, x) for x in escaped_files] | 
 |     return '\n'.join(outputs) | 
 |  | 
 |   CopyFiles(files_to_copy, options.output_dir) | 
 |   return | 
 |  | 
 | def main(argv): | 
 |   try: | 
 |     result = DoMain(argv[1:]) | 
 |   except WrongNumberOfArgumentsException, e: | 
 |     print >>sys.stderr, e | 
 |     return 1 | 
 |   if result: | 
 |     print result | 
 |   return 0 | 
 |  | 
 | if __name__ == '__main__': | 
 |   sys.exit(main(sys.argv)) |