af72639516f12b8285927fc7feebf222a4c0e4ea
[swc-setup-windows-installer.git] / setup / swc-windows-installer.py
1 #!/usr/bin/env python
2
3 """Software Carpentry Windows Installer
4
5 Helps mimic a *nix environment on Windows with as little work as possible.
6
7 The script:
8 * Provides standard ipython operation for msysgit
9 * Provides standard nosetests behavior for msysgit
10 * Installs nano and makes it accessible from msysgit
11
12 To use:
13
14 1. Install Python, IPython, and Nose.  An easy way to do this is with
15    the Anaconda CE Python distribution
16    http://continuum.io/anacondace.html
17 2. Install msysgit
18    http://code.google.com/p/msysgit/downloads/list?q=full+installer+official+git
19 3. Run swc_windows_installer.py
20    You should be able to simply double click the file in Windows
21
22 """
23
24 try:  # Python 3
25     from io import BytesIO as _BytesIO
26 except ImportError:  # Python 2
27     from StringIO import StringIO as _BytesIO
28 import os.path
29 try:  # Python 3
30     from urllib.request import urlopen as _urlopen
31 except ImportError:  # Python 2
32     from urllib2 import urlopen as _urlopen
33 import zipfile
34
35
36 def install_nano(install_directory):
37     """Download and install the nano text editor"""
38     url = "http://www.nano-editor.org/dist/v2.2/NT/nano-2.2.6.zip"
39     r = _urlopen(url)
40     nano_zip_content = _BytesIO(r.read())
41     nano_zip = zipfile.ZipFile(nano_zip_content)
42     nano_files = ['nano.exe', 'cygwin1.dll', 'cygintl-8.dll',
43                   'cygiconv-2.dll', 'cyggcc_s-1.dll']
44     for file_name in nano_files:
45         nano_zip.extract(file_name, install_directory)
46
47 def create_ipython_entry_point(python_scripts_directory):
48     """Creates a terminal-based IPython entry point for msysgit"""
49     contents = '\n'.join([
50             '#!/usr/bin/env python',
51             'from IPython.frontend.terminal.ipapp import launch_new_instance',
52             'launch_new_instance()',
53             '',
54             ])
55     with open(os.path.join(python_scripts_directory, 'ipython'), 'w') as f:
56         f.write(contents)
57
58 def create_nosetests_entry_point(python_scripts_directory):
59     """Creates a terminal-based nosetests entry point for msysgit"""
60     contents = '\n'.join([
61             '#!/usr/bin/env/ python',
62             'import sys',
63             'import nose',
64             "if __name__ == '__main__':",
65             '    sys.exit(nose.core.main())',
66             '',
67             ])
68     with open(os.path.join(python_scripts_directory, 'nosetests'), 'w') as f:
69         f.write(contents)
70
71
72 def update_bash_profile(extra_paths=()):
73     """Create or append to a .bash_profile for Software Carpentry
74
75     Adds nano to the path, sets the default editor to nano, and adds
76     additional paths for other executables.
77     """
78     lines = [
79         '',
80         '# Add paths for Software-Carpentry-installed scripts and executables',
81         'export PATH=$PATH:{}'.format(':'.join(
82             make_posix_path(path) for path in extra_paths),),
83         '',
84         '# Make nano the default editor',
85         'export EDITOR=nano',
86         '',
87         ]
88     config_path = os.path.join(os.path.expanduser('~'), '.bash_profile')
89     with open(config_path, 'a') as f:
90         f.write('\n'.join(lines))
91
92 def make_posix_path(windows_path):
93     """Convert a Windows path to a posix path"""
94     return windows_path.replace('\\', '/').replace('C:', '/c')
95
96
97 def main():
98     home_dir = os.path.expanduser('~')
99     nano_dir = os.path.join(home_dir, '.nano')
100     bin_dir = os.path.join(home_dir, '.swc-bin')
101     create_ipython_entry_point(python_scripts_directory=bin_dir)
102     create_nosetests_entry_point(python_scripts_directory=bin_dir)
103     install_nano(installation_directory=nano_dir)
104     update_bash_profile(extra_paths=(bin_dir, nano_dir))
105
106
107 if __name__ == '__main__':
108     main()