def run(self): from plover_build_utils.install_wheels import WHEELS_CACHE # Download helper. from plover_build_utils.download import download # Run command helper. def run(*args): if self.verbose: log.info('running %s', ' '.join(a for a in args)) subprocess.check_call(args) # First things first: create Plover wheel. wheel_cmd = self.get_finalized_command('bdist_wheel') wheel_cmd.run() plover_wheel = glob.glob( os.path.join(wheel_cmd.dist_dir, wheel_cmd.wheel_dist_name) + '*.whl')[0] # Setup embedded Python distribution. # Note: python35.zip is decompressed to prevent errors when 2to3 # is used (including indirectly by setuptools `build_py` command). py_embedded = download( 'https://www.python.org/ftp/python/3.5.2/python-3.5.2-embed-win32.zip', 'a62675cd88736688bb87999e8b86d13ef2656312') dist_dir = os.path.join(wheel_cmd.dist_dir, PACKAGE + '-win32') data_dir = os.path.join(dist_dir, 'data') stdlib = os.path.join(data_dir, 'python35.zip') if os.path.exists(dist_dir): shutil.rmtree(dist_dir) os.makedirs(data_dir) for path in (py_embedded, stdlib): with zipfile.ZipFile(path) as zip: zip.extractall(data_dir) os.unlink(stdlib) dist_py = os.path.join(data_dir, 'python.exe') # Install pip/wheel. run(dist_py, '-m', 'plover_build_utils.get_pip') # Install Plover + standard plugins and dependencies. # Note: do not use the embedded Python executable with `setup.py # install` to prevent setuptools from installing extra development # dependencies... run(dist_py, '-m', 'plover_build_utils.install_wheels', '-r', 'requirements_distribution.txt') run(dist_py, '-m', 'plover_build_utils.install_wheels', '--ignore-installed', '--no-deps', plover_wheel) run(dist_py, '-m', 'plover_build_utils.install_wheels', '-r', 'requirements_plugins.txt') os.unlink(os.path.join(WHEELS_CACHE, os.path.basename(plover_wheel))) # Trim the fat... if self.trim: from plover_build_utils.trim import trim trim(data_dir, 'windows/dist_blacklist.txt', verbose=self.verbose) # Add miscellaneous files: icon, license, ... for src, target_dir in (('LICENSE.txt', '.'), ('plover/assets/plover.ico', 'data')): dst = os.path.join(dist_dir, target_dir, os.path.basename(src)) shutil.copyfile(src, dst) # Create launchers. for entrypoint, gui in ( ('plover = plover.main:main', True), ('plover_console = plover.main:main', False), ): run( dist_py, '-c', textwrap.dedent(''' from pip._vendor.distlib.scripts import ScriptMaker sm = ScriptMaker(source_dir='{dist_dir}', target_dir='{dist_dir}') sm.executable = 'data\\python.exe' sm.variants = set(('',)) sm.make('{entrypoint}', options={{'gui': {gui}}}) '''.rstrip()).format(dist_dir=dist_dir, entrypoint=entrypoint, gui=gui)) # Make distribution source-less. run( dist_py, '-m', 'plover_build_utils.source_less', # Don't touch pip._vendor.distlib sources, # or `pip install` will not be usable... data_dir, '*/pip/_vendor/distlib/*', ) # Check requirements. run(dist_py, '-m', 'plover_build_utils.check_requirements') # Zip results. if self.zipdir: from plover_build_utils.zipdir import zipdir if self.verbose: log.info('zipping %s', dist_dir) zipdir(dist_dir) # Create an installer. if self.installer: installer_exe = '%s.setup.exe' % dist_dir # Compute install size for "Add/Remove Programs" entry. install_size = sum( os.path.getsize(os.path.join(dirpath, f)) for dirpath, dirnames, filenames in os.walk(dist_dir) for f in filenames) run('makensis.exe', '-NOCD', '-Dsrcdir=' + dist_dir, '-Dversion=' + __version__, '-Dinstall_size=' + str(install_size // 1024), 'windows/installer.nsi', '-XOutFile ' + installer_exe)
def run(self): from plover_build_utils.install_wheels import WHEELS_CACHE # Download helper. from plover_build_utils.download import download # First things first: create Plover wheel. wheel_cmd = self.get_finalized_command('bdist_wheel') wheel_cmd.run() plover_wheel = glob.glob(os.path.join(wheel_cmd.dist_dir, wheel_cmd.wheel_dist_name) + '*.whl')[0] # Setup embedded Python distribution. # Note: python36.zip is decompressed to prevent errors when 2to3 # is used (including indirectly by setuptools `build_py` command). py_embedded = download('https://www.python.org/ftp/python/3.6.3/python-3.6.3-embed-win32.zip', '3769c2129779b43f2dade3b89c783d957bff1461') dist_dir = os.path.join(wheel_cmd.dist_dir, PACKAGE + '-win32') dist_data = os.path.join(dist_dir, 'data') dist_py = os.path.join(dist_data, 'python.exe') dist_stdlib = os.path.join(dist_data, 'python36.zip') if os.path.exists(dist_dir): shutil.rmtree(dist_dir) os.makedirs(dist_data) for path in (py_embedded, dist_stdlib): with zipfile.ZipFile(path) as zip: zip.extractall(dist_data) os.unlink(dist_stdlib) # We don't want a completely isolated Python when using # python.exe/pythonw.exe directly, we need a working site # directory and for the current directory to be prepended # to `sys.path` so `plover_build_utils` can be used and # plugins can be installed from source. dist_pth = os.path.join(dist_data, 'python36._pth') with open(dist_pth, 'r+') as fp: pth = fp.read() + 'import site\n' fp.seek(0) fp.write(pth) dist_site_packages = os.path.join(dist_data, 'Lib', 'site-packages') os.makedirs(dist_site_packages) with open(os.path.join(dist_site_packages, 'sitecustomize.py'), 'w') as fp: fp.write(textwrap.dedent( ''' import os, sys sys.path.insert(0, os.getcwd()) ''' ).lstrip()) # Use standard site.py so user site packages are enabled. site_py = download('https://github.com/python/cpython/raw/v3.6.3/Lib/site.py', '5b5a92032c666e0e30c0b2665b8acffe2a624641') shutil.copyfile(site_py, os.path.join(dist_site_packages, 'site.py')) # Run command helper. def run(*args): if self.verbose: log.info('running %s', ' '.join(a for a in args)) subprocess.check_call(args) def pyrun(*args): run(dist_py, '-E', '-s', *args) # Install pip/wheel. pyrun('-m', 'plover_build_utils.get_pip') # Install Plover + standard plugins and dependencies. # Note: do not use the embedded Python executable with `setup.py # install` to prevent setuptools from installing extra development # dependencies... pyrun('-m', 'plover_build_utils.install_wheels', '-r', 'requirements_distribution.txt') pyrun('-m', 'plover_build_utils.install_wheels', '--ignore-installed', '--no-deps', plover_wheel) pyrun('-m', 'plover_build_utils.install_wheels', '-r', 'requirements_plugins.txt') os.unlink(os.path.join(WHEELS_CACHE, os.path.basename(plover_wheel))) # Trim the fat... if self.trim: from plover_build_utils.trim import trim trim(dist_data, 'windows/dist_blacklist.txt', verbose=self.verbose) # Add miscellaneous files: icon, license, ... for src, target_dir in ( ('LICENSE.txt' , '.' ), ('plover/assets/plover.ico', 'data') ): dst = os.path.join(dist_dir, target_dir, os.path.basename(src)) shutil.copyfile(src, dst) # Create launchers. for entrypoint, gui in ( ('plover = plover.dist_main:main', True ), ('plover_console = plover.dist_main:main', False), ): pyrun('-c', textwrap.dedent( ''' from pip._vendor.distlib.scripts import ScriptMaker sm = ScriptMaker(source_dir='{dist_dir}', target_dir='{dist_dir}') sm.executable = 'data\\python.exe' sm.variants = set(('',)) sm.make('{entrypoint}', options={{'gui': {gui}}}) '''.rstrip()).format(dist_dir=dist_dir, entrypoint=entrypoint, gui=gui)) # Fix Visual C++ Redistributable DLL location. os.rename(os.path.join(dist_dir, 'data', 'vcruntime140.dll'), os.path.join(dist_dir, 'vcruntime140.dll')) # Make distribution source-less. pyrun('-m', 'plover_build_utils.source_less', # Don't touch pip._vendor.distlib sources, # or `pip install` will not be usable... dist_data, '*/pip/_vendor/distlib/*', ) # Check requirements. pyrun('-I', '-m', 'plover_build_utils.check_requirements') # Zip results. if self.zipdir: from plover_build_utils.zipdir import zipdir if self.verbose: log.info('zipping %s', dist_dir) zipdir(dist_dir) # Create an installer. if self.installer: installer_exe = '%s.setup.exe' % dist_dir # Compute install size for "Add/Remove Programs" entry. install_size = sum(os.path.getsize(os.path.join(dirpath, f)) for dirpath, dirnames, filenames in os.walk(dist_dir) for f in filenames) run('makensis.exe', '-NOCD', '-Dsrcdir=' + dist_dir, '-Dversion=' + __version__, '-Dinstall_size=' + str(install_size // 1024), 'windows/installer.nsi', '-XOutFile ' + installer_exe)
def run(self): from plover_build_utils.install_wheels import WHEELS_CACHE # Download helper. from plover_build_utils.download import download # First things first: create Plover wheel. wheel_cmd = self.get_finalized_command('bdist_wheel') wheel_cmd.run() plover_wheel = glob.glob( os.path.join(wheel_cmd.dist_dir, wheel_cmd.wheel_dist_name) + '*.whl')[0] # Setup embedded Python distribution. # Note: python36.zip is decompressed to prevent errors when 2to3 # is used (including indirectly by setuptools `build_py` command). py_embedded = download( 'https://www.python.org/ftp/python/3.6.3/python-3.6.3-embed-win32.zip', '3769c2129779b43f2dade3b89c783d957bff1461') dist_dir = os.path.join(wheel_cmd.dist_dir, PACKAGE + '-win32') dist_data = os.path.join(dist_dir, 'data') dist_py = os.path.join(dist_data, 'python.exe') dist_stdlib = os.path.join(dist_data, 'python36.zip') if os.path.exists(dist_dir): shutil.rmtree(dist_dir) os.makedirs(dist_data) for path in (py_embedded, dist_stdlib): with zipfile.ZipFile(path) as zip: zip.extractall(dist_data) os.unlink(dist_stdlib) # We don't want a completely isolated Python when using # python.exe/pythonw.exe directly, we need a working site # directory and for the current directory to be prepended # to `sys.path` so `plover_build_utils` can be used and # plugins can be installed from source. dist_pth = os.path.join(dist_data, 'python36._pth') with open(dist_pth, 'r+') as fp: pth = fp.read() + 'import site\n' fp.seek(0) fp.write(pth) dist_site_packages = os.path.join(dist_data, 'Lib', 'site-packages') os.makedirs(dist_site_packages) with open(os.path.join(dist_site_packages, 'sitecustomize.py'), 'w') as fp: fp.write( textwrap.dedent(''' import os, sys sys.path.insert(0, os.getcwd()) ''').lstrip()) # Use standard site.py so user site packages are enabled. site_py = download( 'https://github.com/python/cpython/raw/v3.6.3/Lib/site.py', '5b5a92032c666e0e30c0b2665b8acffe2a624641') shutil.copyfile(site_py, os.path.join(dist_site_packages, 'site.py')) # Run command helper. def run(*args): if self.verbose: log.info('running %s', ' '.join(a for a in args)) subprocess.check_call(args) # Install pip/wheel. run(dist_py, '-m', 'plover_build_utils.get_pip') # Install Plover + standard plugins and dependencies. # Note: do not use the embedded Python executable with `setup.py # install` to prevent setuptools from installing extra development # dependencies... run(dist_py, '-m', 'plover_build_utils.install_wheels', '-r', 'requirements_distribution.txt') run(dist_py, '-m', 'plover_build_utils.install_wheels', '--ignore-installed', '--no-deps', plover_wheel) run(dist_py, '-m', 'plover_build_utils.install_wheels', '-r', 'requirements_plugins.txt') os.unlink(os.path.join(WHEELS_CACHE, os.path.basename(plover_wheel))) # Trim the fat... if self.trim: from plover_build_utils.trim import trim trim(dist_data, 'windows/dist_blacklist.txt', verbose=self.verbose) # Add miscellaneous files: icon, license, ... for src, target_dir in (('LICENSE.txt', '.'), ('plover/assets/plover.ico', 'data')): dst = os.path.join(dist_dir, target_dir, os.path.basename(src)) shutil.copyfile(src, dst) # Create launchers. for entrypoint, gui in ( ('plover = plover.dist_main:main', True), ('plover_console = plover.dist_main:main', False), ): run( dist_py, '-c', textwrap.dedent(''' from pip._vendor.distlib.scripts import ScriptMaker sm = ScriptMaker(source_dir='{dist_dir}', target_dir='{dist_dir}') sm.executable = 'data\\python.exe' sm.variants = set(('',)) sm.make('{entrypoint}', options={{'gui': {gui}}}) '''.rstrip()).format(dist_dir=dist_dir, entrypoint=entrypoint, gui=gui)) # Fix Visual C++ Redistributable DLL location. os.rename(os.path.join(dist_dir, 'data', 'vcruntime140.dll'), os.path.join(dist_dir, 'vcruntime140.dll')) # Make distribution source-less. run( dist_py, '-m', 'plover_build_utils.source_less', # Don't touch pip._vendor.distlib sources, # or `pip install` will not be usable... dist_data, '*/pip/_vendor/distlib/*', ) # Check requirements. run(dist_py, '-I', '-m', 'plover_build_utils.check_requirements') # Zip results. if self.zipdir: from plover_build_utils.zipdir import zipdir if self.verbose: log.info('zipping %s', dist_dir) zipdir(dist_dir) # Create an installer. if self.installer: installer_exe = '%s.setup.exe' % dist_dir # Compute install size for "Add/Remove Programs" entry. install_size = sum( os.path.getsize(os.path.join(dirpath, f)) for dirpath, dirnames, filenames in os.walk(dist_dir) for f in filenames) run('makensis.exe', '-NOCD', '-Dsrcdir=' + dist_dir, '-Dversion=' + __version__, '-Dinstall_size=' + str(install_size // 1024), 'windows/installer.nsi', '-XOutFile ' + installer_exe)