111 lines
2.4 KiB
Python
111 lines
2.4 KiB
Python
"""Path operations."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import shutil
|
|
from typing import Optional
|
|
|
|
# Shorthand for join.
|
|
join = os.linesep.join
|
|
|
|
|
|
def rm(path: str):
|
|
"""Remove a file or directory.
|
|
|
|
Args:
|
|
path: The path to the file or directory.
|
|
"""
|
|
if os.path.isdir(path):
|
|
shutil.rmtree(path)
|
|
elif os.path.isfile(path):
|
|
os.remove(path)
|
|
|
|
|
|
def cp(src: str, dest: str, overwrite: bool = True) -> bool:
|
|
"""Copy a file or directory.
|
|
|
|
Args:
|
|
src: The path to the file or directory.
|
|
dest: The path to the destination.
|
|
overwrite: Whether to overwrite the destination.
|
|
|
|
Returns:
|
|
Whether the copy was successful.
|
|
"""
|
|
if src == dest:
|
|
return False
|
|
if not overwrite and os.path.exists(dest):
|
|
return False
|
|
if os.path.isdir(src):
|
|
rm(dest)
|
|
shutil.copytree(src, dest)
|
|
else:
|
|
shutil.copyfile(src, dest)
|
|
return True
|
|
|
|
|
|
def mv(src: str, dest: str, overwrite: bool = True) -> bool:
|
|
"""Move a file or directory.
|
|
|
|
Args:
|
|
src: The path to the file or directory.
|
|
dest: The path to the destination.
|
|
overwrite: Whether to overwrite the destination.
|
|
|
|
Returns:
|
|
Whether the move was successful.
|
|
"""
|
|
if src == dest:
|
|
return False
|
|
if not overwrite and os.path.exists(dest):
|
|
return False
|
|
rm(dest)
|
|
shutil.move(src, dest)
|
|
return True
|
|
|
|
|
|
def mkdir(path: str):
|
|
"""Create a directory.
|
|
|
|
Args:
|
|
path: The path to the directory.
|
|
"""
|
|
if not os.path.exists(path):
|
|
os.makedirs(path)
|
|
|
|
|
|
def ln(src: str, dest: str, overwrite: bool = False) -> bool:
|
|
"""Create a symbolic link.
|
|
|
|
Args:
|
|
src: The path to the file or directory.
|
|
dest: The path to the destination.
|
|
overwrite: Whether to overwrite the destination.
|
|
|
|
Returns:
|
|
Whether the link was successful.
|
|
"""
|
|
if src == dest:
|
|
return False
|
|
if not overwrite and (os.path.exists(dest) or os.path.islink(dest)):
|
|
return False
|
|
if os.path.isdir(src):
|
|
rm(dest)
|
|
os.symlink(src, dest, target_is_directory=True)
|
|
else:
|
|
os.symlink(src, dest)
|
|
return True
|
|
|
|
|
|
def which(program: str) -> Optional[str]:
|
|
"""Find the path to an executable.
|
|
|
|
Args:
|
|
program: The name of the executable.
|
|
|
|
Returns:
|
|
The path to the executable.
|
|
"""
|
|
return shutil.which(program)
|