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