forked from simonjbeaumont/.dotfiles
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstall.py
97 lines (79 loc) · 3.36 KB
/
install.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env python
import argparse
import os.path
import sys
import yaml
def create_derived_file(src, subs, comment_delim=None, dry_run=False):
derived_path = "%s.sub" % src
print("Creating %s from %s:" % (derived_path, src))
with open(src, 'r') as f_src:
contents = f_src.read()
for (to_replace, replace_with) in subs.items():
to_replace_str = "@@%s@@" % to_replace
print("- Substituting in %s: %s -> %s"
% (derived_path, to_replace_str, replace_with))
if to_replace_str not in contents:
print("-- Warning: %s not found in %s" % (to_replace_str, src))
contents = contents.replace(to_replace_str, replace_with)
with open(derived_path, 'w') as f_derived:
if comment_delim:
preamble = ("%s This file has been autogenerated from %s\n\n" %
(comment_delim, os.path.realpath(src)))
f_derived.writelines(preamble)
f_derived.writelines(contents)
return derived_path
def prompt_for_missing_subs(template, subs):
result = {}
print("Prompting for substitutions for %s..." % template)
for sub in subs:
if isinstance(sub, dict):
result.update(sub)
else:
sub_with = raw_input("- Please provide %s: " % sub)
result[sub] = sub_with
return result
def install_symlink(link_to, link_from, force=False, dry_run=False):
print("Installing symlink: %s -> %s" % (link_from, link_to))
link_to = os.path.abspath(link_to)
link_from = os.path.expanduser(link_from)
link_from = os.path.normpath(link_from)
# Quietly skip if link already valid
if os.path.islink(link_from) and os.path.realpath(link_from) == link_to:
return
if os.path.lexists(link_from):
if not force:
print("- Skipping (exists)")
return
os.unlink(link_from)
link_from_dir = os.path.dirname(link_from)
if link_from_dir and not os.path.exists(link_from_dir):
print("- Creating directory: %s" % link_from_dir)
if not dry_run:
os.makedirs(link_from_dir)
print("- Creating link: %s -> %s" % (link_from, link_to))
if not dry_run:
os.symlink(link_to, link_from)
def parse_args_or_exit(argv=None):
parser = argparse.ArgumentParser(description="Install all symlinks")
parser.add_argument("--config", required=True, type=argparse.FileType('r'),
help="Path to config YAML")
parser.add_argument("--force", action="store_true",
help="Force overwrite of existing files or links")
parser.add_argument("--dry-run", action="store_true",
help="Don't do anything, just print")
return parser.parse_args(argv)
def main(argv):
args = parse_args_or_exit(argv)
install = yaml.load(args.config)
for (link_from, config) in install.items():
if isinstance(config, str):
link_to = config
else:
template = config["template"]
subs = prompt_for_missing_subs(template, config.get("subs", []))
comment_delim = config.get("comment_delim", None)
link_to = create_derived_file(template, subs, comment_delim,
args.dry_run)
install_symlink(link_to, link_from, args.force, args.dry_run)
if __name__ == "__main__":
main(sys.argv[1:])