Backup old dotman.py script
This commit is contained in:
117
dotman.py
Executable file
117
dotman.py
Executable file
@@ -0,0 +1,117 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import difflib
|
||||||
|
import filecmp
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
SOURCE_DIR = "./home/"
|
||||||
|
TARGET_DIR = os.environ["HOME"]
|
||||||
|
|
||||||
|
|
||||||
|
def list_files(path: str = ".") -> list[str]:
|
||||||
|
paths = []
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
for file in files:
|
||||||
|
paths.append(os.path.join(root, file))
|
||||||
|
return paths
|
||||||
|
|
||||||
|
|
||||||
|
def map_colored(string: str) -> str:
|
||||||
|
if string.startswith("-"):
|
||||||
|
return f"\033[38;2;255;0;0m{string}\033[0m" # Red
|
||||||
|
elif string.startswith("+"):
|
||||||
|
return f"\033[38;2;0;255;0m{string}\033[0m" # Green
|
||||||
|
else:
|
||||||
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
def print_diff(from_file: str, to_file: str) -> None:
|
||||||
|
with open(from_file, "r") as f1, open(to_file, "r") as f2:
|
||||||
|
diff = list(difflib.unified_diff(
|
||||||
|
f1.readlines(),
|
||||||
|
f2.readlines(),
|
||||||
|
fromfile=from_file,
|
||||||
|
tofile=to_file))
|
||||||
|
colored_diff = list(map(map_colored, diff))
|
||||||
|
|
||||||
|
for line in diff[:2]:
|
||||||
|
print(line, end="")
|
||||||
|
|
||||||
|
for line in colored_diff[2:]:
|
||||||
|
print(line, end="")
|
||||||
|
|
||||||
|
|
||||||
|
def copy_with_dirs(source: str, target: str) -> None:
|
||||||
|
os.makedirs(os.path.dirname(target), exist_ok=True)
|
||||||
|
shutil.copy(source, target)
|
||||||
|
|
||||||
|
|
||||||
|
def deploy(source_dir: str, target_dir: str) -> None:
|
||||||
|
source_files = list_files(source_dir)
|
||||||
|
target_files = list(map(lambda f: os.path.join(
|
||||||
|
target_dir, f[len(source_dir):]), source_files.copy()))
|
||||||
|
|
||||||
|
deploy_map = {}
|
||||||
|
for i, source_file in enumerate(source_files):
|
||||||
|
deploy_map[source_file] = target_files[i]
|
||||||
|
|
||||||
|
for source, target in deploy_map.items():
|
||||||
|
if os.path.isfile(target):
|
||||||
|
if not filecmp.cmp(source, target): # TODO: Consider shallow=False
|
||||||
|
answer = input(target + " conflicts. Overwrite? [y/N] ")
|
||||||
|
if answer.lower().startswith("y"):
|
||||||
|
copy_with_dirs(source, target)
|
||||||
|
else:
|
||||||
|
copy_with_dirs(source, target)
|
||||||
|
|
||||||
|
|
||||||
|
def pull(source_dir: str, target_dir: str) -> None:
|
||||||
|
target_files = list_files(target_dir)
|
||||||
|
source_files = list(map(lambda f: os.path.join(
|
||||||
|
source_dir, f[len(target_dir):]), target_files.copy()))
|
||||||
|
|
||||||
|
pull_map = {}
|
||||||
|
for i, source_file in enumerate(source_files):
|
||||||
|
pull_map[source_file] = target_files[i]
|
||||||
|
|
||||||
|
for source, target in pull_map.items():
|
||||||
|
try:
|
||||||
|
shutil.copy(source, target)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def diff(source_dir: str, target_dir: str) -> None:
|
||||||
|
target_files = list_files(target_dir)
|
||||||
|
source_files = list(map(lambda f: os.path.join(
|
||||||
|
source_dir, f[len(target_dir):]), target_files.copy()))
|
||||||
|
|
||||||
|
file_map = {}
|
||||||
|
for i, file in enumerate(source_files):
|
||||||
|
file_map[file] = target_files[i]
|
||||||
|
|
||||||
|
for source, target in file_map.items():
|
||||||
|
print_diff(source, target)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog="dotman",
|
||||||
|
description="Dotfiles manager")
|
||||||
|
parser.add_argument("command", choices=["deploy", "pull", "diff"],
|
||||||
|
help="deploy or pull dotfiles")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.command == "deploy":
|
||||||
|
deploy(SOURCE_DIR, TARGET_DIR)
|
||||||
|
elif args.command == "pull":
|
||||||
|
pull(TARGET_DIR, SOURCE_DIR)
|
||||||
|
elif args.command == "diff":
|
||||||
|
diff(TARGET_DIR, SOURCE_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user