text: #!/usr/bin/python
  #
  # Copyright 2011 Google Inc. All Rights Reserved.
  """Script to divide and merge profiles."""
  
  import copy
  import optparse
  import os
  import pickle
  import re
  import sys
  import tempfile
  
  import build_chrome_browser
  import lock_machine
  import run_tests
  from cros_utils import command_executer
  from cros_utils import logger
  
  
  class ProfileMerger:
  
    def __init__(self, inputs, output, chunk_size, merge_program, multipliers):
      self._inputs = inputs
      self._output = output
      self._chunk_size = chunk_size
      self._merge_program = merge_program
      self._multipliers = multipliers
      self._ce = command_executer.GetCommandExecuter()
      self._l = logger.GetLogger()
  
    def _GetFilesSetForInputDir(self, input_dir):
      output_file = tempfile.mktemp()
      command = "find %s -name '*.gcda' -o -name '*.imports' > %s" % (input_dir,
                                                                      output_file)
      self._ce.RunCommand(command)
      files = open(output_file, 'r').read()
      files_set = set([])
      for f in files.splitlines():
        stripped_file = f.replace(input_dir, '', 1)
        stripped_file = stripped_file.lstrip('/')
        files_set.add(stripped_file)
      return files_set
  
    def _PopulateFilesSet(self):
      self._files_set = set([])
      for i in self._inputs:
        current_files_set = self._GetFilesSetForInputDir(i)
        self._files_set.update(current_files_set)
  
    def _GetSubset(self):
      ret = []
      for i in range(self._chunk_size):
        if not self._files_set:
          break
        ret.append(self._files_set.pop())
      return ret
  
    def _CopyFilesTree(self, input_dir, files, output_dir):
      for f in files:
        src_file = os.path.join(input_dir, f)
        dst_file = os.path.join(output_dir, f)
        if not os.path.isdir(os.path.dirname(dst_file)):
          command = 'mkdir -p %s' % os.path.dirname(dst_file)
          self._ce.RunCommand(command)
        command = 'cp %s %s' % (src_file, dst_file)
        self._ce.RunCommand(command)
  
    def _DoChunkMerge(self, current_files):
      temp_dirs = []
      for i in self._inputs:
        temp_dir = tempfile.mkdtemp()
        temp_dirs.append(temp_dir)
        self._CopyFilesTree(i, current_files, temp_dir)
      # Now do the merge.
      command = ('%s --inputs=%s --output=%s' %
                 (self._merge_program, ','.join(temp_dirs), self._output))
      if self._multipliers:
        command = ('%s --multipliers=%s' % (command, self._multipliers))
      ret = self._ce.RunCommand(command)
      assert ret == 0, '%s command failed!' % command
      for temp_dir in temp_dirs:
        command = 'rm -rf %s' % temp_dir
        self._ce.RunCommand(command)
  
    def DoMerge(self):
      self._PopulateFilesSet()
      while True:
        current_files = self._GetSubset()
        if not current_files:
          break
        self._DoChunkMerge(current_files)
  
  
  def Main(argv):
    """The main function."""
    # Common initializations
    ###  command_executer.InitCommandExecuter(True)
    command_executer.InitCommandExecuter()
    l = logger.GetLogger()
    ce = command_executer.GetCommandExecuter()
    parser = optparse.OptionParser()
    parser.add_option('--inputs',
                      dest='inputs',
                      help='Comma-separated input profile directories to merge.')
    parser.add_option('--output', dest='output', help='Output profile directory.')
    parser.add_option('--chunk_size',
                      dest='chunk_size',
                      default='50',
                      help='Chunk size to divide up the profiles into.')
    parser.add_option('--merge_program',
                      dest='merge_program',
                      default='/home/xur/bin/profile_merge_v15.par',
                      help='Merge program to use to do the actual merge.')
    parser.add_option('--multipliers',
                      dest='multipliers',
                      help='multipliers to use when merging. (optional)')
  
    options, _ = parser.parse_args(argv)
  
    if not all([options.inputs, options.output]):
      l.LogError('Must supply --inputs and --output')
      return 1
  
    try:
      pm = ProfileMerger(
          options.inputs.split(','), options.output, int(options.chunk_size),
          options.merge_program, options.multipliers)
      pm.DoMerge()
      retval = 0
    except:
      retval = 1
    finally:
      print 'My work is done...'
    return retval
  
  
  if __name__ == '__main__':
    retval = Main(sys.argv)
    sys.exit(retval)
  