file_utils.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import os
  2. import sys
  3. from pathlib import Path
  4. def find_files_by_extension(root_dir, extension):
  5. """
  6. Locates all files with a specific extension within a directory and its subdirectories.
  7. Args:
  8. root_dir (str): The absolute path to the root directory to search.
  9. extension (str): The file extension to look for (e.g., '.unity', '.prefab').
  10. The dot is required.
  11. Returns:
  12. list: A list of absolute paths to the found files.
  13. """
  14. if not extension.startswith('.'):
  15. print("Error: Extension must start with a dot (e.g., '.txt').", file=sys.stderr)
  16. return []
  17. found_files = []
  18. for root, _, files in os.walk(root_dir):
  19. for file in files:
  20. if file.endswith(extension):
  21. found_files.append(os.path.join(root, file))
  22. return found_files
  23. def replicate_directory_structure(source_root, target_root):
  24. """
  25. Copies a directory tree from a source to a target location without copying the files.
  26. Args:
  27. source_root (str): The absolute path of the source directory.
  28. target_root (str): The absolute path of the destination directory.
  29. """
  30. source_root = Path(source_root)
  31. target_root = Path(target_root)
  32. if not source_root.is_dir():
  33. print(f"Error: Source path '{source_root}' is not a valid directory.", file=sys.stderr)
  34. return
  35. for dirpath, _, _ in os.walk(source_root):
  36. # Create a relative path from the source root
  37. relative_path = Path(dirpath).relative_to(source_root)
  38. # Join it with the target root to get the new directory path
  39. target_path = target_root / relative_path
  40. # Create the directory in the target, ignoring if it already exists
  41. target_path.mkdir(parents=True, exist_ok=True)
  42. def create_guid_to_path_map(assets_dir):
  43. """
  44. Creates a dictionary mapping GUIDs to their corresponding asset file paths.
  45. """
  46. guid_map = {}
  47. meta_files = find_files_by_extension(assets_dir, '.meta')
  48. for meta_file_path in meta_files:
  49. asset_path = meta_file_path[:-5] # Remove .meta
  50. guid = None
  51. try:
  52. with open(meta_file_path, 'r', encoding='utf-8') as f:
  53. for line in f:
  54. if line.strip().startswith('guid:'):
  55. guid = line.split(':')[1].strip()
  56. break
  57. if guid:
  58. guid_map[guid] = asset_path
  59. except Exception as e:
  60. print(f"Warning: Could not process meta file {meta_file_path}. {e}", file=sys.stderr)
  61. return guid_map
  62. if __name__ == '__main__':
  63. # Example usage for testing the module directly.
  64. # This requires a temporary directory structure to be set up.
  65. # Create a dummy structure for testing
  66. test_source_dir = Path('./tmp_source_for_testing')
  67. test_target_dir = Path('./tmp_target_for_testing')
  68. try:
  69. print("Setting up test directory structure...")
  70. (test_source_dir / 'scenes').mkdir(parents=True, exist_ok=True)
  71. (test_source_dir / 'prefabs' / 'characters').mkdir(parents=True, exist_ok=True)
  72. (test_source_dir / 'scenes' / 'level1.unity').touch()
  73. (test_source_dir / 'scenes' / 'level1.unity.meta').touch()
  74. (test_source_dir / 'prefabs' / 'player.prefab').touch()
  75. print("\n--- Testing find_files_by_extension ---")
  76. unity_files = find_files_by_extension(str(test_source_dir), '.unity')
  77. print(f"Found .unity files: {unity_files}")
  78. assert len(unity_files) == 1
  79. prefab_files = find_files_by_extension(str(test_source_dir), '.prefab')
  80. print(f"Found .prefab files: {prefab_files}")
  81. assert len(prefab_files) == 1
  82. print("\n--- Testing replicate_directory_structure ---")
  83. replicate_directory_structure(str(test_source_dir), str(test_target_dir))
  84. print("Checking replicated structure:")
  85. assert test_target_dir.exists()
  86. assert (test_target_dir / 'scenes').exists()
  87. assert (test_target_dir / 'prefabs' / 'characters').exists()
  88. assert not (test_target_dir / 'scenes' / 'level1.unity').exists() # File should not be copied
  89. print("Replicated structure seems correct.")
  90. finally:
  91. # Clean up test directories
  92. import shutil
  93. if test_source_dir.exists():
  94. shutil.rmtree(test_source_dir)
  95. if test_target_dir.exists():
  96. shutil.rmtree(test_target_dir)
  97. print("\nCleaned up test directories.")