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…
	
	Add table
		Add a link
		
	
		Reference in a new issue