Skip to content

Commit 9a9dcd1

Browse files
committed
add --clear-zipapps-cache / -czc arg
1 parent 34bcf4c commit 9a9dcd1

File tree

6 files changed

+72
-15
lines changed

6 files changed

+72
-15
lines changed

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,19 +319,23 @@ Details:
319319
- `-a xxx.py`
320320
- to add some files/folders into the zipped file.
321321
- `-u=AUTO`
322+
- **Recommended**
322323
- auto unzip the .pyd / .so files
324+
- or `-u=*` to unzip all the files
323325
- `-r requirements.txt`
324326
- install requirements with `pip install`
325327
- `-o my_app.pyz`
326328
- output the zipped file as given path
327329
- `-m app.__main__:main`
328-
- set the entry point
330+
- entry point
329331
- `-p /usr/bin/python3`
330332
- set the `shebang` line
331333
- `-d`
334+
- **Recommended**
332335
- lazy install mode, requirements will be installed with `pip` while first running
333-
- **Very useful**
334336
- zip file size will be very small, and the default unzip path is `SELF/zipapps_cache/`
337+
- `--clear-zipapps-cache`, `-czc`
338+
- Clear the zipapps cache folder after running, but maybe failed for .pyd/.so files.
335339

336340
Details:
337341

@@ -380,7 +384,7 @@ Details:
380384
1. Compile .py to .pyc for fast import, but zipapp does not work unless you unzip it(so NOT very useful).
381385
2. the `compiled` arg of `zipapps.create_app`
382386
10. ` --cache-path, --source-dir, -cp`
383-
3. The cache path of zipapps to store site-packages and `includes` files. If not set, will create and clean-up in TEMP dir automately.
387+
1. The cache path of zipapps to store site-packages and `includes` files. If not set, will create and clean-up in TEMP dir automately.
384388
2. the `cache_path` arg of `zipapps.create_app`
385389
11. `--shell, -s`
386390
1. Only while `main` is not set, used for shell=True in `subprocess.run`.
@@ -407,7 +411,9 @@ Details:
407411
1. Layer mode for the `serverless` use case, `__main__.py / ensure_zipapps.py / activate_zipapps.py` files will not be set in this mode.
408412
2. `--layer-mode-prefix`
409413
1. Only work while `--layer-mode` is set, will move the files in the given prefix folder.
410-
19. all the other (or `unknown`) args will be used by `pip install`
414+
19. `--clear-zipapps-cache, -czc`
415+
1. Clear the zipapps cache folder after running, but maybe failed for .pyd/.so files.
416+
20. all the other (or `unknown`) args will be used by `pip install`
411417
1. such as `-r requirements.txt`
412418
2. such as `bottle aiohttp`
413419
3. the `pip_args` arg of `zipapps.create_app`

changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11

22
# Changelogs
33

4+
5+
- 2021.11.01
6+
- add `--clear-zipapps-cache` / `-czc` command line arg
7+
- Clear the zipapps cache folder after running, but maybe failed for .pyd/.so files.
8+
- <refactor> move the `const` to the top of `ensure_zipapps` template.
49
- 2021.09.22
510
- fix `--layer-mode-prefix` not work for `-a` files
611
- 2021.09.21

test_utils.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ def _clean_paths():
3636

3737
def test_create_app_function():
3838

39+
# test -czc
40+
_clean_paths()
41+
app_path = create_app(clear_zipapps_cache=False, unzip='*')
42+
stdout_output, stderr_output = subprocess.Popen(
43+
[sys.executable, str(app_path), '-V']).communicate()
44+
assert Path('./zipapps_cache').is_dir()
45+
_clean_paths()
46+
app_path = create_app(clear_zipapps_cache=True, unzip='*')
47+
stdout_output, stderr_output = subprocess.Popen(
48+
[sys.executable, str(app_path), '-V']).communicate()
49+
assert not Path('./zipapps_cache').is_dir()
50+
3951
# test build_id
4052
_clean_paths()
4153
mock_requirement = Path('_requirements.txt')

zipapps/__main__.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,24 @@ def main():
197197
'--layer-mode',
198198
action='store_true',
199199
dest='layer_mode',
200-
help='Layer mode for the serverless use case, __main__.py / ensure_zipapps.py / activate_zipapps.py files will not be set in this mode.')
200+
help=
201+
'Layer mode for the serverless use case, __main__.py / ensure_zipapps.py / activate_zipapps.py files will not be set in this mode.'
202+
)
201203
parser.add_argument(
202204
'--layer-mode-prefix',
203205
default='python',
204206
dest='layer_mode_prefix',
205-
help='Only work while --layer-mode is set, will move the files in the given prefix folder.')
207+
help=
208+
'Only work while --layer-mode is set, will move the files in the given prefix folder.'
209+
)
210+
parser.add_argument(
211+
'-czc',
212+
'--clear-zipapps-cache',
213+
action='store_true',
214+
dest='clear_zipapps_cache',
215+
help=
216+
'Clear the zipapps cache folder after running, but maybe failed for .pyd/.so files.',
217+
)
206218
if len(sys.argv) == 1:
207219
return parser.print_help()
208220
args, pip_args = parser.parse_known_args()
@@ -233,6 +245,7 @@ def main():
233245
ensure_pip=args.ensure_pip,
234246
layer_mode=args.layer_mode,
235247
layer_mode_prefix=args.layer_mode_prefix,
248+
clear_zipapps_cache=args.clear_zipapps_cache,
236249
)
237250

238251

zipapps/ensure_zipapps_template.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
pip_args_md5 = '{pip_args_md5}'
1919
py_version = '.'.join(map(str, sys.version_info[:{python_version_slice}]))
2020
_new_sys_paths = r'''{sys_paths}'''.strip()
21+
clear_zipapps_cache = {clear_zipapps_cache}
2122

2223

2324
def ensure_path(path):
@@ -37,13 +38,15 @@ def rm_dir_or_file(path: Path):
3738
for _ in range(3):
3839
try:
3940
if path.is_dir():
40-
rmtree(str(path.absolute()))
41+
rmtree(str(path.absolute()), ignore_errors=True)
4142
elif path.is_file():
4243
path.unlink()
4344
else:
4445
break
4546
except FileNotFoundError:
4647
break
48+
except PermissionError:
49+
break
4750
else:
4851
return False
4952
return True
@@ -62,8 +65,18 @@ def prepare_path():
6265
zip_file_path = Path(__file__).parent.absolute()
6366
_zipapps_python_path_list = [str(zip_file_path)]
6467
if unzip:
65-
_cache_folder_path = ensure_path(_cache_folder)
66-
_cache_folder_path = _cache_folder_path / zip_file_path.stem
68+
_cache_folder_path_parent = ensure_path(_cache_folder)
69+
_cache_folder_path = _cache_folder_path_parent / zip_file_path.stem
70+
if clear_zipapps_cache:
71+
import atexit
72+
73+
def _remove_cache_folder():
74+
rm_dir_or_file(_cache_folder_path)
75+
if not any(_cache_folder_path_parent.iterdir()):
76+
rm_dir_or_file(_cache_folder_path_parent)
77+
78+
atexit.register(_remove_cache_folder)
79+
6780
_cache_folder_path.mkdir(parents=True, exist_ok=True)
6881
_cache_folder_path_str = str(_cache_folder_path.absolute())
6982
_zipapps_python_path_list.insert(0, _cache_folder_path_str)

zipapps/main.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from pkgutil import get_data
1616
from zipfile import ZIP_DEFLATED, ZIP_STORED, BadZipFile, ZipFile
1717

18-
__version__ = '2021.09.22'
18+
__version__ = '2021.11.01'
1919

2020

2121
class ZipApp(object):
@@ -50,6 +50,7 @@ def __init__(
5050
ensure_pip: bool = False,
5151
layer_mode: bool = False,
5252
layer_mode_prefix: str = 'python',
53+
clear_zipapps_cache: bool = False,
5354
):
5455
"""Zip your code.
5556
@@ -95,6 +96,8 @@ def __init__(
9596
:type includes: bool, optional
9697
:param layer_mode_prefix: Only work while --layer-mode is set, will move the files in the given prefix folder.
9798
:type includes: str, optional
99+
:param clear_zipapps_cache: Clear the zipapps cache folder after running, but maybe failed for .pyd/.so files..
100+
:type includes: bool, optional
98101
"""
99102
self.includes = includes
100103
self.cache_path = cache_path
@@ -118,6 +121,7 @@ def __init__(
118121
self.ensure_pip = ensure_pip
119122
self.layer_mode = layer_mode
120123
self.layer_mode_prefix = layer_mode_prefix
124+
self.clear_zipapps_cache = clear_zipapps_cache
121125

122126
self._tmp_dir: tempfile.TemporaryDirectory = None
123127
self._build_success = False
@@ -164,7 +168,7 @@ def prepare_ensure_pip(self):
164168

165169
def build(self):
166170
self._log(
167-
f'{"=" * 10} Start building `{self._output_path}` with zipapps version <{__version__}> {"=" * 10}'
171+
f'[INFO]: {"=" * 10} Start building `{self._output_path}` with zipapps version <{__version__}> {"=" * 10}'
168172
)
169173
self.ensure_args()
170174
if self.build_exists():
@@ -237,6 +241,9 @@ def prepare_entry_point(self):
237241
auto_unzip_keys = ZipApp.AUTO_FIX_UNZIP_KEYS & unzip_names
238242
unzip_names -= auto_unzip_keys
239243
if warning_names:
244+
if self.clear_zipapps_cache:
245+
msg = f'[WARN]: clear_zipapps_cache is True but .pyd/.so files were found {warning_names}'
246+
self._log(msg)
240247
if auto_unzip_keys:
241248
unzip_names |= warning_names.keys()
242249
else:
@@ -279,6 +286,7 @@ def prepare_active_zipapps(self):
279286
'sys_paths': self.sys_paths,
280287
'python_version_slice': self.python_version_slice,
281288
'pip_args_md5': self.pip_args_md5,
289+
'clear_zipapps_cache': repr(self.clear_zipapps_cache),
282290
}
283291
code = get_data('zipapps', '_entry_point.py').decode('u8')
284292
(self._cache_path / '__main__.py').write_text(code.format(**kwargs))
@@ -402,19 +410,19 @@ def create_app(cls, *args, **kwargs):
402410

403411
@staticmethod
404412
def _log(text):
405-
sys.stderr.write(f'{text}\n')
413+
sys.stderr.write(f'{time.strftime("%Y-%m-%d %H:%M:%S")} | {text}\n')
406414

407415
def __del__(self):
408416
if self._tmp_dir:
409417
self._tmp_dir.cleanup()
410418
self._log(
411-
f'[INFO] Temp cache has been cleaned. ({self._tmp_dir!r})')
419+
f'[INFO]: Temp cache has been cleaned. ({self._tmp_dir!r})')
412420
if self._build_success:
413421
self._log(
414-
f'{"=" * 10} Successfully built `{self._output_path}` {"=" * 10}'
422+
f'[INFO]: {"=" * 10} Successfully built `{self._output_path}` {"=" * 10}'
415423
)
416424
else:
417-
self._log(f'{"=" * 10} Build failed {"=" * 10}')
425+
self._log(f'[ERROR]: {"=" * 10} Build failed {"=" * 10}')
418426

419427

420428
def create_app(*args, **kwargs):

0 commit comments

Comments
 (0)