#!/usr/bin/env python3 # -*- coding: utf-8 -*- from __future__ import print_function import os import platform import shutil import sys sys.path.append('bin') from autojump_argparse import ArgumentParser # noqa SUPPORTED_SHELLS = ('bash', 'zsh', 'fish', 'tcsh') def cp(src, dest, dryrun=False): print('copying file: %s -> %s' % (src, dest)) if not dryrun: shutil.copy(src, dest) def get_shell(): return os.path.basename(os.getenv('SHELL', '')) def mkdir(path, dryrun=False): print('creating directory:', path) if not dryrun and not os.path.exists(path): os.makedirs(path) def modify_autojump_sh(etc_dir, share_dir, dryrun=False): """Append custom installation path to autojump.sh""" custom_install = '\ \n# check custom install \ \nif [ -s %s/autojump.${shell} ]; then \ \n source %s/autojump.${shell} \ \nfi\n' % (share_dir, share_dir) with open(os.path.join(etc_dir, 'autojump.sh'), 'a') as f: f.write(custom_install) def modify_autojump_lua(clink_dir, bin_dir, dryrun=False): """Prepend custom AUTOJUMP_BIN_DIR definition to autojump.lua""" custom_install = "local AUTOJUMP_BIN_DIR = \"%s\"\n" % bin_dir.replace( '\\', '\\\\', ) clink_file = os.path.join(clink_dir, 'autojump.lua') with open(clink_file, 'r') as f: original = f.read() with open(clink_file, 'w') as f: f.write(custom_install + original) def parse_arguments(): # noqa if platform.system() == 'Windows': default_user_destdir = os.path.join( os.getenv('LOCALAPPDATA', ''), 'autojump', ) else: default_user_destdir = os.path.join( os.path.expanduser('~'), '.autojump', ) default_user_prefix = '' default_user_zshshare = 'functions' default_system_destdir = '/' default_system_prefix = '/usr/local' default_system_zshshare = '/usr/share/zsh/site-functions' default_clink_dir = os.path.join(os.getenv('LOCALAPPDATA', ''), 'clink') parser = ArgumentParser( description='Installs autojump globally for root users, otherwise \ installs in current user\'s home directory.' ) parser.add_argument( '-n', '--dryrun', action='store_true', default=False, help='simulate installation', ) parser.add_argument( '-f', '--force', action='store_true', default=False, help='skip root user, shell type, Python version checks', ) parser.add_argument( '-d', '--destdir', metavar='DIR', default=default_user_destdir, help='set destination to DIR', ) parser.add_argument( '-p', '--prefix', metavar='DIR', default=default_user_prefix, help='set prefix to DIR', ) parser.add_argument( '-z', '--zshshare', metavar='DIR', default=default_user_zshshare, help='set zsh share destination to DIR', ) parser.add_argument( '-c', '--clinkdir', metavar='DIR', default=default_clink_dir, help='set clink directory location to DIR (Windows only)', ) parser.add_argument( '-s', '--system', action='store_true', default=False, help='install system wide for all users', ) args = parser.parse_args() if not args.force: if sys.version_info[0] == 2 and sys.version_info[1] < 6: print('Python v2.6+ or v3.0+ required.', file=sys.stderr) sys.exit(1) if args.system: if platform.system() == 'Windows': print( 'System-wide installation is not supported on Windows.', file=sys.stderr, ) sys.exit(1) elif os.geteuid() != 0: print( 'Please rerun as root for system-wide installation.', file=sys.stderr, ) sys.exit(1) if platform.system() != 'Windows' \ and get_shell() not in SUPPORTED_SHELLS: print( 'Unsupported shell: %s' % os.getenv('SHELL'), file=sys.stderr, ) sys.exit(1) if args.destdir != default_user_destdir \ or args.prefix != default_user_prefix \ or args.zshshare != default_user_zshshare: args.custom_install = True else: args.custom_install = False if args.system: if args.custom_install: print( 'Custom paths incompatible with --system option.', file=sys.stderr, ) sys.exit(1) args.destdir = default_system_destdir args.prefix = default_system_prefix args.zshshare = default_system_zshshare return args def show_post_installation_message(etc_dir, share_dir, bin_dir): if platform.system() == 'Windows': print('\nPlease manually add %s to your user path' % bin_dir) else: if get_shell() == 'fish': aj_shell = '%s/autojump.fish' % share_dir source_msg = 'if test -f %s; . %s; end' % (aj_shell, aj_shell) rcfile = '~/.config/fish/config.fish' else: aj_shell = '%s/autojump.sh' % etc_dir source_msg = '[[ -s %s ]] && source %s' % (aj_shell, aj_shell) if platform.system() == 'Darwin' and get_shell() == 'bash': rcfile = '~/.profile' else: rcfile = '~/.%src' % get_shell() print('\nPlease manually add the following line(s) to %s:' % rcfile) print('\n\t' + source_msg) if get_shell() == 'zsh': print('\n\tautoload -U compinit && compinit -u') print('\nPlease restart terminal(s) before running autojump.\n') def main(args): if args.dryrun: print('Installing autojump to %s (DRYRUN)...' % args.destdir) else: print('Installing autojump to %s ...' % args.destdir) bin_dir = os.path.join(args.destdir, args.prefix, 'bin') etc_dir = os.path.join(args.destdir, 'etc', 'profile.d') doc_dir = os.path.join(args.destdir, args.prefix, 'share', 'man', 'man1') share_dir = os.path.join(args.destdir, args.prefix, 'share', 'autojump') zshshare_dir = os.path.join(args.destdir, args.zshshare) mkdir(bin_dir, args.dryrun) mkdir(doc_dir, args.dryrun) mkdir(etc_dir, args.dryrun) mkdir(share_dir, args.dryrun) cp('./bin/autojump', bin_dir, args.dryrun) cp('./bin/autojump_argparse.py', bin_dir, args.dryrun) cp('./bin/autojump_data.py', bin_dir, args.dryrun) cp('./bin/autojump_match.py', bin_dir, args.dryrun) cp('./bin/autojump_utils.py', bin_dir, args.dryrun) cp('./bin/icon.png', share_dir, args.dryrun) cp('./docs/autojump.1', doc_dir, args.dryrun) if platform.system() == 'Windows': cp('./bin/autojump.lua', args.clinkdir, args.dryrun) cp('./bin/autojump.bat', bin_dir, args.dryrun) cp('./bin/j.bat', bin_dir, args.dryrun) cp('./bin/jc.bat', bin_dir, args.dryrun) cp('./bin/jo.bat', bin_dir, args.dryrun) cp('./bin/jco.bat', bin_dir, args.dryrun) if args.custom_install: modify_autojump_lua(args.clinkdir, bin_dir, args.dryrun) else: mkdir(etc_dir, args.dryrun) mkdir(share_dir, args.dryrun) mkdir(zshshare_dir, args.dryrun) cp('./bin/autojump.sh', etc_dir, args.dryrun) cp('./bin/autojump.bash', share_dir, args.dryrun) cp('./bin/autojump.fish', share_dir, args.dryrun) cp('./bin/autojump.zsh', share_dir, args.dryrun) cp('./bin/_j', zshshare_dir, args.dryrun) if args.custom_install: modify_autojump_sh(etc_dir, share_dir, args.dryrun) show_post_installation_message(etc_dir, share_dir, bin_dir) if __name__ == '__main__': sys.exit(main(parse_arguments()))