diff --git a/src/azure-cli-core/azure/cli/core/extension/operations.py b/src/azure-cli-core/azure/cli/core/extension/operations.py index e20aed58b03..0aef89776ea 100644 --- a/src/azure-cli-core/azure/cli/core/extension/operations.py +++ b/src/azure-cli-core/azure/cli/core/extension/operations.py @@ -42,6 +42,7 @@ IS_WINDOWS = sys.platform.lower() in ['windows', 'win32'] LIST_FILE_PATH = os.path.join(os.sep, 'etc', 'apt', 'sources.list.d', 'azure-cli.list') LSB_RELEASE_FILE = os.path.join(os.sep, 'etc', 'lsb-release') +PSYCOPG2_EXTENSIONS = {'rdbms-connect', 'serviceconnector-passwordless'} def _run_pip(pip_exec_args, extension_path=None): @@ -111,7 +112,7 @@ def _add_whl_ext(cli_ctx, source, ext_sha256=None, pip_extra_index_urls=None, pi raise CLIError('Unable to determine extension name from {}. Is the file name correct?'.format(source)) if extension_exists(extension_name, ext_type=WheelExtension): raise CLIError('The extension {} already exists.'.format(extension_name)) - if extension_name == 'rdbms-connect' or extension_name == 'serviceconnector-passwordless': + if extension_name in PSYCOPG2_EXTENSIONS: _install_deps_for_psycopg2() ext_file = None if is_url: @@ -157,6 +158,8 @@ def _add_whl_ext(cli_ctx, source, ext_sha256=None, pip_extra_index_urls=None, pi # Install with pip extension_path = build_extension_path(extension_name, system) pip_args = ['install', '--target', extension_path, ext_file] + if IS_WINDOWS and extension_name in PSYCOPG2_EXTENSIONS: + pip_args.append('--no-build-isolation') if pip_proxy: pip_args = pip_args + ['--proxy', pip_proxy] diff --git a/src/azure-cli-core/azure/cli/core/extension/tests/latest/test_extension_commands.py b/src/azure-cli-core/azure/cli/core/extension/tests/latest/test_extension_commands.py index 2f81268935d..ace477bd2f4 100644 --- a/src/azure-cli-core/azure/cli/core/extension/tests/latest/test_extension_commands.py +++ b/src/azure-cli-core/azure/cli/core/extension/tests/latest/test_extension_commands.py @@ -12,7 +12,7 @@ from azure.cli.core.util import CLIError from azure.cli.core.extension import get_extension, build_extension_path -from azure.cli.core.extension.operations import (add_extension_to_path, list_extensions, add_extension, +from azure.cli.core.extension.operations import (_add_whl_ext, add_extension_to_path, list_extensions, add_extension, show_extension, remove_extension, update_extension, list_available_extensions, OUT_KEY_NAME, OUT_KEY_VERSION, OUT_KEY_METADATA, OUT_KEY_PATH) @@ -174,6 +174,36 @@ def test_add_extension_verify_no_pip_proxy(self): if '--proxy' in pip_cmd: raise AssertionError("proxy parameter in check_output args although no proxy specified") + def test_add_psycopg2_extension_on_windows_disables_build_isolation(self): + source = os.path.join(self.ext_dir, 'rdbms_connect-1.0.0-py2.py3-none-any.whl') + with mock.patch('azure.cli.core.extension.operations.IS_WINDOWS', True), \ + mock.patch('azure.cli.core.extension.operations.extension_exists', return_value=False), \ + mock.patch('azure.cli.core.extension.operations._install_deps_for_psycopg2') as install_deps, \ + mock.patch('azure.cli.core.extension.operations.os.path.isfile', return_value=True), \ + mock.patch('azure.cli.core.extension.operations._validate_whl_extension'), \ + mock.patch('azure.cli.core.extension.operations.check_distro_consistency'), \ + mock.patch('azure.cli.core.extension.operations.build_extension_path', return_value=self.ext_dir), \ + mock.patch('azure.cli.core.extension.operations._run_pip', return_value=0) as run_pip, \ + mock.patch('azure.cli.core.extension.operations.shutil.copyfile'): + _add_whl_ext(self.cmd.cli_ctx, source) + + install_deps.assert_called_once_with() + pip_args = run_pip.call_args.args[0] + self.assertIn('--no-build-isolation', pip_args) + + def test_add_non_psycopg2_extension_on_windows_keeps_build_isolation(self): + with mock.patch('azure.cli.core.extension.operations.IS_WINDOWS', True), \ + mock.patch('azure.cli.core.extension.operations.extension_exists', return_value=False), \ + mock.patch('azure.cli.core.extension.operations._validate_whl_extension'), \ + mock.patch('azure.cli.core.extension.operations.check_distro_consistency'), \ + mock.patch('azure.cli.core.extension.operations.build_extension_path', return_value=self.ext_dir), \ + mock.patch('azure.cli.core.extension.operations._run_pip', return_value=0) as run_pip, \ + mock.patch('azure.cli.core.extension.operations.shutil.copyfile'): + _add_whl_ext(self.cmd.cli_ctx, MY_EXT_SOURCE) + + pip_args = run_pip.call_args.args[0] + self.assertNotIn('--no-build-isolation', pip_args) + def test_add_extension_with_specific_version(self): extension_name = MY_EXT_NAME extension1 = 'myfirstcliextension-0.0.3+dev-py2.py3-none-any.whl'