-
Notifications
You must be signed in to change notification settings - Fork 12
/
tidal-bootstrap.command
executable file
·285 lines (222 loc) · 7.37 KB
/
tidal-bootstrap.command
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#!/usr/bin/env python
import os
import sys
import subprocess
deps = [
'SuperCollider.app',
'Atom.app',
'ghci'
]
# mimic unix which program
def which(program):
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file
return None
def app_exists(app_name):
def is_file(path):
return os.path.isdir(path) and path.endswith('.app')
app_dirs = ['/Applications', os.path.expanduser('~/Applications')]
for dir in app_dirs:
app_path = os.path.join(dir, app_name)
return is_file(app_path)
return None
class Colorize:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
def disable(self):
self.HEADER = ''
self.OKBLUE = ''
self.OKGREEN = ''
self.WARNING = ''
self.FAIL = ''
self.ENDC = ''
success_mark = Colorize.OKGREEN + u'\u2713' + Colorize.ENDC
error_mark = Colorize.FAIL + u'\u2717' + Colorize.ENDC
def parse_input():
""" Parse user input """
# raw_input returns the empty string for "enter"
yes = set(['yes', 'y', 'ye', ''])
no = set(['no', 'n'])
while True:
try:
choice = raw_input('-> ').lower()
if choice not in yes and choice not in no:
print "Please respond with 'yes' or 'no'"
continue
else:
if choice in yes:
return True
elif choice in no:
return False
except (KeyboardInterrupt, SystemExit):
sys.exit(0)
def is_installed(program):
if app_exists(program) or which(program):
print '\t' + success_mark, program
return True
else:
print '\t' + error_mark, program
return False
def setup_cask():
print "Setting up brew cask.. (this could take a while)"
return_code = subprocess.call(['brew', 'tap', 'caskroom/cask'])
if return_code != 0:
print "Could not setup `brew cask`, quitting."
sys.exit(0)
def check_brew():
if which('brew'):
# Get brew cask
setup_cask()
return
else:
print "\nThis script needs `brew` to run!"
print "Please install homebrew and run this script again."
print "Follow the instructions on the homebrew website:\n"
print "\t" + "http://brew.sh/"
sys.exit(0)
def welcome():
print "==============="
print "TIDAL BOOTSTRAP"
print "==============="
print "\nThis script will check if you have all dependencies (programs)"
print "installed on your system to begin working with TidalCycles.\n"
print ("If a dependency is missing the script will try "
+ "to download and install it for you.\n")
print "Do you wish to continue?"
print "y/n (or press Enter to continue)\n"
if parse_input():
return
else:
print "Okay, qutting."
sys.exit(0)
# TODO: Make this parallel using subprocess.Popen
def install_dep(cmd, name):
print "Installing:", name
if name == 'ghci':
name = 'haskell-platform'
command = cmd.split()
command.append(name)
return_code = subprocess.call(command)
if return_code != 0:
print "Could not install", name, "quitting."
sys.exit(0)
def install_app_dependencies(targets):
# See if user has installed homebrew, otherwise we quit here
check_brew()
for program in targets:
name, ext = os.path.splitext(program)
install_dep('brew cask install', name.lower())
print "\nAll app dependencies installed!"
def check_packages():
print "\nChecking packages.."
has_tidal = check_tidal()
has_atom_pkg = check_atom_plugin()
has_sc_quark = check_sc_quarks()
found_pkgs = [has_tidal, has_atom_pkg, has_sc_quark]
if found_pkgs.count(True) == 3:
print Colorize.OKGREEN + "\nAll packages are installed!"+Colorize.ENDC
elif not has_tidal or not has_atom_pkg:
print (
Colorize.WARNING
+ "Sorry, all packages could not be installed"
+ Colorize.ENDC
)
if not has_tidal:
print "Tidal cabal package could not be installed"
if not has_atom_pkg:
print "Atom tidal package could not be installed"
print ("Visit: http://tidalcycles.org/getting_started.html "
+ "and install them using the instructions found there")
if not has_sc_quark:
print ("Please open the file: "
+ Colorize.OKGREEN
+ "install-superdirt-quark.scd"
+ Colorize.ENDC
+ " in SuperCollider to install SuperDirt")
def check_atom_plugin():
print "Checking if tidal atom package is installed.."
try:
output = subprocess.check_output('apm list | grep tidal',
shell=True)
except subprocess.CalledProcessError, err:
output = err.output
if output:
print success_mark, output
return True
else:
return_code = subprocess.call(['apm', 'install', 'tidalcycles'])
if return_code != 0:
print "Could not install tidalcycles atom package!"
print "Try to install from Atom.app instead"
return False
else:
return True
def check_tidal():
print "Checking if tidal package is installed.."
try:
output = subprocess.check_output('ghc-pkg list | grep tidal',
shell=True)
except subprocess.CalledProcessError, err:
output = err.output
if output:
print success_mark, output
return True
else:
print "Installing tidal.."
return_code = subprocess.call(['cabal', 'install', 'tidal'])
if return_code != 0:
print "Could not install tidal!"
return False
else:
return True
def check_sc_quarks():
print "Checking if SuperDirt quark is installed.."
dirt_path = os.path.expanduser(
('~/Library/Application Support/SuperCollider'
+ '/downloaded-quarks/SuperDirt')
)
if not os.path.isdir(dirt_path):
print "SuperDirt quark was not found"
return False
else:
print success_mark, dirt_path
return True
def main():
welcome()
print "Checking dependencies..\n"
targets = []
for program in deps:
installed = is_installed(program)
if not installed:
targets.append(program)
if targets:
print "\nThe following dependencies needs to be installed:\n"
for dep in targets:
print Colorize.OKBLUE + '\t- ' + dep + Colorize.ENDC
print "\nDo you wish to install them?"
print "y/n (or press Enter to accept)\n"
if parse_input():
install_app_dependencies(targets)
else:
print "Okay, quitting."
sys.exit(0)
else:
print "\nAll app dependencies found!"
# See if we need to install additional packages
check_packages()
if __name__ == '__main__':
main()