forked from vfxetc/vee
-
Notifications
You must be signed in to change notification settings - Fork 0
/
install_vee.py
230 lines (175 loc) · 7.47 KB
/
install_vee.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
'''usage: python install.py
This script may be run on its own, or straight from GitHub, e.g.:
python <(curl -fsSL https://raw.githubusercontent.com/westernx/vee/master/install_vee.py)
To install to /usr/local/vee, and force an update to the latest version:
python <(curl -fsSL https://raw.githubusercontent.com/westernx/vee/master/install_vee.py) --yes
'''
def ANSI(*args):
return ''.join('\x1b[' + str(x) for x in args)
def SGR(*args):
return ''.join(ANSI(str(x) + 'm') for x in args)
red = lambda x: SGR(1, 31) + x + SGR(0)
green = lambda x: SGR(1, 32) + x + SGR(0)
yellow = lambda x: SGR(1, 33) + x + SGR(0)
blue = lambda x: SGR(1, 34) + x + SGR(0)
bold = lambda x: SGR(1) + x + SGR(0)
faint = lambda x: SGR(2) + x + SGR(0)
def heading(heading, msg='', detail=''):
print blue(heading), bold(msg), detail
def error(msg, detail=''):
print red("Error:"), bold(msg), detail
def warning(msg, detail=''):
print yellow('Warning:'), bold(msg), detail
import sys
if sys.version_info < (2, 7):
error("VEE requires Python 2.7")
exit(1)
from subprocess import call, check_call, check_output, PIPE
import argparse
import errno
import os
import shutil
import tarfile
import urllib2
import zipfile
def makedirs(x):
try:
os.makedirs(x)
except OSError as e:
if e.errno != errno.EEXIST:
raise
class SwitchAction(argparse.Action):
def __init__(self, option_strings, **kwargs):
kwargs['nargs'] = 0
self.option_values = {}
for opt in option_strings[:]:
self.option_values[opt] = True
if opt.startswith('--'):
false_opt = '--no-' + opt[2:]
self.option_values[false_opt] = False
option_strings.append(false_opt)
super(SwitchAction, self).__init__(option_strings, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, self.option_values[option_string])
def main(argv=None):
parser = argparse.ArgumentParser()
parser.add_argument('--prefix', help='where to install vee')
parser.add_argument('--url', default='https://github.com/westernx/vee.git')
parser.add_argument('--branch', default='master')
parser.add_argument('--force', action=SwitchAction, help='install over local changes')
parser.add_argument('--bashrc', action=SwitchAction, help='add vee to your ~/.bashrc file')
parser.add_argument('-y', '--yes', action='store_true', help='automatically confirm all prompts')
args = parser.parse_args(argv)
def get_arg(key, message, default):
value = getattr(args, key)
if value is not None:
return value
if args.yes:
return default
print '%s [%s]:' % (green(message), faint(default)),
res = raw_input().strip()
return res or default
def prompt_bool(message):
if args.yes:
return True
while True:
print '%s [%s]:' % (green(message), faint('Yn')),
res = raw_input().strip().lower()
if res in ('', 'y', 'yes'):
return True
if res in ('n', 'no'):
return False
def prompt_switch(key, message):
value = getattr(args, key)
if value is not None:
return value
return prompt_bool(message)
# Running as root is scary.
if not os.getuid():
warning('Running as root is dangerous.')
if not prompt_bool('Continue anyways?'):
return
# Make sure we have git.
if not check_output(['which', 'git']):
error('git was not found; cannot continue.')
return 2
# Determine where to install.
prefix = args.prefix or os.environ.get('VEE')
if not prefix:
prefix = get_arg('prefix', 'Where should we install VEE?', '/usr/local/vee')
prefix = os.path.abspath(prefix)
if not os.path.exists(os.path.dirname(prefix)):
warning('Directory above install location does not exist.')
if not prompt_bool('Are you sure you want to create it?'):
return
# Create directory and set permissions.
if not os.access(prefix, os.W_OK):
warning('No write access to %s' % os.path.dirname(prefix))
if not prompt_bool('Use sudo to make the directory?'):
return
check_output(['sudo', 'mkdir', '-p', prefix])
check_output(['sudo', 'chown', str(os.getuid()), prefix])
else:
makedirs(prefix)
vee_src = os.path.join(prefix, 'src')
# Init or clone the repo.
git_dir = os.path.join(vee_src, '.git')
if not os.path.exists(vee_src):
heading('Cloning', args.url)
check_call(['git', 'clone', args.url, vee_src])
else:
if not os.path.exists(git_dir):
heading('Initing repo on top of existing')
check_call(['git', '--git-dir', git_dir, '--work-tree', vee_src, 'init'])
check_call(['git', '--git-dir', git_dir, '--work-tree', vee_src, 'config', 'remote.origin.url', args.url])
check_call(['git', '--git-dir', git_dir, '--work-tree', vee_src, 'config', 'remote.origin.fetch', '+refs/heads/*:refs/remotes/origin/*'])
# Assert the repo is clean.
status = check_output(['git', '--git-dir', git_dir, '--work-tree', vee_src, 'status', '--porcelain']).strip()
if status:
warning('Repository is not clean.')
if not prompt_switch('force', 'Would you like to continue? All changes will be lost.'):
return
# Fetch and reset.
heading('Fetching updates from remote repo')
check_call(['git', '--git-dir', git_dir, '--work-tree', vee_src, 'fetch', 'origin', args.branch])
heading('Updating to master')
check_call(['git', '--git-dir', git_dir, '--work-tree', vee_src, 'reset', '--hard', 'FETCH_HEAD'])
heading('Cleaning ignored files')
check_call(['git', '--git-dir', git_dir, '--work-tree', vee_src, 'clean', '-dxf'], stdout=PIPE)
# Basic sanity checks.
heading('Performing self-check')
if not os.path.exists(os.path.join(vee_src, 'vee', '__init__.py')):
error('Repository does not appear to be vee; cannot continue.')
return 3
out = check_output([os.path.join(vee_src, 'bin', 'vee'), 'doctor', '--ping'])
if out.strip() != 'pong':
error('Basic self-check did not pass; try `vee doctor --ping`')
return 4
shell_lines = [
'export VEE="%s"' % prefix,
'export PATH="$VEE/src/bin:$PATH" # Add VEE to your environment',
]
if prompt_switch('bashrc', 'Append to your ~/.bashrc?'):
heading('Adding VEE to your ~/.bashrc')
print yellow('Note:'), bold('You may need to open a new terminal, or `source ~/.bashrc`, for VEE to work.')
bashrc = os.path.expanduser('~/.bashrc')
if os.path.exists(bashrc):
lines = list(open(bashrc))
else:
lines = []
# Strip out existing config.
lines = [
line for line in lines if
not (line.startswith('export VEE="') or line.startswith('export PATH="$VEE'))
]
content = ''.join(lines).rstrip() + '\n\n' + '\n'.join(shell_lines) + '\n'
with open(bashrc, 'w') as fh:
fh.write(content)
elif os.environ.get('VEE', '') != prefix:
heading('Add the following to your environment:')
for line in shell_lines:
print ' ' + line.split('#')[0]
heading('Done!')
print 'VEE will still need to be initialized via `vee init`.'
if __name__ == '__main__':
exit(main() or 0)