path_ops.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. """Path operations."""
  2. from __future__ import annotations
  3. import os
  4. import shutil
  5. from typing import Optional
  6. # Shorthand for join.
  7. join = os.linesep.join
  8. def rm(path: str):
  9. """Remove a file or directory.
  10. Args:
  11. path: The path to the file or directory.
  12. """
  13. if os.path.isdir(path):
  14. shutil.rmtree(path)
  15. elif os.path.isfile(path):
  16. os.remove(path)
  17. def cp(src: str, dest: str, overwrite: bool = True) -> bool:
  18. """Copy a file or directory.
  19. Args:
  20. src: The path to the file or directory.
  21. dest: The path to the destination.
  22. overwrite: Whether to overwrite the destination.
  23. Returns:
  24. Whether the copy was successful.
  25. """
  26. if src == dest:
  27. return False
  28. if not overwrite and os.path.exists(dest):
  29. return False
  30. if os.path.isdir(src):
  31. rm(dest)
  32. shutil.copytree(src, dest)
  33. else:
  34. shutil.copyfile(src, dest)
  35. return True
  36. def mv(src: str, dest: str, overwrite: bool = True) -> bool:
  37. """Move a file or directory.
  38. Args:
  39. src: The path to the file or directory.
  40. dest: The path to the destination.
  41. overwrite: Whether to overwrite the destination.
  42. Returns:
  43. Whether the move was successful.
  44. """
  45. if src == dest:
  46. return False
  47. if not overwrite and os.path.exists(dest):
  48. return False
  49. rm(dest)
  50. shutil.move(src, dest)
  51. return True
  52. def mkdir(path: str):
  53. """Create a directory.
  54. Args:
  55. path: The path to the directory.
  56. """
  57. if not os.path.exists(path):
  58. os.makedirs(path)
  59. def ln(src: str, dest: str, overwrite: bool = False) -> bool:
  60. """Create a symbolic link.
  61. Args:
  62. src: The path to the file or directory.
  63. dest: The path to the destination.
  64. overwrite: Whether to overwrite the destination.
  65. Returns:
  66. Whether the link was successful.
  67. """
  68. if src == dest:
  69. return False
  70. if not overwrite and (os.path.exists(dest) or os.path.islink(dest)):
  71. return False
  72. if os.path.isdir(src):
  73. rm(dest)
  74. os.symlink(src, dest, target_is_directory=True)
  75. else:
  76. os.symlink(src, dest)
  77. return True
  78. def which(program: str) -> Optional[str]:
  79. """Find the path to an executable.
  80. Args:
  81. program: The name of the executable.
  82. Returns:
  83. The path to the executable.
  84. """
  85. return shutil.which(program)