-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathupdate_config.py
More file actions
executable file
·98 lines (81 loc) · 3.17 KB
/
Copy pathupdate_config.py
File metadata and controls
executable file
·98 lines (81 loc) · 3.17 KB
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
98
#!/usr/bin/env python3
import json
import os
import subprocess
import sys
import shutil
from difflib import unified_diff
if os.getenv('USER'):
USER_HOME = os.path.expanduser("~{}".format(os.environ['USER']))
else:
USER_HOME = os.path.expanduser("~")
CHEZMOI_HOME = os.getenv('CHEZMOI_HOME') or subprocess.run(["chezmoi", "source-path"], universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.strip()
CHEZMOI_CONFIG = os.getenv('CHEZMOI_CONFIG') or os.path.join(USER_HOME, '.config/chezmoi/chezmoi.json')
CHEZMOI_CONFIG_TMPL = os.getenv('CHEZMOI_CONFIG_TMPL') or os.path.join(CHEZMOI_HOME, '.chezmoi.json.tmpl')
def write_file(path, content):
with open(path, 'w', encoding='utf-8') as fw:
fw.write(content)
def read_config():
config = None
with open(CHEZMOI_CONFIG, 'r', encoding='utf-8') as fr:
config = fr.read()
return config
def read_config_template():
config = None
with open(CHEZMOI_CONFIG_TMPL, 'r', encoding='utf-8') as fr:
config = fr.read()
s = subprocess.run(["chezmoi", "execute-template"], universal_newlines=True, input=config, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return s.stdout
def show_diff(new):
if not new:
return
if not os.path.exists(CHEZMOI_CONFIG):
return
if not shutil.which('diff'):
old = read_config()
d = unified_diff([x + "\n" for x in old.splitlines()], [x + "\n" for x in new.splitlines()],
fromfile='before', tofile='after')
sys.stdout.writelines(d)
return
try:
s = subprocess.run(['diff', '--unified', '--color=always', '--', CHEZMOI_CONFIG, '-'], universal_newlines=True, input=new, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
if s.returncode == 2:
raise RuntimeError
print(s.stdout)
except RuntimeError:
subprocess.run(['diff', '--unified', '--', CHEZMOI_CONFIG, '-'], universal_newlines=True, input=new)
def main():
# It's not possible for an existing config not to exist
# if it doesn't somehow, just run chezmoi init
old = read_config()
new = read_config_template()
if old == new:
print('Config up to date')
return
# Show diff and ask if we update
show_diff(new)
print('\n')
while True:
action = input("[merge,overwrite,skip] ").lower()
if action.startswith('m'):
old_json = json.loads(old)
new_json = json.loads(new)
new_json['data'] = {**new_json['data'], **old_json['data']}
new_str = json.dumps(new_json, indent=2)
show_diff(new_str)
if 'y' in input('Merge? [yN] ').lower():
write_file(CHEZMOI_CONFIG, new_str)
print('merged {}'.format(CHEZMOI_CONFIG))
return
elif action.startswith('o'):
write_file(CHEZMOI_CONFIG, new)
print('overwrote {}'.format(CHEZMOI_CONFIG))
return
elif action.startswith('s'):
return
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print('\n\nCancelled')