path_ops.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. """Path operations."""
  2. from __future__ import annotations
  3. import json
  4. import os
  5. import shutil
  6. from pathlib import Path
  7. from reflex import constants
  8. # Shorthand for join.
  9. join = os.linesep.join
  10. def rm(path: str):
  11. """Remove a file or directory.
  12. Args:
  13. path: The path to the file or directory.
  14. """
  15. if os.path.isdir(path):
  16. shutil.rmtree(path)
  17. elif os.path.isfile(path):
  18. os.remove(path)
  19. def cp(src: str, dest: str, overwrite: bool = True) -> bool:
  20. """Copy a file or directory.
  21. Args:
  22. src: The path to the file or directory.
  23. dest: The path to the destination.
  24. overwrite: Whether to overwrite the destination.
  25. Returns:
  26. Whether the copy was successful.
  27. """
  28. if src == dest:
  29. return False
  30. if not overwrite and os.path.exists(dest):
  31. return False
  32. if os.path.isdir(src):
  33. rm(dest)
  34. shutil.copytree(src, dest)
  35. else:
  36. shutil.copyfile(src, dest)
  37. return True
  38. def mv(src: str, dest: str, overwrite: bool = True) -> bool:
  39. """Move a file or directory.
  40. Args:
  41. src: The path to the file or directory.
  42. dest: The path to the destination.
  43. overwrite: Whether to overwrite the destination.
  44. Returns:
  45. Whether the move was successful.
  46. """
  47. if src == dest:
  48. return False
  49. if not overwrite and os.path.exists(dest):
  50. return False
  51. rm(dest)
  52. shutil.move(src, dest)
  53. return True
  54. def mkdir(path: str):
  55. """Create a directory.
  56. Args:
  57. path: The path to the directory.
  58. """
  59. os.makedirs(path, exist_ok=True)
  60. def ln(src: str, dest: str, overwrite: bool = False) -> bool:
  61. """Create a symbolic link.
  62. Args:
  63. src: The path to the file or directory.
  64. dest: The path to the destination.
  65. overwrite: Whether to overwrite the destination.
  66. Returns:
  67. Whether the link was successful.
  68. """
  69. if src == dest:
  70. return False
  71. if not overwrite and (os.path.exists(dest) or os.path.islink(dest)):
  72. return False
  73. if os.path.isdir(src):
  74. rm(dest)
  75. os.symlink(src, dest, target_is_directory=True)
  76. else:
  77. os.symlink(src, dest)
  78. return True
  79. def which(program: str) -> str | None:
  80. """Find the path to an executable.
  81. Args:
  82. program: The name of the executable.
  83. Returns:
  84. The path to the executable.
  85. """
  86. return shutil.which(program)
  87. def get_node_bin_path() -> str | None:
  88. """Get the node binary dir path.
  89. Returns:
  90. The path to the node bin folder.
  91. """
  92. if not os.path.exists(constants.NODE_BIN_PATH):
  93. str_path = which("node")
  94. return str(Path(str_path).parent) if str_path else str_path
  95. return constants.NODE_BIN_PATH
  96. def get_node_path() -> str | None:
  97. """Get the node binary path.
  98. Returns:
  99. The path to the node binary file.
  100. """
  101. if not os.path.exists(constants.NODE_PATH):
  102. return which("node")
  103. return constants.NODE_PATH
  104. def get_npm_path() -> str | None:
  105. """Get npm binary path.
  106. Returns:
  107. The path to the npm binary file.
  108. """
  109. if not os.path.exists(constants.NODE_PATH):
  110. return which("npm")
  111. return constants.NPM_PATH
  112. def update_json_file(file_path: str, update_dict: dict[str, int | str]):
  113. """Update the contents of a json file.
  114. Args:
  115. file_path: the path to the JSON file.
  116. update_dict: object to update json.
  117. """
  118. fp = Path(file_path)
  119. # Create the file if it doesn't exist.
  120. fp.touch(exist_ok=True)
  121. # Create an empty json object if file is empty
  122. fp.write_text("{}") if fp.stat().st_size == 0 else None
  123. # Read the existing json object from the file.
  124. json_object = {}
  125. if fp.stat().st_size == 0:
  126. with open(fp) as f:
  127. json_object = json.load(f)
  128. # Update the json object with the new data.
  129. json_object.update(update_dict)
  130. # Write the updated json object to the file
  131. with open(fp, "w") as f:
  132. json.dump(json_object, f, ensure_ascii=False)