Support script to audit, remove dotfile symlinks
Adding a simple script to help me manage the symlinks to the dotfiles managed by my mono-repo.
This commit is contained in:
parent
edea127e07
commit
a65b895c8e
1 changed files with 88 additions and 0 deletions
88
python/delete_dotfile_symlinks.py
Executable file
88
python/delete_dotfile_symlinks.py
Executable file
|
@ -0,0 +1,88 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# TODO: Prefer a proper Python module doc here.
|
||||||
|
# Find and delete all symlinks to the dotfiles defined in $BRIEFCASE.
|
||||||
|
#
|
||||||
|
# Oftentimes I corrupt the state of my dotfiles. The intention with this script
|
||||||
|
# is to write some tooling to help me better manage my dotfile cleanliness. An
|
||||||
|
# example workflow might look like:
|
||||||
|
#
|
||||||
|
# ```shell
|
||||||
|
# > ./delete_dotfile_symlinks.py --audit
|
||||||
|
# > ./delete_dotfile_symlinks.py --seriously
|
||||||
|
# > cd ..
|
||||||
|
# > make install
|
||||||
|
# ```
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Dependencies
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from os.path import expanduser
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Library
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
def homify(path):
|
||||||
|
"""Prefer ~ instead of the absolute `path`."""
|
||||||
|
home = expanduser('~')
|
||||||
|
return path.replace(home, '~')
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='Remove symlinks to my managed dotfiles.')
|
||||||
|
parser.add_argument('--audit', dest='audit', action='store_true', help='Output all symlinks that would be deleted. This is the default behavior. This option is mutually exclusive with the --seriously option.')
|
||||||
|
parser.add_argument('--seriously', dest='seriously', action='store_true', help='Actually delete the symlinks. This option is mutually exclusive with the --audit option.')
|
||||||
|
parser.add_argument('--repo-name', dest='name', default='briefcase', help='The name of the repository. Usually "briefcase" or "dotfiles".')
|
||||||
|
parser.add_argument('--device-only', dest='device_only', action='store_true', help='Only output the device-specific dotfiles.')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# TODO: Instead of doing this manually, is this something that argparse supports?
|
||||||
|
if not args.audit and not args.seriously:
|
||||||
|
print('Either --audit or --seriously must be passed. See --help for more information.')
|
||||||
|
# TODO: What's the proper exit code here?
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# These two options are mutually exclusive.
|
||||||
|
assert args.audit != args.seriously
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
for cwd, dirs, files in os.walk(expanduser("~")):
|
||||||
|
# Skip this repository.
|
||||||
|
if args.name in cwd:
|
||||||
|
continue
|
||||||
|
for file in files:
|
||||||
|
source = os.path.join(cwd, file)
|
||||||
|
if os.path.islink(source):
|
||||||
|
dest = os.readlink(source)
|
||||||
|
# We won't know certainly if the link points to a dotfile that I manage
|
||||||
|
# with this simple test.
|
||||||
|
if args.device_only:
|
||||||
|
# TODO: Change 'desktop' with a lookup of hostname to device name.
|
||||||
|
if 'configs/desktop' in dest:
|
||||||
|
if args.audit:
|
||||||
|
print('{} -> {}'.format(homify(source), homify(dest)))
|
||||||
|
elif args.seriously:
|
||||||
|
print('rm {}'.format(source))
|
||||||
|
os.remove(source)
|
||||||
|
count += 1
|
||||||
|
elif args.name in dest:
|
||||||
|
if args.audit:
|
||||||
|
print('{} -> {}'.format(homify(source), homify(dest)))
|
||||||
|
elif args.seriously:
|
||||||
|
print('rm {}'.format(source))
|
||||||
|
os.remove(source)
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
if args.audit:
|
||||||
|
print('Would have deleted {} symlinks.'.format(count))
|
||||||
|
elif args.seriously:
|
||||||
|
print('Successfully deleted {} symlinks.'.format(count))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in a new issue