-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsetup_camels.py
331 lines (269 loc) · 11.8 KB
/
setup_camels.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
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
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
import codecs
import os
import re
import subprocess
import sys
from pathlib import Path
# Add PYENV environment variables as the subprocesses won't know them before a restart of the installation
os.environ["PYENV"] = str(Path.home() / (Path(r".pyenv/pyenv-win")))
os.environ["PYENV_HOME"] = str(Path.home() / (Path(r".pyenv/pyenv-win")))
os.environ["PYENV_ROOT"] = str(Path.home() / (Path(r".pyenv/pyenv-win")))
os.environ["PATH"] += os.pathsep + str(Path.home() / (Path(r".pyenv/pyenv-win/bin")))
os.environ["PATH"] += os.pathsep + str(Path.home() / (Path(r".pyenv/pyenv-win/shims")))
def check_if_pyenv_installed() -> bool:
"""Checks to see if pyenv is already installed.
Pyenv is used to set up a clean python environemnt for CAMELS.
Parameters
----------
Returns
-------
bool
True if pyenv is already installed, False if it is not.
"""
if (subprocess.run(["powershell", "-ExecutionPolicy", "Bypass", "pyenv"],
stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NO_WINDOW, )).returncode == 0:
print('pyenv already installed')
return True
elif (subprocess.run(["powershell", "-ExecutionPolicy", "Bypass", "pyenv"],
stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NO_WINDOW, )).returncode == 1:
print('pyenv not installed')
return False
def run_pyenv_install(temp_path):
"""Installs pyenv using the official GitHub powershell script.
Uninstall with following command in command line: 'install-pyenv-win.ps1 -uninstall'
Parameters
----------
temp_path :
path to a temporary folder in {tmp} created by Inno Setup when installing.
This value is passed to this python script (and function) when running the InnoSetup
installer exe.
Returns
-------
None
Raises
-------
OSError
If it fails to run the installation script for pyenv.
"""
if subprocess.run(["powershell", "-ExecutionPolicy", "Bypass",
f'cd {temp_path};Invoke-WebRequest -UseBasicParsing -Uri '
'"https://raw.githubusercontent.com/pyenv-win/pyenv'
'-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile '
'"./install-pyenv-win.ps1"; '
'&"./install-pyenv-win.ps1";Remove-Item '
'./install-pyenv-win.ps1 '],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NO_WINDOW, ).returncode:
raise OSError(
f'Failed to run the install script install-pyenv-win.ps1 in path: {temp_path}')
def check_pyenv_version():
"""Executes `pyenv --version` in the installation path to check if pyenv installed properly
and returns the pyenv version.
Parameters
----------
Returns
-------
string
Contains the captured pyenv version for example `3.11.1`
Raises
-------
OSError
If it fails to run the pyenv --version command or if the version can't be read from the
stdout via re.search.
"""
ret = subprocess.run(["powershell", "-ExecutionPolicy", "Bypass", f'pyenv --version'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE,
creationflags=subprocess.CREATE_NO_WINDOW, )
if ret.returncode:
raise OSError('Failed to run the pyenv --version command')
ret = ret.stdout.decode('utf-8')
search = re.search(r'pyenv\s(\d.\d.?\d?)', ret)
version = search.group(1)
if version:
return version
else:
raise OSError('pyenv installation seems to have failed as no valid pyenv version '
'can be read')
def install_python_version(python_version):
"""
Parameters
----------
python_version : :obj:`str`
The python version that should be installed. Is hard coded in the
`main_setup_python_environment` function.
Returns
-------
None
Raises
-------
OSError
If it fails to run the `pyenv install` command.
"""
if subprocess.run(
["powershell", "-ExecutionPolicy", "Bypass", f'pyenv install {python_version}'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NO_WINDOW, ).returncode:
raise OSError(f'Failed to run "pyenv install {python_version}" successfully')
def set_local_python_version(nomad_camels_install_path, python_version):
"""
Parameters
----------
nomad_camels_install_path :
Path where NOMAD-CAMELS should be installed. This is set by the installation wizard
created with InnoSetup.
python_version : :obj:`str`
The python version that should be installed. Is hard coded in the
`main_setup_python_environment` function.
Returns
-------
None
"""
if os.path.isdir(nomad_camels_install_path):
pass
else:
raise OSError(f'Could not find the NOMAD-CAMELS folder: {nomad_camels_install_path}')
if subprocess.run(
["powershell", "-ExecutionPolicy", "Bypass", f'cd {nomad_camels_install_path};'
f'pyenv local {python_version}'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NO_WINDOW, ).returncode:
raise OSError(f'Failed to cd to {nomad_camels_install_path} and set local python '
f'version with pyenv local {python_version}')
def create_desertenv(nomad_camels_install_path):
"""
Parameters
----------
nomad_camels_install_path :
Path where NOMAD-CAMELS should be installed. This is set by the installation wizard
created with InnoSetup.
Returns
-------
None
Raises
-------
OSError
If it fails to run the `pyenv which python` command or fails to create a virtual
environment.
"""
ret = subprocess.run(
["powershell", "-ExecutionPolicy", "Bypass", f'cd {nomad_camels_install_path};'
'pyenv which python'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE, )
if ret.returncode:
raise OSError('Failed to run the "pyenv which python" command')
python_exe_path = ret.stdout.decode('utf-8').replace('\r\n', '')
if subprocess.run(
["powershell", "-ExecutionPolicy", "Bypass", f'cd {nomad_camels_install_path};'
f'{python_exe_path} -m venv .desertenv;'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NO_WINDOW, ).returncode:
raise OSError(f'Failed to create virtual env with "{python_exe_path} -m venv '
f'.desertenv" in {nomad_camels_install_path}')
def pip_install_camels(nomad_camels_install_path):
"""
Parameters
----------
nomad_camels_install_path :
Path where NOMAD-CAMELS should be installed. This is set by the installation wizard
created with InnoSetup.
Returns
-------
None
Raises
-------
OSError
If it fails to run the `pip install nomad-camels` command.
"""
if subprocess.run(
["powershell", "-ExecutionPolicy", "Bypass", f'cd {nomad_camels_install_path};'
r'.\.desertenv\Scripts\activate;'
f'pip install '
'--no-cache-dir nomad-camels'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NO_WINDOW, ).returncode:
raise OSError(f'Failed to pip install NOMAD-CAMELS')
def create_ini_file(nomad_camels_install_path):
"""Creates a .ini file with the python exe path and the camels start path.
This .ini file is used by the NOMAD-CAMELS.exe which is simply a wrapped .bat file
which runs these commands
Parameters
----------
nomad_camels_install_path : optional
Path where NOMAD-CAMELS should be installed. This is set by the installation wizard
created with InnoSetup.
Returns
-------
None
Raises
-------
OSError
If it fails to create the .ini file.
"""
if os.path.exists(
os.path.join(nomad_camels_install_path, r'.desertenv\Scripts\pythonw.exe')):
print('path exists')
python_exe_path = os.path.join(nomad_camels_install_path,
r'.desertenv\Scripts\pythonw.exe')
if os.path.exists(os.path.join(nomad_camels_install_path,
r'.desertenv\Lib\site-packages\nomad_camels\CAMELS_start.py')):
print('camels start exists')
camels_start_path = os.path.join(nomad_camels_install_path,
r'.desertenv\Lib\site-packages\nomad_camels\CAMELS_start.py')
if subprocess.run(
["powershell", "-ExecutionPolicy", "Bypass", f'cd {nomad_camels_install_path};'
fr'New-Item -Force -Path .\run\ '
'-Name "NOMAD-CAMELS.ini" -ItemType "file" -Value '
f'@"\npython_exe_path={python_exe_path}\n'
f'camels_start_path={camels_start_path}\n"@\n;'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NO_WINDOW, ).returncode:
print('failed subprocess call')
raise OSError(f'Failed to create the NOMAD-CAMELS.ini file with the (app) install path'
f'(and python path created with pyenv')
def main_setup_python_environment(nomad_camels_install_path=None,
temp_path=None):
"""Installs the correct python version using pyenv and then sets up the python environment.
The environment is installed into '.desertenv' in the NOMAD-CAMELS folder given by
`nomad_camels_install_path` which is created by the Inno Setup installer.
Parameters
----------
nomad_camels_install_path : optional
Path where NOMAD-CAMELS should be installed. This is set by the installation wizard
created with InnoSetup.
temp_path : optional
path to a temporary folder in {tmp} created by Inno Setup when installing.
This value is passed to this python script (and function) when running the InnoSetup
installer exe.
Returns
-------
None
"""
python_version = '3.11.3'
if check_if_pyenv_installed():
print('pyenv is already installed')
# pyenv_version = check_pyenv_version() # more for debugging purposes
else:
print('pyenv not installed')
run_pyenv_install(temp_path)
# pyenv_version = check_pyenv_version() # more for debugging purposes
print('install_python_version')
install_python_version(python_version)
print('set_local_python_version')
set_local_python_version(nomad_camels_install_path, python_version)
print('create_desertenv')
create_desertenv(nomad_camels_install_path)
print('pip_install_camels')
pip_install_camels(nomad_camels_install_path)
print('create_ini_file')
create_ini_file(nomad_camels_install_path)
if __name__ == '__main__':
temp_path_ = r'C:\Users\yh43epyd\AppData\Local\Temp\junk_tmp'
nomad_camels_install_path_ = r'C:\EAGLE-7.7.0\NOMAD-CAMELS'
if len(sys.argv) > 1:
nomad_camels_install_path_ = sys.argv[1]
temp_path_ = sys.argv[2]
main_setup_python_environment(nomad_camels_install_path=nomad_camels_install_path_,
temp_path=temp_path_)