2015-12-19 14:52:17 +01:00
|
|
|
#!/bin/sh
|
|
|
|
# This script helps you install Lektor on your computer. Right now it
|
|
|
|
# only supports Linux and OS X and only on OS X will it install the
|
|
|
|
# desktop version.
|
|
|
|
#
|
|
|
|
# For more information see https://www.getlektor.com/
|
|
|
|
|
|
|
|
# Wrap everything in a function so that we do not accidentally execute
|
|
|
|
# something we should not in case a truncated version of the script
|
|
|
|
# is executed.
|
|
|
|
I() {
|
|
|
|
set -u
|
|
|
|
|
2016-06-03 06:54:49 +02:00
|
|
|
if ! hash python 2> /dev/null; then
|
2015-12-19 14:52:17 +01:00
|
|
|
echo "Error: To use this script you need to have Python installed"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2016-06-03 06:54:49 +02:00
|
|
|
python - <<'EOF'
|
2015-12-19 14:52:17 +01:00
|
|
|
if 1:
|
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import json
|
|
|
|
import tempfile
|
2015-12-23 18:54:17 +01:00
|
|
|
import shutil
|
2018-12-04 19:48:16 +01:00
|
|
|
from subprocess import CalledProcessError, check_output, Popen
|
2017-06-16 16:50:54 +02:00
|
|
|
try:
|
|
|
|
from urllib.request import urlopen
|
|
|
|
except ImportError:
|
|
|
|
from urllib import urlopen
|
2015-12-19 14:52:17 +01:00
|
|
|
|
2016-06-03 06:54:49 +02:00
|
|
|
PY2 = sys.version_info[0] == 2
|
|
|
|
if PY2:
|
|
|
|
input = raw_input
|
2015-12-19 14:52:17 +01:00
|
|
|
|
|
|
|
sys.stdin = open('/dev/tty', 'r')
|
|
|
|
|
|
|
|
VENV_URL = "https://pypi.python.org/pypi/virtualenv/json"
|
|
|
|
KNOWN_BINS = ['/usr/local/bin', '/opt/local/bin',
|
|
|
|
os.path.join(os.environ['HOME'], '.bin'),
|
|
|
|
os.path.join(os.environ['HOME'], '.local', 'bin')]
|
|
|
|
|
2016-10-11 18:57:15 +02:00
|
|
|
if os.environ.get('LEKTOR_SILENT') == None:
|
|
|
|
prompt = True
|
|
|
|
else:
|
|
|
|
prompt = False
|
|
|
|
|
2015-12-19 14:52:17 +01:00
|
|
|
def find_user_paths():
|
|
|
|
rv = []
|
|
|
|
for item in os.environ['PATH'].split(':'):
|
|
|
|
if os.access(item, os.W_OK) \
|
|
|
|
and item not in rv \
|
|
|
|
and '/sbin' not in item:
|
|
|
|
rv.append(item)
|
|
|
|
return rv
|
|
|
|
|
|
|
|
def bin_sort_key(path):
|
|
|
|
try:
|
|
|
|
return KNOWN_BINS.index(path)
|
|
|
|
except ValueError:
|
|
|
|
return float('inf')
|
|
|
|
|
|
|
|
def find_locations(paths):
|
|
|
|
paths.sort(key=bin_sort_key)
|
|
|
|
for path in paths:
|
|
|
|
if path.startswith(os.environ['HOME']):
|
|
|
|
return path, os.path.join(os.environ['HOME'],
|
|
|
|
'.local', 'lib', 'lektor')
|
|
|
|
elif path.endswith('/bin'):
|
|
|
|
return path, os.path.join(
|
|
|
|
os.path.dirname(path), 'lib', 'lektor')
|
|
|
|
None, None
|
|
|
|
|
2015-12-25 12:26:52 +01:00
|
|
|
def get_confirmation():
|
|
|
|
while 1:
|
2016-06-03 06:54:49 +02:00
|
|
|
user_input = input('Continue? [Yn] ').lower().strip()
|
|
|
|
if user_input in ('', 'y'):
|
2015-12-25 12:26:52 +01:00
|
|
|
break
|
2016-06-03 06:54:49 +02:00
|
|
|
elif user_input == 'n':
|
2018-01-30 19:15:17 +01:00
|
|
|
print('')
|
2016-06-03 06:54:49 +02:00
|
|
|
print('Aborted!')
|
2015-12-25 12:26:52 +01:00
|
|
|
sys.exit()
|
|
|
|
|
2016-02-10 17:55:41 +01:00
|
|
|
def deletion_error(func, path, excinfo):
|
2016-06-03 06:54:49 +02:00
|
|
|
print('Problem deleting {}'.format(path))
|
|
|
|
print('Please try and delete {} manually'.format(path))
|
|
|
|
print('Aborted!')
|
2016-02-10 17:55:41 +01:00
|
|
|
sys.exit()
|
|
|
|
|
2015-12-25 12:26:52 +01:00
|
|
|
def wipe_installation(lib_dir, symlink_path):
|
|
|
|
if os.path.lexists(symlink_path):
|
|
|
|
os.remove(symlink_path)
|
|
|
|
if os.path.exists(lib_dir):
|
2016-02-10 17:55:41 +01:00
|
|
|
shutil.rmtree(lib_dir, onerror=deletion_error)
|
2015-12-25 12:26:52 +01:00
|
|
|
|
|
|
|
def check_installation(lib_dir, bin_dir):
|
|
|
|
symlink_path = os.path.join(bin_dir, 'lektor')
|
|
|
|
if os.path.exists(lib_dir) or os.path.lexists(symlink_path):
|
2016-06-03 06:54:49 +02:00
|
|
|
print(' Lektor seems to be installed already.')
|
|
|
|
print(' Continuing will delete:')
|
|
|
|
print(' %s' % lib_dir)
|
|
|
|
print(' and remove this symlink:')
|
|
|
|
print(' %s' % symlink_path)
|
2018-01-30 19:15:17 +01:00
|
|
|
print('')
|
2018-01-18 00:18:31 +01:00
|
|
|
if prompt:
|
|
|
|
get_confirmation()
|
2018-01-30 19:15:17 +01:00
|
|
|
print('')
|
2015-12-25 12:26:52 +01:00
|
|
|
wipe_installation(lib_dir, symlink_path)
|
|
|
|
|
2015-12-19 14:52:17 +01:00
|
|
|
def fail(message):
|
2016-06-03 06:54:49 +02:00
|
|
|
print('Error: %s' % message)
|
2015-12-19 14:52:17 +01:00
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
def install(virtualenv_url, lib_dir, bin_dir):
|
|
|
|
t = tempfile.mkdtemp()
|
|
|
|
Popen('curl -sf "%s" | tar -xzf - --strip-components=1' %
|
|
|
|
virtualenv_url, shell=True, cwd=t).wait()
|
2015-12-23 18:54:17 +01:00
|
|
|
|
2015-12-19 14:52:17 +01:00
|
|
|
try:
|
|
|
|
os.makedirs(lib_dir)
|
|
|
|
except OSError:
|
|
|
|
pass
|
2018-12-04 19:48:16 +01:00
|
|
|
try:
|
|
|
|
check_output([sys.executable, './src/virtualenv.py', lib_dir], cwd=t)
|
|
|
|
except CalledProcessError: # virtualenv 16.1.0, 17+
|
|
|
|
Popen([sys.executable, './virtualenv.py', lib_dir], cwd=t).wait()
|
2015-12-19 14:52:17 +01:00
|
|
|
Popen([os.path.join(lib_dir, 'bin', 'pip'),
|
2015-12-25 12:26:52 +01:00
|
|
|
'install', '--upgrade', 'Lektor']).wait()
|
2015-12-19 14:52:17 +01:00
|
|
|
os.symlink(os.path.join(lib_dir, 'bin', 'lektor'),
|
2015-12-25 12:26:52 +01:00
|
|
|
os.path.join(bin_dir, 'lektor'))
|
2015-12-19 14:52:17 +01:00
|
|
|
|
|
|
|
def main():
|
2018-01-30 19:15:17 +01:00
|
|
|
print('')
|
2016-06-03 06:54:49 +02:00
|
|
|
print('Welcome to Lektor')
|
2018-01-30 19:15:17 +01:00
|
|
|
print('')
|
2016-06-03 06:54:49 +02:00
|
|
|
print('This script will install Lektor on your computer.')
|
2018-01-30 19:15:17 +01:00
|
|
|
print('')
|
2015-12-19 14:52:17 +01:00
|
|
|
|
|
|
|
paths = find_user_paths()
|
|
|
|
if not paths:
|
|
|
|
fail('None of the items in $PATH are writable. Run with '
|
|
|
|
'sudo or add a $PATH item that you have access to.')
|
|
|
|
|
|
|
|
bin_dir, lib_dir = find_locations(paths)
|
|
|
|
if bin_dir is None or lib_dir is None:
|
|
|
|
fail('Could not determine installation location for Lektor.')
|
|
|
|
|
2015-12-25 12:26:52 +01:00
|
|
|
check_installation(lib_dir, bin_dir)
|
|
|
|
|
2016-06-03 06:54:49 +02:00
|
|
|
print('Installing at:')
|
|
|
|
print(' bin: %s' % bin_dir)
|
|
|
|
print(' app: %s' % lib_dir)
|
2018-01-30 19:15:17 +01:00
|
|
|
print('')
|
2015-12-19 14:52:17 +01:00
|
|
|
|
2016-10-11 18:57:15 +02:00
|
|
|
if prompt: get_confirmation()
|
2015-12-19 14:52:17 +01:00
|
|
|
|
Update install.sh
Fix to avoid "TypeError: the JSON object must be str, not 'bytes'" error while installing.
Traceback:
curl -sf https://www.getlektor.com/install.sh | sudo sh
Welcome to Lektor
This script will install Lektor on your computer.
Installing at:
bin: /usr/local/bin
app: /usr/local/lib/lektor
Continue? [Yn] y
Traceback (most recent call last):
File "<stdin>", line 142, in <module>
File "<stdin>", line 130, in main
File "/usr/lib/python3.5/json/__init__.py", line 268, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "/usr/lib/python3.5/json/__init__.py", line 312, in loads
s.__class__.__name__))
TypeError: the JSON object must be str, not 'bytes'
2017-11-19 10:19:49 +01:00
|
|
|
for url in json.loads(urlopen(VENV_URL).read().decode('utf-8'))['urls']:
|
2015-12-19 14:52:17 +01:00
|
|
|
if url['python_version'] == 'source':
|
|
|
|
virtualenv = url['url']
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
fail('Could not find virtualenv')
|
|
|
|
|
|
|
|
install(virtualenv, lib_dir, bin_dir)
|
|
|
|
|
2018-01-30 19:15:17 +01:00
|
|
|
print('')
|
2016-06-03 06:54:49 +02:00
|
|
|
print('All done!')
|
2015-12-19 14:52:17 +01:00
|
|
|
|
|
|
|
main()
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
I
|