You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
7.7 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. from __future__ import print_function
  4. import os
  5. import platform
  6. import shutil
  7. import sys
  8. sys.path.append('bin')
  9. from autojump_argparse import ArgumentParser # noqa
  10. SUPPORTED_SHELLS = ('bash', 'zsh', 'fish', 'tcsh')
  11. def cp(src, dest, dryrun=False):
  12. print('copying file: %s -> %s' % (src, dest))
  13. if not dryrun:
  14. shutil.copy(src, dest)
  15. def get_shell():
  16. return os.path.basename(os.getenv('SHELL', ''))
  17. def mkdir(path, dryrun=False):
  18. print('creating directory:', path)
  19. if not dryrun and not os.path.exists(path):
  20. os.makedirs(path)
  21. def modify_autojump_sh(etc_dir, share_dir, dryrun=False):
  22. """Append custom installation path to autojump.sh"""
  23. custom_install = '\
  24. \n# check custom install \
  25. \nif [ -s %s/autojump.${shell} ]; then \
  26. \n source %s/autojump.${shell} \
  27. \nfi\n' % (share_dir, share_dir)
  28. with open(os.path.join(etc_dir, 'autojump.sh'), 'a') as f:
  29. f.write(custom_install)
  30. def modify_autojump_lua(clink_dir, bin_dir, dryrun=False):
  31. """Prepend custom AUTOJUMP_BIN_DIR definition to autojump.lua"""
  32. custom_install = "local AUTOJUMP_BIN_DIR = \"%s\"\n" % bin_dir.replace(
  33. '\\',
  34. '\\\\',
  35. )
  36. clink_file = os.path.join(clink_dir, 'autojump.lua')
  37. with open(clink_file, 'r') as f:
  38. original = f.read()
  39. with open(clink_file, 'w') as f:
  40. f.write(custom_install + original)
  41. def parse_arguments(): # noqa
  42. if platform.system() == 'Windows':
  43. default_user_destdir = os.path.join(
  44. os.getenv('LOCALAPPDATA', ''),
  45. 'autojump',
  46. )
  47. else:
  48. default_user_destdir = os.path.join(
  49. os.path.expanduser('~'),
  50. '.autojump',
  51. )
  52. default_user_prefix = ''
  53. default_user_zshshare = 'functions'
  54. default_system_destdir = '/'
  55. default_system_prefix = '/usr/local'
  56. default_system_zshshare = '/usr/share/zsh/site-functions'
  57. default_clink_dir = os.path.join(os.getenv('LOCALAPPDATA', ''), 'clink')
  58. parser = ArgumentParser(
  59. description='Installs autojump globally for root users, otherwise \
  60. installs in current user\'s home directory.'
  61. )
  62. parser.add_argument(
  63. '-n', '--dryrun', action='store_true', default=False,
  64. help='simulate installation',
  65. )
  66. parser.add_argument(
  67. '-f', '--force', action='store_true', default=False,
  68. help='skip root user, shell type, Python version checks',
  69. )
  70. parser.add_argument(
  71. '-d', '--destdir', metavar='DIR', default=default_user_destdir,
  72. help='set destination to DIR',
  73. )
  74. parser.add_argument(
  75. '-p', '--prefix', metavar='DIR', default=default_user_prefix,
  76. help='set prefix to DIR',
  77. )
  78. parser.add_argument(
  79. '-z', '--zshshare', metavar='DIR', default=default_user_zshshare,
  80. help='set zsh share destination to DIR',
  81. )
  82. parser.add_argument(
  83. '-c', '--clinkdir', metavar='DIR', default=default_clink_dir,
  84. help='set clink directory location to DIR (Windows only)',
  85. )
  86. parser.add_argument(
  87. '-s', '--system', action='store_true', default=False,
  88. help='install system wide for all users',
  89. )
  90. args = parser.parse_args()
  91. if not args.force:
  92. if sys.version_info[0] == 2 and sys.version_info[1] < 6:
  93. print('Python v2.6+ or v3.0+ required.', file=sys.stderr)
  94. sys.exit(1)
  95. if args.system:
  96. if platform.system() == 'Windows':
  97. print(
  98. 'System-wide installation is not supported on Windows.',
  99. file=sys.stderr,
  100. )
  101. sys.exit(1)
  102. elif os.geteuid() != 0:
  103. print(
  104. 'Please rerun as root for system-wide installation.',
  105. file=sys.stderr,
  106. )
  107. sys.exit(1)
  108. if platform.system() != 'Windows' \
  109. and get_shell() not in SUPPORTED_SHELLS:
  110. print(
  111. 'Unsupported shell: %s' % os.getenv('SHELL'),
  112. file=sys.stderr,
  113. )
  114. sys.exit(1)
  115. if args.destdir != default_user_destdir \
  116. or args.prefix != default_user_prefix \
  117. or args.zshshare != default_user_zshshare:
  118. args.custom_install = True
  119. else:
  120. args.custom_install = False
  121. if args.system:
  122. if args.custom_install:
  123. print(
  124. 'Custom paths incompatible with --system option.',
  125. file=sys.stderr,
  126. )
  127. sys.exit(1)
  128. args.destdir = default_system_destdir
  129. args.prefix = default_system_prefix
  130. args.zshshare = default_system_zshshare
  131. return args
  132. def show_post_installation_message(etc_dir, share_dir, bin_dir):
  133. if platform.system() == 'Windows':
  134. print('\nPlease manually add %s to your user path' % bin_dir)
  135. else:
  136. if get_shell() == 'fish':
  137. aj_shell = '%s/autojump.fish' % share_dir
  138. source_msg = 'if test -f %s; . %s; end' % (aj_shell, aj_shell)
  139. rcfile = '~/.config/fish/config.fish'
  140. else:
  141. aj_shell = '%s/autojump.sh' % etc_dir
  142. source_msg = '[[ -s %s ]] && source %s' % (aj_shell, aj_shell)
  143. if platform.system() == 'Darwin' and get_shell() == 'bash':
  144. rcfile = '~/.profile'
  145. else:
  146. rcfile = '~/.%src' % get_shell()
  147. print('\nPlease manually add the following line(s) to %s:' % rcfile)
  148. print('\n\t' + source_msg)
  149. if get_shell() == 'zsh':
  150. print('\n\tautoload -U compinit && compinit -u')
  151. print('\nPlease restart terminal(s) before running autojump.\n')
  152. def main(args):
  153. if args.dryrun:
  154. print('Installing autojump to %s (DRYRUN)...' % args.destdir)
  155. else:
  156. print('Installing autojump to %s ...' % args.destdir)
  157. bin_dir = os.path.join(args.destdir, args.prefix, 'bin')
  158. etc_dir = os.path.join(args.destdir, 'etc', 'profile.d')
  159. doc_dir = os.path.join(args.destdir, args.prefix, 'share', 'man', 'man1')
  160. share_dir = os.path.join(args.destdir, args.prefix, 'share', 'autojump')
  161. zshshare_dir = os.path.join(args.destdir, args.zshshare)
  162. mkdir(bin_dir, args.dryrun)
  163. mkdir(doc_dir, args.dryrun)
  164. mkdir(etc_dir, args.dryrun)
  165. mkdir(share_dir, args.dryrun)
  166. cp('./bin/autojump', bin_dir, args.dryrun)
  167. cp('./bin/autojump_argparse.py', bin_dir, args.dryrun)
  168. cp('./bin/autojump_data.py', bin_dir, args.dryrun)
  169. cp('./bin/autojump_match.py', bin_dir, args.dryrun)
  170. cp('./bin/autojump_utils.py', bin_dir, args.dryrun)
  171. cp('./bin/icon.png', share_dir, args.dryrun)
  172. cp('./docs/autojump.1', doc_dir, args.dryrun)
  173. if platform.system() == 'Windows':
  174. cp('./bin/autojump.lua', args.clinkdir, args.dryrun)
  175. cp('./bin/autojump.bat', bin_dir, args.dryrun)
  176. cp('./bin/j.bat', bin_dir, args.dryrun)
  177. cp('./bin/jc.bat', bin_dir, args.dryrun)
  178. cp('./bin/jo.bat', bin_dir, args.dryrun)
  179. cp('./bin/jco.bat', bin_dir, args.dryrun)
  180. if args.custom_install:
  181. modify_autojump_lua(args.clinkdir, bin_dir, args.dryrun)
  182. else:
  183. mkdir(etc_dir, args.dryrun)
  184. mkdir(share_dir, args.dryrun)
  185. mkdir(zshshare_dir, args.dryrun)
  186. cp('./bin/autojump.sh', etc_dir, args.dryrun)
  187. cp('./bin/autojump.bash', share_dir, args.dryrun)
  188. cp('./bin/autojump.fish', share_dir, args.dryrun)
  189. cp('./bin/autojump.zsh', share_dir, args.dryrun)
  190. cp('./bin/_j', zshshare_dir, args.dryrun)
  191. if args.custom_install:
  192. modify_autojump_sh(etc_dir, share_dir, args.dryrun)
  193. show_post_installation_message(etc_dir, share_dir, bin_dir)
  194. if __name__ == '__main__':
  195. sys.exit(main(parse_arguments()))