From 864b049205ceb0d1755f81b38364009b92b67a95 Mon Sep 17 00:00:00 2001 From: Christoph Stahl Date: Wed, 26 Oct 2022 14:34:39 +0200 Subject: [PATCH] Initial dotfile program --- .local/bin/dotfiles | 131 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100755 .local/bin/dotfiles diff --git a/.local/bin/dotfiles b/.local/bin/dotfiles new file mode 100755 index 0000000..ffcd1f0 --- /dev/null +++ b/.local/bin/dotfiles @@ -0,0 +1,131 @@ +#!/usr/bin/env python + + + +""" + link [path] -> move to dotfiles, git add and symlink back + unlink [path] -> move from dotfiles and git rm + apply [path] -> add symlink to system + sync -> pull -> commit -> push +""" + +from argparse import ArgumentParser +import shutil +import os.path +import os +import sys + +basedir = os.path.expanduser("~/.dotfiles") + +def getpaths(path): + absolutpath = os.path.abspath(os.path.expanduser(path)) + dotfilepath = basedir + absolutpath[len(os.path.expanduser("~")):] + + return absolutpath, dotfilepath + + +def link(path, force): + absolutpath, dotfilepath = getpaths(path) + + if not absolutpath.startswith(os.path.expanduser("~")): + print(f"Could not add {path} to repo, only files in your home directory are supported", file=sys.stderr) + sys.exit(2) + + if absolutpath == os.path.expanduser("~"): + print(f"Cannot add home directory to dotfiles", file=sys.stderr) + sys.exit(3) + + if absolutpath.startswith(basedir): + print("Cannot add dotfile directory to to dotfiles", file=sys.stderr) + sys.exit(4) + + if os.path.exists(dotfilepath): + print(f"{dotfilepath} already exists.", file=sys.stderr) + if not force: + sys.exit(5) + else: + print(f"removing {dotfilepath}", file=sys.stderr) + os.system(f"git -C {basedir} rm -r {dotfilepath}") + + print(f"{absolutpath} -> {dotfilepath}") + os.makedirs(os.path.dirname(dotfilepath), exist_ok=True) + shutil.move(absolutpath, dotfilepath) + os.system(f"git -C {basedir} add {dotfilepath}") + os.symlink(dotfilepath, absolutpath) + +def unlink(path): + absolutpath, dotfilepath = getpaths(path) + + if not os.path.islink(absolutpath): + print(f"{absolutpath} is not a symbolic link", file=sys.stderr) + sys.exit(6) + + if not os.path.exists(dotfilepath): + print(f"No dotfile for {absolutpath}", file=sys.stderr) + sys.exit(7) + + print(f"Deleting symlink {absolutpath}") + os.remove(absolutpath) + print(f"{dotfilepath} -> {absolutpath}") + shutil.move(dotfilepath, absolutpath) + os.system(f"git -C {basedir} rm -r {dotfilepath}") + + +def apply(path, force): + absolutpath, dotfilepath = getpaths(path) + + if not os.path.exists(dotfilepath): + print(f"{dotfilepath} does not exist", file=sys.stderr) + sys.exit(8) + + if os.path.exists(absolutpath): + print(f"{absolutpath} already exists", file=sys.stderr) + if not force: + sys.exit(9) + else: + print(f"Removing {absolutpath}", file=sys.stderr) + shutil.rmtree(absolutpath) + + os.link(dotfilepath, absolutpath) + + +def sync(): + os.system(f"git -C {basedir} pull") + os.system(f"git -C {basedir} commit -am \"dotfiles\"") + os.system(f"git -C {basedir} push") + + +def main(): + if not os.path.exists(basedir): + print(f"Creating {basedir}", file=sys.stderr) + if not os.path.isdir(basedir): + print(f"{basedir} exists, but is not a directory") + sys.exit(1) + + parser = ArgumentParser() + subparsers = parser.add_subparsers(dest="command") + add_parser = subparsers.add_parser("link") + unlink_parser = subparsers.add_parser("unlink") + symlink_parser = subparsers.add_parser("apply") + sync_parser = subparsers.add_parser("sync") + + add_parser.add_argument('--force', '-f', action="store_true") + add_parser.add_argument('path') + unlink_parser.add_argument('path') + symlink_parser.add_argument('--force', '-f', action="store_true") + symlink_parser.add_argument('path') + + args = parser.parse_args() + + match args.command: + case "link": + link(args.path, args.force) + case "unlink": + unlink(args.path) + case "apply": + apply(args.path, args.force) + case "sync": + sync() + +if __name__ == "__main__": + main()