Initial dotfile program

This commit is contained in:
Christoph Stahl 2022-10-26 14:34:39 +02:00
commit 864b049205

131
.local/bin/dotfiles Executable file
View file

@ -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()