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 line
7.7 KiB

10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
  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()))