diff --git a/homeassistant/requirements.py b/homeassistant/requirements.py index ca34a4bbae4..1164eff4eb8 100644 --- a/homeassistant/requirements.py +++ b/homeassistant/requirements.py @@ -44,12 +44,15 @@ async def async_process_requirements(hass: HomeAssistant, name: str, def pip_kwargs(config_dir: Optional[str]) -> Dict[str, Any]: """Return keyword arguments for PIP install.""" + is_docker = pkg_util.is_docker_env() kwargs = { - 'constraints': os.path.join(os.path.dirname(__file__), CONSTRAINT_FILE) + 'constraints': os.path.join(os.path.dirname(__file__), + CONSTRAINT_FILE), + 'no_cache_dir': is_docker, } if 'WHEELS_LINKS' in os.environ: kwargs['find_links'] = os.environ['WHEELS_LINKS'] if not (config_dir is None or pkg_util.is_virtual_env()) and \ - not pkg_util.is_docker_env(): + not is_docker: kwargs['target'] = os.path.join(config_dir, 'deps') return kwargs diff --git a/homeassistant/util/package.py b/homeassistant/util/package.py index 272a097b24c..6f6d03d67b6 100644 --- a/homeassistant/util/package.py +++ b/homeassistant/util/package.py @@ -49,7 +49,8 @@ def is_installed(package: str) -> bool: def install_package(package: str, upgrade: bool = True, target: Optional[str] = None, constraints: Optional[str] = None, - find_links: Optional[str] = None) -> bool: + find_links: Optional[str] = None, + no_cache_dir: Optional[bool] = False) -> bool: """Install a package on PyPi. Accepts pip compatible package strings. Return boolean if install successful. @@ -58,6 +59,8 @@ def install_package(package: str, upgrade: bool = True, _LOGGER.info('Attempting install of %s', package) env = os.environ.copy() args = [sys.executable, '-m', 'pip', 'install', '--quiet', package] + if no_cache_dir: + args.append('--no-cache-dir') if upgrade: args.append('--upgrade') if constraints is not None: diff --git a/tests/test_requirements.py b/tests/test_requirements.py index 35264c2e1b4..bbf86278bd2 100644 --- a/tests/test_requirements.py +++ b/tests/test_requirements.py @@ -30,9 +30,8 @@ class TestRequirements: @patch('homeassistant.util.package.is_docker_env', return_value=False) @patch('homeassistant.util.package.install_package', return_value=True) def test_requirement_installed_in_venv( - self, mock_install, mock_venv, mock_denv, mock_dirname): + self, mock_install, mock_denv, mock_venv, mock_dirname): """Test requirement installed in virtual environment.""" - mock_venv.return_value = True mock_dirname.return_value = 'ha_package_path' self.hass.config.skip_pip = False mock_integration( @@ -42,14 +41,16 @@ class TestRequirements: assert 'comp' in self.hass.config.components assert mock_install.call_args == call( 'package==0.0.1', - constraints=os.path.join('ha_package_path', CONSTRAINT_FILE)) + constraints=os.path.join('ha_package_path', CONSTRAINT_FILE), + no_cache_dir=False, + ) @patch('os.path.dirname') @patch('homeassistant.util.package.is_virtual_env', return_value=False) @patch('homeassistant.util.package.is_docker_env', return_value=False) @patch('homeassistant.util.package.install_package', return_value=True) def test_requirement_installed_in_deps( - self, mock_install, mock_venv, mock_denv, mock_dirname): + self, mock_install, mock_denv, mock_venv, mock_dirname): """Test requirement installed in deps directory.""" mock_dirname.return_value = 'ha_package_path' self.hass.config.skip_pip = False @@ -60,7 +61,9 @@ class TestRequirements: assert 'comp' in self.hass.config.components assert mock_install.call_args == call( 'package==0.0.1', target=self.hass.config.path('deps'), - constraints=os.path.join('ha_package_path', CONSTRAINT_FILE)) + constraints=os.path.join('ha_package_path', CONSTRAINT_FILE), + no_cache_dir=False, + ) async def test_install_existing_package(hass): @@ -108,7 +111,9 @@ async def test_install_with_wheels_index(hass): print(mock_inst.call_args) assert mock_inst.call_args == call( 'hello==1.0.0', find_links="https://wheels.hass.io/test", - constraints=os.path.join('ha_package_path', CONSTRAINT_FILE)) + constraints=os.path.join('ha_package_path', CONSTRAINT_FILE), + no_cache_dir=True, + ) async def test_install_on_docker(hass): @@ -135,4 +140,6 @@ async def test_install_on_docker(hass): print(mock_inst.call_args) assert mock_inst.call_args == call( 'hello==1.0.0', - constraints=os.path.join('ha_package_path', CONSTRAINT_FILE)) + constraints=os.path.join('ha_package_path', CONSTRAINT_FILE), + no_cache_dir=True, + )