|
1 | 1 | import argparse
|
2 | 2 | import json
|
3 | 3 | import sys
|
| 4 | +import time |
| 5 | +from pathlib import Path |
4 | 6 |
|
5 | 7 | from . import __version__
|
6 |
| -from .main import ZipApp, create_app |
| 8 | +from .main import ZipApp |
7 | 9 |
|
8 | 10 | USAGE = r'''
|
9 | 11 | ===========================================================================
|
|
51 | 53 | PS: all the unknown args will be used by "pip install".
|
52 | 54 | ==========================================================================='''
|
53 | 55 |
|
| 56 | +PIP_PYZ_URL = 'https://bootstrap.pypa.io/pip/pip.pyz' |
| 57 | + |
| 58 | + |
| 59 | +def _get_now(): |
| 60 | + return time.strftime('%Y-%m-%d %H:%M:%S') |
| 61 | + |
| 62 | + |
| 63 | +def _get_pth_path(): |
| 64 | + py_exe_path = Path(sys.executable) |
| 65 | + for _path in py_exe_path.parent.glob('*._pth'): |
| 66 | + _pth_path = _path |
| 67 | + break |
| 68 | + else: |
| 69 | + fname = f'python{sys.version_info.major}{sys.version_info.minor}._pth' |
| 70 | + _pth_path = py_exe_path.parent / fname |
| 71 | + return _pth_path |
| 72 | + |
| 73 | + |
| 74 | +def _append_pth(): |
| 75 | + import re |
| 76 | + _pth_path = _get_pth_path() |
| 77 | + if _pth_path.is_file(): |
| 78 | + print('find _pth file:', |
| 79 | + _pth_path.as_posix(), |
| 80 | + flush=True, |
| 81 | + file=sys.stderr) |
| 82 | + _path_bytes = _pth_path.read_bytes() |
| 83 | + else: |
| 84 | + _path_bytes = b'' |
| 85 | + if not re.search(b'^import site$', _path_bytes): |
| 86 | + _path_bytes += b'\nimport site\n' |
| 87 | + if not re.search(b'^pip\.pyz$', _path_bytes): |
| 88 | + _path_bytes += b'\npip.pyz\n' |
| 89 | + _pth_path.write_bytes(_path_bytes) |
| 90 | + |
| 91 | + |
| 92 | +def download_pip_pyz(target: Path = None, log=True): |
| 93 | + from urllib.request import urlretrieve |
| 94 | + |
| 95 | + pip_pyz_path = Path(target or (Path(sys.executable).parent / 'pip.pyz')) |
| 96 | + if log: |
| 97 | + msg = f'Download {PIP_PYZ_URL} -> {pip_pyz_path.absolute().as_posix()}' |
| 98 | + print(_get_now(), msg, flush=True, file=sys.stderr) |
| 99 | + if pip_pyz_path.is_file(): |
| 100 | + pip_pyz_path.unlink() |
| 101 | + urlretrieve(url=PIP_PYZ_URL, |
| 102 | + filename=pip_pyz_path.absolute().as_posix(), |
| 103 | + reporthook=lambda a, b, c: print( |
| 104 | + _get_now(), |
| 105 | + f'Downloading {int(100*(1+a)*b/c)}%, {(1 + a) * b} / {c}', |
| 106 | + end='\r', |
| 107 | + flush=True, |
| 108 | + file=sys.stderr, |
| 109 | + ) if log else None) |
| 110 | + try: |
| 111 | + sys.path.append(pip_pyz_path.absolute().as_posix()) |
| 112 | + import pip as _ |
| 113 | + if log: |
| 114 | + print(f'\n{_get_now()} install pip ok', flush=True, file=sys.stderr) |
| 115 | + return True |
| 116 | + except ImportError: |
| 117 | + if log: |
| 118 | + print(f'\n{_get_now()} install pip failed', |
| 119 | + flush=True, |
| 120 | + file=sys.stderr) |
| 121 | + |
| 122 | + |
| 123 | +def handle_win32_embeded(): |
| 124 | + _pth_path = _get_pth_path() |
| 125 | + |
| 126 | + if not _pth_path.is_file(): |
| 127 | + return |
| 128 | + try: |
| 129 | + import pip as _ |
| 130 | + return |
| 131 | + except ImportError: |
| 132 | + need_install = ( |
| 133 | + input(f'\n{"=" * 50}\npip module not found, try installing?(Y/n)' |
| 134 | + ).lower().strip() or 'y') |
| 135 | + if need_install != 'y': |
| 136 | + return |
| 137 | + print('find _pth file:', _pth_path.as_posix(), flush=True, file=sys.stderr) |
| 138 | + if download_pip_pyz(): |
| 139 | + _append_pth() |
| 140 | + import os |
| 141 | + |
| 142 | + os.system('%s -m pip -V' % Path(sys.executable).as_posix()) |
| 143 | + os.system('pause') |
| 144 | + |
54 | 145 |
|
55 | 146 | def main():
|
56 | 147 | parser = argparse.ArgumentParser(usage=USAGE, prog='Zipapps')
|
@@ -267,9 +358,18 @@ def main():
|
267 | 358 | dest='quite_mode',
|
268 | 359 | help='mute logs.',
|
269 | 360 | )
|
| 361 | + parser.add_argument('--download-pip-pyz', |
| 362 | + default='', |
| 363 | + dest='download_pip_pyz', |
| 364 | + help=f'Download pip.pyz from "{PIP_PYZ_URL}"') |
| 365 | + |
270 | 366 | if len(sys.argv) == 1:
|
271 |
| - return parser.print_help() |
| 367 | + parser.print_help() |
| 368 | + handle_win32_embeded() |
| 369 | + return |
272 | 370 | args, pip_args = parser.parse_known_args()
|
| 371 | + if args.download_pip_pyz: |
| 372 | + return download_pip_pyz(args.download_pip_pyz) |
273 | 373 | if args.quite_mode:
|
274 | 374 | ZipApp.LOGGING = False
|
275 | 375 | if '-q' not in pip_args and '--quiet' not in pip_args:
|
|
0 commit comments