-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
{Packaging} Optimize Linux package and docker image by removing py file #25801
base: dev
Are you sure you want to change the base?
Changes from 27 commits
08062d2
0f175e0
8e7d36f
04adb00
4aef92d
7410096
159c08b
a07664b
c66c260
8861360
c456088
9645801
293f252
5efeab5
324ec66
2051488
7fb7902
9e0338c
a1d6758
39c5b2f
eec7166
a960bbf
8229caf
3f9af6d
eb0566d
6d6cb07
a971e4e
219679d
25c4ffe
e4dcccb
27a9bab
8a059d3
76e6239
2676b09
ee56c59
80506cf
441d23e
fdeb09d
c9c8c5d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -139,36 +139,8 @@ copy %REPO_ROOT%\build_scripts\windows\resources\CLI_LICENSE.rtf %BUILDING_DIR% | |
copy %REPO_ROOT%\build_scripts\windows\resources\ThirdPartyNotices.txt %BUILDING_DIR% | ||
copy %REPO_ROOT%\NOTICE.txt %BUILDING_DIR% | ||
|
||
REM Remove .py and only deploy .pyc files | ||
pushd %BUILDING_DIR%\Lib\site-packages | ||
for /f %%f in ('dir /b /s *.pyc') do ( | ||
set PARENT_DIR=%%~df%%~pf.. | ||
echo !PARENT_DIR! | findstr /C:\Lib\site-packages\pip\ 1>nul | ||
if !errorlevel! neq 0 ( | ||
REM Only take the file name without 'pyc' extension: e.g., (same below) __init__.cpython-310 | ||
set FILENAME=%%~nf | ||
REM Truncate the '.cpython-310' postfix which is 12 chars long: __init__ | ||
REM https://stackoverflow.com/a/636391/2199657 | ||
set BASE_FILENAME=!FILENAME:~0,-12! | ||
REM __init__.pyc | ||
set pyc=!BASE_FILENAME!.pyc | ||
REM Delete ..\__init__.py | ||
del !PARENT_DIR!\!BASE_FILENAME!.py | ||
REM Copy to ..\__init__.pyc | ||
copy %%~f !PARENT_DIR!\!pyc! >nul | ||
REM Delete __init__.pyc | ||
del %%~f | ||
) ELSE ( | ||
echo --SKIP !PARENT_DIR! under pip | ||
) | ||
) | ||
popd | ||
|
||
REM Remove __pycache__ | ||
echo remove pycache | ||
for /d /r %BUILDING_DIR%\Lib\site-packages\pip %%d in (__pycache__) do ( | ||
if exist %%d rmdir /s /q "%%d" | ||
) | ||
REM replace .py with .pyc and remove __pycache__ dir to save space | ||
%BUILDING_DIR%\python.exe %REPO_ROOT%\scripts\use_pyc.py %BUILDING_DIR%\Lib\site-packages\ %PYTHON_VERSION% | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Won't it be pretty hard to debug anything when there's no source code left? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's true, but I think most of the users never edit CLI source code for debug. For those who want to change source code, they need to install from pypi. |
||
|
||
REM Remove dist-info | ||
echo remove dist-info | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
import logging | ||
import glob | ||
import os | ||
import platform | ||
import re | ||
import sys | ||
from pathlib import Path | ||
import shutil | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
def calculate_folder_size(start_path): | ||
"""Calculate total size of a folder and file count.""" | ||
# https://stackoverflow.com/questions/1392413/calculating-a-directorys-size-using-python | ||
total_size = 0 | ||
total_count = 0 | ||
for dirpath, dirnames, filenames in os.walk(start_path): | ||
for f in filenames: | ||
fp = os.path.join(dirpath, f) | ||
# skip if it is symbolic link | ||
if not os.path.islink(fp): | ||
total_count += 1 | ||
total_size += os.path.getsize(fp) | ||
|
||
return total_size, total_count | ||
|
||
|
||
def _print_folder_size(folder): | ||
size, count = calculate_folder_size(folder) | ||
size_in_mb = size / 1048576 # 1 MB = 1024 * 1024 B = 1048576 B | ||
_LOGGER.info(f"{size_in_mb:.2f} MB, {count} files") | ||
|
||
|
||
def main(folder, version=None): | ||
_LOGGER.info(f'Replace .py with .pyc, base folder: {folder}') | ||
_print_folder_size(folder) | ||
if version is None: | ||
version = re.search(r'python(\d\.\d+)', folder).group(1) | ||
else: | ||
# 3.10.10 | ||
version = '.'.join(version.split('.')[:2]) | ||
# invoke==1.2.0 has a weird file: invoke/completion/__pycache__/__init__.cpython-36.pyc | ||
# define pyc suffix to skip it | ||
pyc_suffix = f'cpython-{version.replace(".", "")}.pyc' | ||
_LOGGER.info(f'pyc suffix: {pyc_suffix}') | ||
for file in glob.glob(f'{folder}/**/__pycache__/*{pyc_suffix}', recursive=True): | ||
# If pip's py files are also removed, the error is raised when installing some packages. | ||
# See https://github.com/Azure/azure-cli/pull/25801 for details. | ||
if 'site-packages/pip' in file: | ||
continue | ||
|
||
# file is /opt/az/lib/python3.10/site-packages/websocket/__pycache__/_app.cpython-310.pyc | ||
# py_filename is _app.py | ||
py_filename = Path(file).name[:-len(pyc_suffix)] + 'py' | ||
# py_path is /opt/az/lib/python3.10/site-packages/websocket/_app.py | ||
py_path = Path(file).parent.parent / py_filename | ||
if py_path.exists(): | ||
py_path.unlink() | ||
shutil.move(file, py_path.with_suffix('.pyc')) | ||
|
||
for f in glob.glob(f'{folder}/**/__pycache__', recursive=True): | ||
# Remove pip __pycache__ folder for Windows only to save more space | ||
if 'site-packages/pip' in f and not platform.system() == 'Windows': | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removing py file has side effects.
The MSI also keeps py files under |
||
continue | ||
shutil.rmtree(f) | ||
|
||
_LOGGER.info('Finish processing') | ||
_print_folder_size(folder) | ||
|
||
|
||
if __name__ == '__main__': | ||
logging.basicConfig(level=logging.DEBUG) | ||
if len(sys.argv) == 2: | ||
main(sys.argv[1]) | ||
else: | ||
main(sys.argv[1], sys.argv[2]) |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -33,13 +33,13 @@ | |||||||||||||||||||
AbstractPreparer, | ||||||||||||||||||||
SingleValueReplacer) | ||||||||||||||||||||
from azure.core.exceptions import HttpResponseError | ||||||||||||||||||||
from ..._client_factory import cf_mysql_flexible_private_dns_zone_suffix_operations, cf_postgres_flexible_private_dns_zone_suffix_operations | ||||||||||||||||||||
from ...flexible_server_virtual_network import prepare_private_network, prepare_private_dns_zone, prepare_public_network, DEFAULT_VNET_ADDRESS_PREFIX, DEFAULT_SUBNET_ADDRESS_PREFIX | ||||||||||||||||||||
from ...flexible_server_custom_postgres import DbContext as PostgresDbContext | ||||||||||||||||||||
from ...flexible_server_custom_mysql import DbContext as MysqlDbContext | ||||||||||||||||||||
from ...flexible_server_custom_mysql import _determine_iops | ||||||||||||||||||||
from ..._flexible_server_util import get_mysql_list_skus_info | ||||||||||||||||||||
from ..._util import retryable_method | ||||||||||||||||||||
from azure.cli.command_modules.rdbms._client_factory import cf_mysql_flexible_private_dns_zone_suffix_operations, cf_postgres_flexible_private_dns_zone_suffix_operations | ||||||||||||||||||||
from azure.cli.command_modules.rdbms.flexible_server_virtual_network import prepare_private_network, prepare_private_dns_zone, prepare_public_network, DEFAULT_VNET_ADDRESS_PREFIX, DEFAULT_SUBNET_ADDRESS_PREFIX | ||||||||||||||||||||
from azure.cli.command_modules.rdbms.flexible_server_custom_postgres import DbContext as PostgresDbContext | ||||||||||||||||||||
from azure.cli.command_modules.rdbms.flexible_server_custom_mysql import DbContext as MysqlDbContext | ||||||||||||||||||||
from azure.cli.command_modules.rdbms.flexible_server_custom_mysql import _determine_iops | ||||||||||||||||||||
from azure.cli.command_modules.rdbms._flexible_server_util import get_mysql_list_skus_info | ||||||||||||||||||||
from azure.cli.command_modules.rdbms._util import retryable_method | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When import statement is
The According to pytest import mechanisms and sys.path/PYTHONPATH, pytest searches for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It fails at azure-cli/scripts/release/debian/test_deb_package.py Lines 13 to 21 in 1c31408
Yes, we should not use |
||||||||||||||||||||
# Constants | ||||||||||||||||||||
SERVER_NAME_PREFIX = 'azuredbclitest-' | ||||||||||||||||||||
SERVER_NAME_MAX_LENGTH = 20 | ||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to make the pyc change in a separate PR, just in case something goes wrong and we need to roll back.