-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsanguine-bootstrap.py
133 lines (116 loc) · 6.21 KB
/
sanguine-bootstrap.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
import os
import re
import subprocess
import sys
import traceback
sys.path.append(os.path.split(os.path.abspath(__file__))[0])
from sanguine.install.install_common import *
from sanguine.install.install_helpers import run_installer, find_command_and_add_to_path
from sanguine.install.install_github import github_project_exists, clone_github_project, GithubFolder
from sanguine.install.simple_download import pattern_from_url, download_temp
from sanguine.install.install_checks import report_hostile_programs, safe_call
from sanguine.install.install_ui import InstallUI
__version__ = '0.1.3c'
# TODO: eat pre-prompt input using msvcrt.kbhit()
# TODO: progress or at least "I'm alive" pseudo-progress while downloading/installing
# TODO: consider [optional] install of GitHub Desktop (to install-dependencies.py?)
# TODO: icacls replacement (apparently, icacls is not always available); try https://stackoverflow.com/a/27500472/28537706
_MODDERS_ANONYMOUS = 'modders-anonymous'
_SANGUINE_ROSE = 'sanguine-rose'
_GHFOLDER = GithubFolder(_MODDERS_ANONYMOUS + '/' + _SANGUINE_ROSE)
ui = InstallUI()
try:
add_file_logging(os.path.splitext(sys.argv[0])[0] + '.log.html')
safe_call(['echo', 'Starting'] + sys.argv + ['...'],
shell=True) # for a mystical reason, launching an external process which prints something to the screen, solves console color issues
info('Sanguine bootstrapper version {}...'.format(__version__))
info('Bootstrapper .exe bundled Python version: {}'.format(sys.version))
report_hostile_programs(ui)
for arg in sys.argv[1:]:
if arg.lower() == '/silent':
ui.set_silent_mode()
info('Silent mode enabled')
alert('This will install sanguine-rose from scratch, including, if necessary, installing python and/or git.')
choice = ui.message_box('Do you want to proceed?', ['Yes', 'no'])
if choice == 'no':
alert('Exiting.')
sys.exit()
### download and install python
pyok = find_command_and_add_to_path(['py', '--version'], shell=True)
if pyok:
info('py found, no need to download and install python')
else:
info('py not found, will try to download and install python')
dlurl = pattern_from_url('https://python.org/downloads/',
r'(https://www\.python\.org/ftp/python/3\.[0-9.]*/python-3\.[0-9.]*-amd64.exe)')
raise_if_not(len(dlurl) == 1)
info('Downloading {}...'.format(dlurl[0]))
pyinstallexe = download_temp(dlurl[0], ui.network_error_handler(2))
run_installer(ui, [pyinstallexe, '/quiet', 'InstallAllUsers=1', 'PrependPath=1'], 'python.org',
'Installing python... Installer runs in silent mode and may take up to 5 minutes.')
info('Python installer finished.')
pyok = find_command_and_add_to_path(['py', '--version'], shell=True)
raise_if_not(pyok)
info('Python is available now.')
gitok = find_command_and_add_to_path(['git', '--version'])
if gitok:
info('git found, no need to download and install it')
else:
info('git not found, will try to download and install it')
tags = pattern_from_url('https://gitforwindows.org/',
r'https://github.com/git-for-windows/git/releases/tag/([a-zA-Z0-9.]*)"')
raise_if_not(len(tags) == 1)
tag = tags[0]
m = re.match(r'v([0-9.]*)\.windows\.[0-9]*', tag)
raise_if_not(bool(m))
ver = m.group(1)
url = 'https://github.com/git-for-windows/git/releases/download/{}/Git-{}-64-bit.exe'.format(tag, ver)
info('Downloading {}...'.format(url))
gitinstallexe = download_temp(url, ui.network_error_handler(2))
run_installer(ui, [gitinstallexe, '/SP-', '/VERYSILENT', '/SUPPRESSMSGBOXES', '/NORESTART'], 'github.com',
'Installing git... Installer runs in silent mode and may take up to 5 minutes.')
info('Git installer finished.')
gitok = find_command_and_add_to_path(['git', '--version'], shell=True)
raise_if_not(gitok)
info('Git is available now.')
skiprepo = False
while True:
githubdir = ui.input_box('Where do you want to keep your Github projects (including sanguine-rose)?',
'C:\\Modding\\GitHub', level=LinearUIImportance.Important)
if os.path.isdir(githubdir):
ok = github_project_exists(githubdir, _GHFOLDER)
if ok == 1:
info(
'It seems that you already have {} cloned. Will proceed without cloning {}.'.format(_SANGUINE_ROSE,
_SANGUINE_ROSE))
skiprepo = True
break
if ok == -1:
alert('Folder {}\\{}\\{} already exists. Please choose another folder for GitHub projects.'.format(
githubdir, _GHFOLDER.author, _GHFOLDER.project))
else:
assert ok == 0
break
else:
break
if not skiprepo:
clone_github_project(githubdir, _GHFOLDER,
ui.network_error_handler(2), adjustpermissions=True)
sanguinedir = _GHFOLDER.folder(githubdir)
info(
'Bootstrapping completed. Now you do not need {} anymore, and should use scripts in {} instead.'.format(
sys.argv[0], sanguinedir))
info('You still need to run {}\\sanguine-install-dependencies.py'.format(sanguinedir))
choice = ui.message_box('Do you want to run it now?', ['Yes', 'no'], level=LinearUIImportance.Important)
if choice == 'no':
info('{}\\sanguine-install-dependencies.py was not run, make sure to run it before using sanguine-rose'.format(
sanguinedir))
else:
cmd = '{}\\sanguine-install-dependencies.py'.format(sanguinedir)
info('Running {}...'.format(cmd))
ok = subprocess.check_call(
['py', cmd] + sys.argv[1:]) # should not use shell=True here, seems to cause trouble on the very first run
except Exception as e:
critical('Exception: {}'.format(e))
alert(traceback.format_exc())
ui.confirm_box('Press any key to exit {}'.format(sys.argv[0]), level=LinearUIImportance.VeryImportant)