Last active
May 14, 2024 16:28
-
-
Save rz3n/5d9d373dea28b031302173cef5e261bc to your computer and use it in GitHub Desktop.
Dotfiles bootstrap script in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
ignore: | |
- .git | |
- .gitignore | |
- README.md | |
- install | |
- install.ignore.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import os | |
import yaml | |
def dotfiles(dstDir, srcDir, force=False): | |
# for all files and directories in srcDir, create a symlink in dstDir | |
# if it is a directory, recursively create directories and symlinks for all | |
# files | |
for item in os.listdir(srcDir): | |
# if it is a ignored file or directory, skip it | |
if item in IGNORE: | |
continue | |
if dstDir == HOME_DIR: | |
dstFile = os.path.join(dstDir, '.' + item) | |
else: | |
dstFile = os.path.join(dstDir, item) | |
srcFile = os.path.join(srcDir, item) | |
# if it is a file | |
if os.path.isfile(srcFile): | |
# check if it exists | |
if os.path.lexists(dstFile): | |
# if it is a symlink, skip it | |
if os.path.islink(dstFile): | |
continue | |
# if it is not a symlink, ask if we should overwrite it | |
else: | |
if not force: | |
response = input("Overwrite file `%s'? [y/N] " % dstFile) | |
if not response.lower().startswith('y'): | |
print ("Skipping `%s'..." % dstFile) | |
continue | |
else: | |
os.remove(dstFile) | |
elif force: | |
os.remove(dstFile) | |
# create the symlink | |
os.symlink(srcFile, dstFile) | |
# if it is a directory | |
if os.path.isdir(srcFile): | |
# check if it exists | |
if not os.path.exists(dstFile): | |
os.makedirs(dstFile) | |
# recursively create symlinks for all files | |
dotfiles(dstFile, srcFile, force) | |
if __name__ == '__main__': | |
# get arguments | |
parser = argparse.ArgumentParser() | |
parser.add_argument('-s', '--src') | |
parser.add_argument('-d', '--dst') | |
parser.add_argument('-f', '--force', default=False, action='store_true', | |
help='overwrite existing files') | |
args = parser.parse_args() | |
# current directory | |
if not args.src: | |
DOTFILES_DIR = os.path.abspath('.') | |
else: | |
DOTFILES_DIR = os.path.abspath(args.src) | |
# home directory | |
if not args.dst: | |
HOME_DIR = os.path.expanduser('~') | |
else: | |
HOME_DIR = os.path.expanduser(args.dst) | |
# ignored files and directories (from install.ignore.yaml) | |
with open('install.ignore.yaml') as f: | |
IGNORE = yaml.load(f, Loader=yaml.FullLoader)['ignore'] | |
# create symlinks | |
print('Creating symlinks...') | |
dotfiles(HOME_DIR, DOTFILES_DIR, args.force) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment