fs_tools.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. from __future__ import print_function
  2. import os
  3. import platform
  4. import sys
  5. import shutil
  6. import errno
  7. # Explicitly enable local imports
  8. # Don't forget to add imported scripts to inputs of the calling command!
  9. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  10. import process_command_files as pcf
  11. def link_or_copy(src, dst, trace={}):
  12. if dst not in trace:
  13. trace[dst] = src
  14. try:
  15. if platform.system().lower() == 'windows':
  16. shutil.copy(src, dst)
  17. else:
  18. os.link(src, dst)
  19. except OSError as e:
  20. if e.errno == errno.EEXIST:
  21. if dst in trace:
  22. print(
  23. '[[bad]]link_or_copy: copy collision found - tried to copy {} to {} which was copied earlier from {}[[rst]]'.format(
  24. src, dst, trace[dst]
  25. ),
  26. file=sys.stderr,
  27. )
  28. else:
  29. print('[[bad]]link_or_copy: destination file already exists: {}[[rst]]'.format(dst), file=sys.stderr)
  30. if e.errno == errno.ENOENT:
  31. print('[[bad]]link_or_copy: source file doesn\'t exists: {}[[rst]]'.format(src), file=sys.stderr)
  32. raise
  33. if __name__ == '__main__':
  34. mode = sys.argv[1]
  35. args = pcf.get_args(sys.argv[2:])
  36. if mode == 'copy':
  37. shutil.copy(args[0], args[1])
  38. elif mode == 'copy_tree_no_link':
  39. dst = args[1]
  40. shutil.copytree(
  41. args[0], dst, ignore=lambda dirname, names: [n for n in names if os.path.islink(os.path.join(dirname, n))]
  42. )
  43. elif mode == 'copy_files':
  44. src = args[0]
  45. dst = args[1]
  46. files = open(args[2]).read().strip().split()
  47. for f in files:
  48. s = os.path.join(src, f)
  49. d = os.path.join(dst, f)
  50. if os.path.exists(d):
  51. continue
  52. try:
  53. os.makedirs(os.path.dirname(d))
  54. except OSError:
  55. pass
  56. shutil.copy(s, d)
  57. elif mode == 'copy_all_files':
  58. src = args[0]
  59. dst = args[1]
  60. for root, _, files in os.walk(src):
  61. for f in files:
  62. if os.path.islink(os.path.join(root, f)):
  63. continue
  64. file_dst = os.path.join(dst, os.path.relpath(root, src), f)
  65. if os.path.exists(file_dst):
  66. continue
  67. try:
  68. os.makedirs(os.path.dirname(file_dst))
  69. except OSError:
  70. pass
  71. shutil.copy(os.path.join(root, f), file_dst)
  72. elif mode == 'rename_if_exists':
  73. if os.path.exists(args[0]):
  74. shutil.move(args[0], args[1])
  75. elif mode == 'rename':
  76. targetdir = os.path.dirname(args[1])
  77. if targetdir and not os.path.exists(targetdir):
  78. os.makedirs(os.path.dirname(args[1]))
  79. shutil.move(args[0], args[1])
  80. elif mode == 'remove':
  81. for f in args:
  82. try:
  83. if os.path.isfile(f) or os.path.islink(f):
  84. os.remove(f)
  85. else:
  86. shutil.rmtree(f)
  87. except OSError:
  88. pass
  89. elif mode == 'link_or_copy':
  90. link_or_copy(args[0], args[1])
  91. elif mode == 'link_or_copy_to_dir':
  92. assert len(args) > 1
  93. start = 0
  94. if args[0] == '--no-check':
  95. if args == 2:
  96. sys.exit()
  97. start = 1
  98. dst = args[-1]
  99. for src in args[start:-1]:
  100. link_or_copy(src, os.path.join(dst, os.path.basename(src)))
  101. elif mode == 'cat':
  102. with open(args[0], 'w') as dst:
  103. for input_name in args[1:]:
  104. with open(input_name) as src:
  105. dst.write(src.read())
  106. elif mode == 'md':
  107. try:
  108. os.makedirs(args[0])
  109. except OSError:
  110. pass
  111. else:
  112. raise Exception('unsupported tool %s' % mode)