From f374519f66c90132cf9dfc53a782533f0639f52d Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 12 Nov 2013 10:02:23 -0800 Subject: [PATCH 1/3] swc-windows-installer.py: Split out zip_install into its own function This makes it easy to install other packages besides nano. I've also added SHA1 checks to avoid installing packages that don't match the expected hash. This lets us trust ZipFile.extractall instead of extracting from a hard-coded list of approved files. --- swc-windows-installer.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/swc-windows-installer.py b/swc-windows-installer.py index 1ecd7149d..1904bbb89 100755 --- a/swc-windows-installer.py +++ b/swc-windows-installer.py @@ -20,6 +20,7 @@ """ +import hashlib try: # Python 3 from io import BytesIO as _BytesIO except ImportError: # Python 2 @@ -32,17 +33,28 @@ import zipfile +def zip_install(url, sha1, install_directory): + """Download and install a zipped bundle of compiled software""" + r = _urlopen(url) + zip_bytes = r.read() + download_sha1 = hashlib.sha1(zip_bytes).hexdigest() + if download_sha1 != sha1: + raise ValueError( + 'downloaded {!r} has the wrong SHA1 hash: {} != {}'.format( + url, downloaded_sha1, sha1)) + zip_io = _BytesIO(zip_bytes) + zip_file = zipfile.ZipFile(zip_io) + if not os.path.isdir(install_directory): + os.makedirs(install_directory) + zip_file.extractall(install_directory) + + def install_nano(install_directory): """Download and install the nano text editor""" - url = "http://www.nano-editor.org/dist/v2.2/NT/nano-2.2.6.zip" - r = _urlopen(url) - nano_zip_content = _BytesIO(r.read()) - nano_zip = zipfile.ZipFile(nano_zip_content) - nano_files = ['nano.exe', 'cygwin1.dll', 'cygintl-8.dll', - 'cygiconv-2.dll', 'cyggcc_s-1.dll'] - os.makedirs(install_directory) - for file_name in nano_files: - nano_zip.extract(file_name, install_directory) + zip_install( + url='http://www.nano-editor.org/dist/v2.2/NT/nano-2.2.6.zip', + sha1='f5348208158157060de0a4df339401f36250fe5b', + install_directory=install_directory) def create_nosetests_entry_point(python_scripts_directory): @@ -89,7 +101,7 @@ def main(): bin_dir = os.path.join(swc_dir, 'bin') create_nosetests_entry_point(python_scripts_directory=bin_dir) nano_dir = os.path.join(swc_dir, 'lib', 'nano') - install_nano(installation_directory=nano_dir) + install_nano(install_directory=nano_dir) update_bash_profile(extra_paths=(nano_dir, bin_dir)) From c6691358526b7f77e1d23649c765d605b554fb93 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 12 Nov 2013 10:05:08 -0800 Subject: [PATCH 2/3] swc-windows-installer.py: Only create the python-scripts dir if it doesn't exist os.makedirs, unlike 'mkdir -p', errors if the target directory already exists [1,2]. [1]: http://docs.python.org/2/library/os.html#os.makedirs "Raises an error exception if the leaf directory already exists or cannot be created" [2]: http://docs.python.org/3/library/os.html#os.makedirs "If exist_ok is False (the default), an OSError is raised if the target directory already exists." --- swc-windows-installer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/swc-windows-installer.py b/swc-windows-installer.py index 1904bbb89..3d2a790e8 100755 --- a/swc-windows-installer.py +++ b/swc-windows-installer.py @@ -67,6 +67,8 @@ def create_nosetests_entry_point(python_scripts_directory): ' sys.exit(nose.core.main())', '', ]) + if not os.path.isdir(python_scripts_directory): + os.makedirs(python_scripts_directory) with open(os.path.join(python_scripts_directory, 'nosetests'), 'w') as f: f.write(contents) From 70c97fca300d0f2cb9e7c565faa222ba1de9f3bb Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 13 Nov 2013 08:12:58 -0800 Subject: [PATCH 3/3] swc-windows-installer.py: Use regular expressions to POSIX-ify paths On a Windows 7 SP1 box with Python 2.7.3: >>> import os.path >>> os.path.expanduser('~') 'c:/Users/JohnDoe' That wasn't matching the previous POSIX-ification patterns, which assumed the drive prefix would be uppercase (C:). Now we use a regular expression to match both cases. --- swc-windows-installer.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/swc-windows-installer.py b/swc-windows-installer.py index 3d2a790e8..041642ac0 100755 --- a/swc-windows-installer.py +++ b/swc-windows-installer.py @@ -26,6 +26,7 @@ except ImportError: # Python 2 from StringIO import StringIO as _BytesIO import os +import re try: # Python 3 from urllib.request import urlopen as _urlopen except ImportError: # Python 2 @@ -93,9 +94,15 @@ def update_bash_profile(extra_paths=()): with open(config_path, 'a') as f: f.write('\n'.join(lines)) + def make_posix_path(windows_path): """Convert a Windows path to a posix path""" - return windows_path.replace('\\', '/').replace('C:', '/c') + for regex, sub in [ + (re.compile(r'\\'), '/'), + (re.compile('^[Cc]:'), '/c'), + ]: + windows_path = regex.sub(sub, windows_path) + return windows_path def main():