Bug 1048446 - [mozinstall] Add ability to download and extract installer from a url, r?whimboo
This is a minor convenience for downloading the installer from a url. It uses requests (which should be
available everywhere in-tree).
MozReview-Commit-ID: 8IfiVkYNr06
--- a/testing/mozbase/mozinstall/mozinstall/mozinstall.py
+++ b/testing/mozbase/mozinstall/mozinstall/mozinstall.py
@@ -3,19 +3,22 @@
# You can obtain one at http://mozilla.org/MPL/2.0/.
from optparse import OptionParser
import os
import shutil
import subprocess
import sys
import tarfile
+import tempfile
import time
import zipfile
+import requests
+
import mozfile
import mozinfo
try:
import pefile
has_pefile = True
except ImportError:
has_pefile = False
@@ -91,22 +94,31 @@ def get_binary(path, app_name):
def install(src, dest):
"""Install a zip, exe, tar.gz, tar.bz2 or dmg file, and return the path of
the installation folder.
:param src: Path to the install file
:param dest: Path to install to (to ensure we do not overwrite any existent
files the folder should not exist yet)
"""
+
+ if not is_installer(src):
+ msg = "{} is not a valid installer file".format(src)
+ if '://' in src:
+ try:
+ return _install_url(src, dest)
+ except:
+ exc, val, tb = sys.exc_info()
+ msg = "{} ({})".format(msg, val)
+ raise InvalidSource, msg, tb
+ raise InvalidSource(msg)
+
src = os.path.realpath(src)
dest = os.path.realpath(dest)
- if not is_installer(src):
- raise InvalidSource(src + ' is not valid installer file.')
-
did_we_create = False
if not os.path.exists(dest):
did_we_create = True
os.makedirs(dest)
trbk = None
try:
install_dir = None
@@ -232,16 +244,36 @@ def uninstall(install_folder):
# http://docs.python.org/library/sys.html#sys.exc_info
del trbk
# Ensure that we remove any trace of the installation. Even the uninstaller
# on Windows leaves files behind we have to explicitely remove.
mozfile.remove(install_folder)
+def _install_url(url, dest):
+ """Saves a url to a temporary file, and passes that through to the
+ install function.
+
+ :param url: Url to the install file
+ :param dest: Path to install to (to ensure we do not overwrite any existent
+ files the folder should not exist yet)
+ """
+ r = requests.get(url, stream=True)
+ name = tempfile.mkstemp()[1]
+ try:
+ with open(name, 'w+b') as fh:
+ for chunk in r.iter_content(chunk_size=16*1024):
+ fh.write(chunk)
+ result = install(name, dest)
+ finally:
+ mozfile.remove(name)
+ return result
+
+
def _install_dmg(src, dest):
"""Extract a dmg file into the destination folder and return the
application folder.
src -- DMG image which has to be extracted
dest -- the path to extract to
"""
--- a/testing/mozbase/mozinstall/setup.py
+++ b/testing/mozbase/mozinstall/setup.py
@@ -6,20 +6,21 @@ import os
from setuptools import setup
try:
here = os.path.dirname(os.path.abspath(__file__))
description = file(os.path.join(here, 'README.md')).read()
except IOError:
description = None
-PACKAGE_VERSION = '1.12'
+PACKAGE_VERSION = '1.13'
deps = ['mozinfo >= 0.7',
'mozfile >= 1.0',
+ 'requests',
]
setup(name='mozInstall',
version=PACKAGE_VERSION,
description="package for installing and uninstalling Mozilla applications",
long_description="see http://mozbase.readthedocs.org/",
# Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=['Environment :: Console',
--- a/testing/mozbase/mozinstall/tests/test.py
+++ b/testing/mozbase/mozinstall/tests/test.py
@@ -108,16 +108,20 @@ class TestMozInstall(unittest.TestCase):
elif mozinfo.isWin:
self.assertRaises(mozinstall.InvalidSource, mozinstall.install,
self.bz2, 'firefox')
elif mozinfo.isMac:
self.assertRaises(mozinstall.InvalidSource, mozinstall.install,
self.bz2, 'firefox')
+ # Test an invalid url handler
+ self.assertRaises(mozinstall.InvalidSource, mozinstall.install,
+ 'file://foo.bar', 'firefox')
+
@unittest.skipIf(mozinfo.isWin, "Bug 1157352 - We need a new firefox.exe "
"for mozinstall 1.12 and higher.")
def test_install(self):
""" Test mozinstall's install capability """
if mozinfo.isLinux:
installdir = mozinstall.install(self.bz2, self.tempdir)
self.assertEqual(os.path.join(self.tempdir, 'firefox'), installdir)
@@ -162,10 +166,11 @@ class TestMozInstall(unittest.TestCase):
mozinstall.uninstall(installdir_zip)
self.assertFalse(os.path.exists(installdir_zip))
elif mozinfo.isMac:
installdir = mozinstall.install(self.dmg, self.tempdir)
mozinstall.uninstall(installdir)
self.assertFalse(os.path.exists(installdir))
+
if __name__ == '__main__':
mozunit.main()