diff --git a/python/mozbuild/mozbuild/action/exe_7z_archive.py b/python/mozbuild/mozbuild/action/exe_7z_archive.py index 6a079df9fa49..16ba4290bd99 100644 --- a/python/mozbuild/mozbuild/action/exe_7z_archive.py +++ b/python/mozbuild/mozbuild/action/exe_7z_archive.py @@ -13,14 +13,21 @@ import mozpack.path as mozpath def archive_exe(pkg_dir, tagfile, sfx_package, package): tmpdir = tempfile.mkdtemp(prefix='tmp') - subprocess.check_call(['upx', '--best', '-o', mozpath.join(tmpdir, '7zSD.sfx'), sfx_package]) - shutil.move(pkg_dir, 'core') - subprocess.check_call(['7z', 'a', '-r', '-t7z', mozpath.join(tmpdir, 'app.7z'), '-mx', '-m0=BCJ2', '-m1=LZMA:d25', '-m2=LZMA:d19', '-m3=LZMA:d19', '-mb0:1', '-mb0s1:2', '-mb0s2:3']) - shutil.move('core', pkg_dir) - with open(package, 'wb') as o: - for i in [mozpath.join(tmpdir, '7zSD.sfx'), tagfile, mozpath.join(tmpdir, 'app.7z')]: - shutil.copyfileobj(open(i, 'rb'), o) - os.chmod(package, 0755) + try: + if pkg_dir: + shutil.move(pkg_dir, 'core') + subprocess.check_call(['upx', '--best', '-o', mozpath.join(tmpdir, '7zSD.sfx'), sfx_package]) + + subprocess.check_call(['7z', 'a', '-r', '-t7z', mozpath.join(tmpdir, 'app.7z'), '-mx', '-m0=BCJ2', '-m1=LZMA:d25', '-m2=LZMA:d19', '-m3=LZMA:d19', '-mb0:1', '-mb0s1:2', '-mb0s2:3']) + + with open(package, 'wb') as o: + for i in [mozpath.join(tmpdir, '7zSD.sfx'), tagfile, mozpath.join(tmpdir, 'app.7z')]: + shutil.copyfileobj(open(i, 'rb'), o) + os.chmod(package, 0755) + finally: + if pkg_dir: + shutil.move('core', pkg_dir) + shutil.rmtree(tmpdir) def main(args): if len(args) != 4: diff --git a/python/mozbuild/mozbuild/mach_commands.py b/python/mozbuild/mozbuild/mach_commands.py index b3ac0826f803..05a6b1fe996e 100644 --- a/python/mozbuild/mozbuild/mach_commands.py +++ b/python/mozbuild/mozbuild/mach_commands.py @@ -1963,3 +1963,17 @@ class Repackage(MachCommandBase): from mozbuild.repackaging.dmg import repackage_dmg repackage_dmg(input, output) + + @SubCommand('repackage', 'installer', + description='Repackage into a Windows installer exe') + @CommandArgument('--tag', type=str, required=True, + help='The .tag file used to build the installer') + @CommandArgument('--setupexe', type=str, required=True, + help='setup.exe file inside the installer') + @CommandArgument('--package', type=str, required=False, + help='Optional package .zip for building a full installer') + @CommandArgument('--output', '-o', type=str, required=True, + help='Output filename') + def repackage_installer(self, tag, setupexe, package, output): + from mozbuild.repackaging.installer import repackage_installer + repackage_installer(self.topsrcdir, tag, setupexe, package, output) diff --git a/python/mozbuild/mozbuild/repackaging/installer.py b/python/mozbuild/mozbuild/repackaging/installer.py new file mode 100644 index 000000000000..fdd261503fa4 --- /dev/null +++ b/python/mozbuild/mozbuild/repackaging/installer.py @@ -0,0 +1,45 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +import os +import tempfile +import shutil +import zipfile +import mozpack.path as mozpath +from mozbuild.action.exe_7z_archive import archive_exe +from mozbuild.util import ensureParentDir + +def repackage_installer(topsrcdir, tag, setupexe, package, output): + if package and not zipfile.is_zipfile(package): + raise Exception("Package file %s is not a valid .zip file." % package) + + # We need the full path for the tag and output, since we chdir later. + tag = mozpath.realpath(tag) + output = mozpath.realpath(output) + ensureParentDir(output) + + tmpdir = tempfile.mkdtemp() + old_cwd = os.getcwd() + try: + if package: + z = zipfile.ZipFile(package) + z.extractall(tmpdir) + z.close() + + # Copy setup.exe into the root of the install dir, alongside the + # package. + shutil.copyfile(setupexe, mozpath.join(tmpdir, mozpath.basename(setupexe))) + + # archive_exe requires us to be in the directory where the package is + # unpacked (the tmpdir) + os.chdir(tmpdir) + + sfx_package = mozpath.join(topsrcdir, 'other-licenses/7zstub/firefox/7zSD.sfx') + + package_name = 'firefox' if package else None + archive_exe(package_name, tag, sfx_package, output) + + finally: + os.chdir(old_cwd) + shutil.rmtree(tmpdir)