forked from durdn/cfg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstall.py
executable file
·153 lines (134 loc) · 5.56 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env python
import os
import glob
import sys
from os.path import join,normpath,abspath,islink
from pprint import pprint
import hashlib
debug = False
version = '1.0'
cfgname = '.cfg'
bkpname = 'backup.cfg'
gitrepo = '[email protected]:durdn/cfg.git'
gitrepo_ro = 'git://github.com/durdn/cfg.git'
ignored = ['install.py',
'install.pyc',
'.git',
'.gitignore',
'README',
'bin'
]
home = normpath(os.environ['HOME'])
backup_folder = normpath(join(home,bkpname))
cfg_folder = normpath(join(home,cfgname))
def call(command,fake = False):
"""
call(command) --> (result, output)
Runs the command in the local shell returning a tuple
containing :
- the return result (None for 0, otherwise an int), and
- the full, stripped standard output.
You wouldn't normally use this, instead consider call(), test() and system()
"""
print command
if fake:
return
process = os.popen(command)
output = []
line = process.readline()
while not line == "":
sys.stdout.flush()
output.append(line)
line = process.readline()
result = process.close()
return (result, "".join(output).strip())
def assets(rootpath,flist,test):
return filter(lambda x: test(x), [normpath(join(rootpath,f)) for f in flist])
def local_assets(flist,test):
return assets(home,flist,test)
def cfg_assets(flist,test):
return filter(lambda x: test(x) and os.path.split(x)[1] not in ignored,
assets(cfg_folder,flist,test))
def install_tracked_assets(cfg_folder, destination_folder):
"Install tracked configuration files into destination folder"
files = cfg_assets(os.listdir(cfg_folder),os.path.isfile)
for f in files:
name = os.path.split(f)[1]
dest = join(destination_folder,name)
if os.path.exists(dest):
hashsrc = hashlib.sha1(file(f).read()).hexdigest()
hashdest = hashlib.sha1(file(dest).read()).hexdigest()
if hashsrc != hashdest:
call('F [install/backup] %s' % dest,fake=True)
call('mv %s %s' % (dest,join(backup_folder,name)),fake=debug)
call('ln -s %s %s' % (f,dest),fake=debug)
else:
if islink(dest):
call('F [unchanged] %s' % dest,fake=True)
else:
call('F [unchanged/relink] %s' % dest,fake=True)
call('mv %s %s' % (dest,join(backup_folder,name)),fake=debug)
call('ln -s %s %s' % (f,dest),fake=debug)
else:
call('ln -s %s %s' % (f,dest),fake=debug)
dirs = cfg_assets(os.listdir(cfg_folder),os.path.isdir)
for d in dirs:
name = os.path.split(d)[1]
destdir = join(destination_folder,name)
if (os.path.exists(destdir)):
dest_linksto = os.readlink(destdir)
if dest_linksto == d:
call('D [unchanged] %s linked to %s' % (destdir, d), fake=True)
else:
call('mv %s %s' % (d,join(backup_folder,name)),fake=debug)
call('ln -s %s %s' % (d,destdir),fake=debug)
else:
call('ln -s %s %s' % (d,destdir),fake=debug)
if __name__ == '__main__':
print '|* cfg version', version
print '|* home is', home
print '|* backup folder is',backup_folder
print '|* cfg folder is',cfg_folder
#create backup folder for existing configs that will be overwritten
if not os.path.exists(backup_folder):
os.mkdir(backup_folder)
#clone config folder if not present, update if present
if not os.path.exists(cfg_folder):
#clone cfg repo
call("git clone %s %s" % (gitrepo,cfg_folder))
if not os.path.exists(cfg_folder):
print '!!! ssh key not installed on github for this box, cloning read only repo'
call("git clone %s %s" % (gitrepo_ro,cfg_folder))
print '|* changing remote origin to read/write repo: %s' % gitrepo
call("cd %s && git config remote.origin.url %s" % (cfg_folder, gitrepo))
if os.path.exists(join(home,'.ssh/id_rsa.pub')):
print "|* please copy your public key below to github or you won't be able to commit"
print
print file(join(home,'.ssh/id_rsa.pub')).read()
else:
print '|* please generate your public/private key pair with the command:'
print
print 'ssh-keygen'
print
print '|* and copy the public key to github'
else:
call("cd %s && git submodule init" % (cfg_folder))
call("cd %s && git submodule update" % (cfg_folder))
else:
if os.path.exists(join(cfg_folder,'.git')):
print '|-> cfg already cloned to',cfg_folder
print '|-> pulling origin master'
if debug:
call("cd %s" % (cfg_folder))
else:
call("cd %s && git pull origin master" % (cfg_folder))
print '|-> initializing submodules'
call("cd %s && git submodule init" % (cfg_folder))
print '|-> updating submodules'
call("cd %s && git submodule update" % (cfg_folder))
else:
print '|-> git tracking projects not found in %s, ending program in shame' % cfg_folder
stats = cfg_assets(os.listdir(cfg_folder),lambda x: True)
print '|* tracking %d assets in %s' % (len(stats),cfgname)
print '|* installing tracked config files...'
install_tracked_assets(cfg_folder,home)