tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

copy_ex.py (4103B)


      1 #!/usr/bin/env python3
      2 #
      3 # Copyright 2014 The Chromium Authors
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 """Copies files to a directory."""
      8 
      9 
     10 import filecmp
     11 import itertools
     12 import optparse
     13 import os
     14 import shutil
     15 import sys
     16 
     17 from util import build_utils
     18 import action_helpers  # build_utils adds //build to sys.path.
     19 
     20 
     21 def _get_all_files(base):
     22  """Returns a list of all the files in |base|. Each entry is relative to the
     23  last path entry of |base|."""
     24  result = []
     25  dirname = os.path.dirname(base)
     26  for root, _, files in os.walk(base):
     27    result.extend([os.path.join(root[len(dirname):], f) for f in files])
     28  return result
     29 
     30 def CopyFile(f, dest, deps):
     31  """Copy file or directory and update deps."""
     32  if os.path.isdir(f):
     33    shutil.copytree(f, os.path.join(dest, os.path.basename(f)))
     34    deps.extend(_get_all_files(f))
     35  else:
     36    if os.path.isfile(os.path.join(dest, os.path.basename(f))):
     37      dest = os.path.join(dest, os.path.basename(f))
     38 
     39    deps.append(f)
     40 
     41    if os.path.isfile(dest):
     42      if filecmp.cmp(dest, f, shallow=False):
     43        return
     44      # The shutil.copy() below would fail if the file does not have write
     45      # permissions. Deleting the file has similar costs to modifying the
     46      # permissions.
     47      os.unlink(dest)
     48 
     49    shutil.copy(f, dest)
     50 
     51 def DoCopy(options, deps):
     52  """Copy files or directories given in options.files and update deps."""
     53  files = list(
     54      itertools.chain.from_iterable(
     55          action_helpers.parse_gn_list(f) for f in options.files))
     56 
     57  for f in files:
     58    if os.path.isdir(f) and not options.clear:
     59      print('To avoid stale files you must use --clear when copying '
     60            'directories')
     61      sys.exit(-1)
     62    CopyFile(f, options.dest, deps)
     63 
     64 def DoRenaming(options, deps):
     65  """Copy and rename files given in options.renaming_sources and update deps."""
     66  src_files = list(
     67      itertools.chain.from_iterable(
     68          action_helpers.parse_gn_list(f) for f in options.renaming_sources))
     69 
     70  dest_files = list(
     71      itertools.chain.from_iterable(
     72          action_helpers.parse_gn_list(f)
     73          for f in options.renaming_destinations))
     74 
     75  if (len(src_files) != len(dest_files)):
     76    print('Renaming source and destination files not match.')
     77    sys.exit(-1)
     78 
     79  for src, dest in zip(src_files, dest_files):
     80    if os.path.isdir(src):
     81      print('renaming diretory is not supported.')
     82      sys.exit(-1)
     83    else:
     84      CopyFile(src, os.path.join(options.dest, dest), deps)
     85 
     86 def main(args):
     87  args = build_utils.ExpandFileArgs(args)
     88 
     89  parser = optparse.OptionParser()
     90  action_helpers.add_depfile_arg(parser)
     91 
     92  parser.add_option('--dest', help='Directory to copy files to.')
     93  parser.add_option('--files', action='append',
     94                    help='List of files to copy.')
     95  parser.add_option('--clear', action='store_true',
     96                    help='If set, the destination directory will be deleted '
     97                    'before copying files to it. This is highly recommended to '
     98                    'ensure that no stale files are left in the directory.')
     99  parser.add_option('--stamp', help='Path to touch on success.')
    100  parser.add_option('--renaming-sources',
    101                    action='append',
    102                    help='List of files need to be renamed while being '
    103                         'copied to dest directory')
    104  parser.add_option('--renaming-destinations',
    105                    action='append',
    106                    help='List of destination file name without path, the '
    107                         'number of elements must match rename-sources.')
    108 
    109  options, _ = parser.parse_args(args)
    110 
    111  if options.clear:
    112    build_utils.DeleteDirectory(options.dest)
    113    build_utils.MakeDirectory(options.dest)
    114 
    115  deps = []
    116 
    117  if options.files:
    118    DoCopy(options, deps)
    119 
    120  if options.renaming_sources:
    121    DoRenaming(options, deps)
    122 
    123  if options.depfile:
    124    action_helpers.write_depfile(options.depfile, options.stamp, deps)
    125 
    126  if options.stamp:
    127    build_utils.Touch(options.stamp)
    128 
    129 
    130 if __name__ == '__main__':
    131  sys.exit(main(sys.argv[1:]))