More robust installer with ability to save install preferences
parent
fe815f170d
commit
907446f97f
294
install.sh
294
install.sh
|
|
@ -1,88 +1,224 @@
|
|||
#!/usr/bin/env bash
|
||||
BASH_IT="$HOME/.bash_it"
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from os import path
|
||||
from optparse import OptionParser
|
||||
import ConfigParser
|
||||
from glob import glob
|
||||
|
||||
cp $HOME/.bash_profile $HOME/.bash_profile.bak
|
||||
HOME=os.getenv('HOME')
|
||||
BASH_IT=path.join(HOME, '.bash_it')
|
||||
BASH_PROFILE = path.join(HOME, '.bash_profile')
|
||||
|
||||
echo "Your original .bash_profile has been backed up to .bash_profile.bak"
|
||||
def confirm(prompt=None, default=False):
|
||||
"""
|
||||
Prompt the user for yes or no input.
|
||||
|
||||
cp $HOME/.bash_it/template/bash_profile.template.bash $HOME/.bash_profile
|
||||
Returns True or False
|
||||
"""
|
||||
if prompt is None:
|
||||
prompt = 'Confirm'
|
||||
|
||||
echo "Copied the template .bash_profile into ~/.bash_profile, edit this file to customize bash-it"
|
||||
if default:
|
||||
prompt = '%s [%s/%s]: ' % (prompt, 'Y', 'n')
|
||||
else:
|
||||
prompt = '%s [%s/%s]: ' % (prompt, 'y', 'N')
|
||||
|
||||
while True:
|
||||
ans = raw_input(prompt)
|
||||
if not ans:
|
||||
return default
|
||||
elif ans.lower() == 'y':
|
||||
return True
|
||||
elif ans.lower() == 'n':
|
||||
return False
|
||||
else:
|
||||
print 'Please enter y or n.'
|
||||
continue
|
||||
|
||||
while true
|
||||
do
|
||||
read -p "Do you use Jekyll? (If you don't know what Jekyll is, answer 'n') [Y/N] " RESP
|
||||
def ask(prompt, values, default=None):
|
||||
for i, v in enumerate(values):
|
||||
prompt += '\n %d. %s' % (i + 1, v)
|
||||
|
||||
case $RESP
|
||||
in
|
||||
[yY])
|
||||
cp $HOME/.bash_it/template/jekyllconfig.template.bash $HOME/.jekyllconfig
|
||||
echo "Copied the template .jekyllconfig into your home directory. Edit this file to customize bash-it for using the Jekyll plugins"
|
||||
break
|
||||
;;
|
||||
[nN])
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Please enter Y or N"
|
||||
esac
|
||||
done
|
||||
prompt += '\n Choice #?'
|
||||
|
||||
function load_all() {
|
||||
file_type=$1
|
||||
[ ! -d "$BASH_IT/$file_type/enabled" ] && mkdir "$BASH_IT/${file_type}/enabled"
|
||||
ln -s $BASH_IT/${file_type}/[^_]available/* "${BASH_IT}/${file_type}/enabled"
|
||||
}
|
||||
if default:
|
||||
prompt += ' [%s]' % default
|
||||
|
||||
function load_some() {
|
||||
file_type=$1
|
||||
for file in `ls $BASH_IT/${file_type}/available/[^_]*`
|
||||
do
|
||||
if [ ! -d "$BASH_IT/$file_type/enabled" ]
|
||||
then
|
||||
mkdir "$BASH_IT/$file_type/enabled"
|
||||
fi
|
||||
while true
|
||||
do
|
||||
read -p "Would you like to enable the ${file%.*.*} $file_type? [Y/N] " RESP
|
||||
case $RESP in
|
||||
[yY])
|
||||
ln -s "$BASH_IT/$file_type/available/$file" "$BASH_IT/$file_type/enabled"
|
||||
break
|
||||
;;
|
||||
[nN])
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Please choose y or n."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
}
|
||||
prompt += ': '
|
||||
|
||||
for type in "aliases" "plugins" "completion"
|
||||
do
|
||||
while true
|
||||
do
|
||||
read -p "Would you like to enable all, some, or no $type? Some of these may make bash slower to start up (especially completion). (all/some/none) " RESP
|
||||
case $RESP
|
||||
in
|
||||
some)
|
||||
load_some $type
|
||||
break
|
||||
;;
|
||||
all)
|
||||
load_all $type
|
||||
break
|
||||
;;
|
||||
none)
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Unknown choice. Please enter some, all, or none"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
min = 1
|
||||
max = len(values)
|
||||
options = range(min, max + 1)
|
||||
|
||||
while True:
|
||||
ans = raw_input(prompt)
|
||||
if not ans:
|
||||
return default
|
||||
|
||||
try:
|
||||
ans = int(ans)
|
||||
except ValueError:
|
||||
print('Please enter a number %d-%d' % (min, max))
|
||||
prompt = '#?: '
|
||||
continue
|
||||
|
||||
if ans in options:
|
||||
return values[ans - 1]
|
||||
else:
|
||||
print('Please enter a number %d-%d' % (min, max))
|
||||
prompt = '#?: '
|
||||
|
||||
|
||||
def is_bash_it_installed():
|
||||
if path.exists(BASH_PROFILE):
|
||||
f = open(BASH_PROFILE, 'r')
|
||||
installed = '$BASH_IT' in f.read()
|
||||
f.close()
|
||||
return installed
|
||||
return False
|
||||
|
||||
class Configurator(object):
|
||||
def __init__(self, config, prompt):
|
||||
self.config = config
|
||||
self.prompt = prompt
|
||||
|
||||
def getbool(self, key, default=False):
|
||||
section, key = key.split('.', 1)
|
||||
if self.config.has_option(section, key):
|
||||
val = self.config.getboolean(section, key)
|
||||
else:
|
||||
val = default
|
||||
|
||||
return val
|
||||
|
||||
def get(self, key, default=None):
|
||||
section, key = key.split('.', 1)
|
||||
if self.config.has_option(section, key):
|
||||
val = self.config.get(section, key)
|
||||
else:
|
||||
val = default
|
||||
|
||||
return val
|
||||
|
||||
def set(self, key, value):
|
||||
section, key = key.split('.', 1)
|
||||
if not self.config.has_section(section):
|
||||
self.config.add_section(section)
|
||||
|
||||
self.config.set(section, key, value)
|
||||
|
||||
def confirm(self, key, question, default=False):
|
||||
val = self.getbool(key, default)
|
||||
if self.prompt:
|
||||
val = confirm(question, val)
|
||||
|
||||
if val:
|
||||
self.set(key, 'yes')
|
||||
else:
|
||||
self.set(key, 'no')
|
||||
return val
|
||||
|
||||
def ask(self, key, question, values, default=None):
|
||||
val = self.get(key, default)
|
||||
|
||||
if self.prompt:
|
||||
val = ask(question, values, val)
|
||||
|
||||
self.set(key, val)
|
||||
return val
|
||||
|
||||
|
||||
def main(configfile=None, prompt=True):
|
||||
config = ConfigParser.RawConfigParser()
|
||||
if configfile:
|
||||
config.read(configfile)
|
||||
|
||||
conf = Configurator(config, prompt)
|
||||
|
||||
if is_bash_it_installed():
|
||||
print('Bash-it already installed, running configurator...')
|
||||
else:
|
||||
profile_name = path.basename(BASH_PROFILE)
|
||||
if conf.confirm('bash-it.install', 'Do you want to install bash-it into your %s?' % profile_name):
|
||||
print('Installing bash-it into %s...' % profile_name)
|
||||
if path.exists(BASH_PROFILE) and conf.confirm('bash-it.backup', 'Do you want to back up your %s?' % profile_name, True):
|
||||
shutil.copy(BASH_PROFILE, BASH_PROFILE + '.bak')
|
||||
print("Your original .bash_profile has been backed up to %s.bak" % profile_name)
|
||||
|
||||
shutil.copyfile(path.join(BASH_IT, 'template/bash_profile.template.bash'), BASH_PROFILE)
|
||||
|
||||
print("Copied the template .bash_profile into %s, edit this file to customize bash-it" % BASH_PROFILE)
|
||||
|
||||
|
||||
jekyll_config = path.join(HOME, '.jekyllconfig')
|
||||
if path.exists(jekyll_config):
|
||||
print('Jekyll config already installed.')
|
||||
elif conf.confirm('jekyll.install', 'Do you use Jekyll? (If you don\'t know what Jekyll is, answer "n")'):
|
||||
shutil.copyfile(path.join(BASH_IT, 'template/jekyllconfig.template.bash'), jekyll_config)
|
||||
print("Copied the template .jekyllconfig to %s. Edit this file to customize bash-it for using the Jekyll plugins" % jekyll_config)
|
||||
|
||||
for name, type in [('alias', 'aliases'), ('plugin', 'plugins'), ('completion', 'completion')]:
|
||||
resp = conf.ask('%s.install' % type, 'Would you like to enable all, some, or no %s? Some of these may make bash slower to start up (especially completion)' % type, values=['all', 'some', 'none'], default='all')
|
||||
install_dir = path.join(BASH_IT, type, 'enabled')
|
||||
|
||||
if resp in ['all', 'some'] and not path.exists(install_dir):
|
||||
os.makedirs(install_dir)
|
||||
|
||||
if resp in ['all', 'none']:
|
||||
config.remove_section(type)
|
||||
conf.set(type + '.install', resp)
|
||||
|
||||
for filename in glob(path.join(BASH_IT, type, 'available', '*')):
|
||||
plugin_filename = path.basename(filename)
|
||||
if plugin_filename.startswith('_'):
|
||||
continue
|
||||
|
||||
plugin_name, _ = plugin_filename.split('.', 1)
|
||||
|
||||
install_file = path.join(install_dir, plugin_filename)
|
||||
conf_key = '.'.join([type, plugin_name])
|
||||
|
||||
if resp == 'all' or (resp == 'some' and
|
||||
conf.confirm(conf_key, 'Would you like to enable the %s %s' % (plugin_name, name))):
|
||||
if path.exists(install_file):
|
||||
os.remove(install_file)
|
||||
|
||||
os.symlink(filename, install_file)
|
||||
print(' Installed %s %s' % (plugin_name, name))
|
||||
elif path.exists(install_file):
|
||||
os.remove(install_file)
|
||||
print(' Removed %s %s' % (plugin_name, name))
|
||||
|
||||
if conf.prompt:
|
||||
if confirm('Would you like to save your install preferences?'):
|
||||
filename = configfile or 'pref.ini'
|
||||
ans = raw_input('Where would you like to save to? [%s]:' % filename)
|
||||
if not ans:
|
||||
ans = filename
|
||||
|
||||
ans = path.join(BASH_IT, ans)
|
||||
|
||||
f = open(ans, 'w')
|
||||
config.write(f)
|
||||
f.close()
|
||||
print('Saved preferences to %s' % ans)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = OptionParser()
|
||||
parser.add_option('-c', '--config', dest='config',
|
||||
help='Config file to use', metavar="FILE")
|
||||
parser.add_option('-n', '--no-prompt', dest='no_prompt', action='store_true',
|
||||
help='Install without prompting.')
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if options.no_prompt and not options.config:
|
||||
parser.abort('You must supply a config to use without prompting.')
|
||||
|
||||
try:
|
||||
main(options.config, not options.no_prompt)
|
||||
except KeyboardInterrupt:
|
||||
print('\nCancelled by keyboard.')
|
||||
|
|
|
|||
Loading…
Reference in New Issue