copy_docs_files_to_dir.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import argparse
  2. import codecs
  3. import errno
  4. import os
  5. import process_command_files as pcf
  6. import shutil
  7. import sys
  8. def parse_args():
  9. parser = argparse.ArgumentParser()
  10. parser.add_argument('--bin-dir', nargs='*')
  11. parser.add_argument('--build-root', required=True)
  12. parser.add_argument('--dest-dir', required=True)
  13. parser.add_argument('--docs-dir', action='append', nargs=2, dest='docs_dirs', default=None)
  14. parser.add_argument('--existing', choices=('skip', 'overwrite'), default='overwrite')
  15. parser.add_argument('--source-root', required=True)
  16. parser.add_argument('--src-dir', action='append', nargs='*', dest='src_dirs', default=None)
  17. parser.add_argument('files', nargs='*')
  18. return parser.parse_args(pcf.get_args(sys.argv[1:]))
  19. def makedirs(dirname):
  20. try:
  21. os.makedirs(dirname)
  22. except OSError as e:
  23. if e.errno == errno.EEXIST and os.path.isdir(dirname):
  24. pass
  25. else:
  26. raise
  27. def copy_file(src, dst, overwrite=False, orig_path=None):
  28. if os.path.exists(dst) and not overwrite:
  29. return
  30. makedirs(os.path.dirname(dst))
  31. with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst:
  32. if orig_path and src.endswith('.md'):
  33. out = b''
  34. buf = fsrc.readline()
  35. bom_length = len(codecs.BOM_UTF8)
  36. if buf[:bom_length] == codecs.BOM_UTF8:
  37. out += codecs.BOM_UTF8
  38. buf = buf[bom_length:]
  39. info = 'vcsPath: {}\n'.format(orig_path)
  40. if buf.startswith(b'---') and b'\n' in buf[3:] and buf[3:].rstrip(b'\r\n') == b'':
  41. content = b''
  42. found = False
  43. while True:
  44. line = fsrc.readline()
  45. if len(line) == 0:
  46. break
  47. content += line
  48. if line.startswith(b'---') and line[3:].rstrip(b'\r\n') == b'':
  49. found = True
  50. break
  51. out += buf
  52. if found:
  53. out += info.encode('utf-8')
  54. out += content
  55. else:
  56. out += '---\n{}---\n'.format(info).encode('utf-8')
  57. out += buf
  58. fdst.write(out)
  59. shutil.copyfileobj(fsrc, fdst)
  60. def main():
  61. args = parse_args()
  62. dest_dir = os.path.normpath(args.dest_dir)
  63. makedirs(dest_dir)
  64. source_root = os.path.normpath(args.source_root) + os.path.sep
  65. build_root = os.path.normpath(args.build_root) + os.path.sep
  66. is_overwrite_existing = args.existing == 'overwrite'
  67. if args.docs_dirs:
  68. for item in args.docs_dirs:
  69. assert len(item) == 2
  70. docs_dir, nm = item[0], item[1]
  71. assert not os.path.isabs(docs_dir)
  72. if nm and nm != '.':
  73. assert not os.path.isabs(nm)
  74. dst = os.path.join(dest_dir, nm)
  75. else:
  76. dst = dest_dir
  77. abs_docs_dir = os.path.join(args.source_root, docs_dir)
  78. for root, _, files in os.walk(abs_docs_dir):
  79. for f in files:
  80. if os.path.islink(os.path.join(root, f)):
  81. continue
  82. file_src = os.path.normpath(os.path.join(root, f))
  83. assert file_src.startswith(source_root)
  84. file_dst = os.path.join(dst, os.path.relpath(root, abs_docs_dir), f)
  85. copy_file(
  86. file_src, file_dst, overwrite=is_overwrite_existing, orig_path=file_src[len(source_root) :]
  87. )
  88. if args.src_dirs:
  89. for item in args.src_dirs:
  90. assert len(item) > 1
  91. src_dir, nm = os.path.normpath(item[0]), item[1]
  92. assert os.path.isabs(src_dir)
  93. if nm and nm != '.':
  94. assert not os.path.isabs(nm)
  95. dst = os.path.join(dest_dir, nm)
  96. else:
  97. dst = dest_dir
  98. if src_dir.startswith(source_root):
  99. root = source_root
  100. is_from_source_root = True
  101. else:
  102. assert src_dir.startswith(build_root)
  103. root = build_root
  104. is_from_source_root = False
  105. for f in item[2:]:
  106. file_src = os.path.normpath(f)
  107. assert file_src.startswith(root)
  108. rel_path = file_src[len(root) :] if is_from_source_root else None
  109. file_dst = os.path.join(dst, file_src[len(src_dir) :])
  110. copy_file(file_src, file_dst, overwrite=is_overwrite_existing, orig_path=rel_path)
  111. if args.bin_dir:
  112. assert len(args.bin_dir) > 1
  113. bin_dir, bin_dir_namespace = os.path.normpath(args.bin_dir[0]) + os.path.sep, args.bin_dir[1]
  114. assert bin_dir.startswith(build_root)
  115. if bin_dir_namespace and bin_dir_namespace != '.':
  116. assert not os.path.isabs(bin_dir_namespace)
  117. dst = os.path.join(dest_dir, bin_dir_namespace)
  118. else:
  119. dst = dest_dir
  120. for file_src in args.bin_dir[2:]:
  121. assert os.path.isfile(file_src)
  122. assert file_src.startswith(bin_dir)
  123. file_dst = os.path.join(dst, file_src[len(bin_dir) :])
  124. copy_file(file_src, file_dst, overwrite=is_overwrite_existing, orig_path=None)
  125. for src in args.files:
  126. file_src = os.path.normpath(src)
  127. assert os.path.isfile(file_src), 'File [{}] does not exist...'.format(file_src)
  128. rel_path = file_src
  129. orig_path = None
  130. if file_src.startswith(source_root):
  131. rel_path = file_src[len(source_root) :]
  132. orig_path = rel_path
  133. elif file_src.startswith(build_root):
  134. rel_path = file_src[len(build_root) :]
  135. else:
  136. raise Exception('Unexpected file path [{}].'.format(file_src))
  137. assert not os.path.isabs(rel_path)
  138. file_dst = os.path.join(args.dest_dir, rel_path)
  139. if file_dst != file_src:
  140. copy_file(file_src, file_dst, is_overwrite_existing, orig_path)
  141. if __name__ == '__main__':
  142. main()