Commit 6223d061 by Sébastien Eustace

Improve dependency resolution to avoid unnecessary operations

parent b128854a
# Change Log # Change Log
## [Unreleased]
### Changed
- Improved dependency resolution to avoid unnecessary operations.
## [0.6.5] - 2018-03-22 ## [0.6.5] - 2018-03-22
### Fixed ### Fixed
......
...@@ -28,7 +28,8 @@ class Installer: ...@@ -28,7 +28,8 @@ class Installer:
venv, venv,
package: Package, package: Package,
locker: Locker, locker: Locker,
pool: Pool): pool: Pool,
installed: InstalledRepository = None):
self._io = io self._io = io
self._venv = venv self._venv = venv
self._package = package self._package = package
...@@ -47,6 +48,7 @@ class Installer: ...@@ -47,6 +48,7 @@ class Installer:
self._extras = [] self._extras = []
self._installer = self._get_installer() self._installer = self._get_installer()
self._installed_repository = installed or self._get_installed()
@property @property
def installer(self): def installer(self):
...@@ -116,11 +118,10 @@ class Installer: ...@@ -116,11 +118,10 @@ class Installer:
def _do_install(self, local_repo): def _do_install(self, local_repo):
locked_repository = Repository() locked_repository = Repository()
# initialize locked repo if we are installing from lock
if not self._update or (self._update and self._locker.is_locked()):
locked_repository = self._locker.locked_repository(True)
if self._update: if self._update:
if self._locker.is_locked():
locked_repository = self._locker.locked_repository(True)
# Checking extras # Checking extras
for extra in self._extras: for extra in self._extras:
if extra not in self._package.extras: if extra not in self._package.extras:
...@@ -152,6 +153,7 @@ class Installer: ...@@ -152,6 +153,7 @@ class Installer:
solver = Solver( solver = Solver(
self._package, self._package,
self._pool, self._pool,
self._installed_repository,
locked_repository, locked_repository,
self._io self._io
) )
...@@ -162,6 +164,11 @@ class Installer: ...@@ -162,6 +164,11 @@ class Installer:
ops = solver.solve(request, fixed=fixed) ops = solver.solve(request, fixed=fixed)
else: else:
self._io.writeln('<info>Installing dependencies from lock file</>') self._io.writeln('<info>Installing dependencies from lock file</>')
locked_repository = self._locker.locked_repository(
self.is_dev_mode()
)
if not self._locker.is_fresh(): if not self._locker.is_fresh():
self._io.writeln( self._io.writeln(
'<warning>' '<warning>'
...@@ -342,7 +349,7 @@ class Installer: ...@@ -342,7 +349,7 @@ class Installer:
def _get_operations_from_lock(self, def _get_operations_from_lock(self,
locked_repository: Repository locked_repository: Repository
) -> List[Operation]: ) -> List[Operation]:
installed_repo = InstalledRepository.load(self._venv) installed_repo = self._installed_repository
ops = [] ops = []
extra_packages = [ extra_packages = [
...@@ -460,3 +467,6 @@ class Installer: ...@@ -460,3 +467,6 @@ class Installer:
def _get_installer(self) -> BaseInstaller: def _get_installer(self) -> BaseInstaller:
return PipInstaller(self._venv, self._io) return PipInstaller(self._venv, self._io)
def _get_installed(self) -> InstalledRepository:
return InstalledRepository.load(self._venv)
...@@ -18,9 +18,10 @@ from .ui import UI ...@@ -18,9 +18,10 @@ from .ui import UI
class Solver: class Solver:
def __init__(self, package, pool, locked, io): def __init__(self, package, pool, installed, locked, io):
self._package = package self._package = package
self._pool = pool self._pool = pool
self._installed = installed
self._locked = locked self._locked = locked
self._io = io self._io = io
...@@ -79,7 +80,7 @@ class Solver: ...@@ -79,7 +80,7 @@ class Solver:
operations = [] operations = []
for package in packages: for package in packages:
installed = False installed = False
for pkg in self._locked.packages: for pkg in self._installed.packages:
if package.name == pkg.name: if package.name == pkg.name:
installed = True installed = True
# Checking version # Checking version
...@@ -100,7 +101,11 @@ class Solver: ...@@ -100,7 +101,11 @@ class Solver:
break break
if remove: if remove:
operations.append(Uninstall(pkg)) for locked in self._locked.packages:
if locked.name == pkg.name:
operations.append(Uninstall(pkg))
break
return list(reversed(operations)) return list(reversed(operations))
......
...@@ -36,7 +36,6 @@ class Venv: ...@@ -36,7 +36,6 @@ class Venv:
if self._venv: if self._venv:
self._venv = Path(self._venv) self._venv = Path(self._venv)
self._windows = sys.platform == 'win32' self._windows = sys.platform == 'win32'
self._bin_dir = None self._bin_dir = None
......
...@@ -115,8 +115,8 @@ def venv(): ...@@ -115,8 +115,8 @@ def venv():
@pytest.fixture() @pytest.fixture()
def installer(package, pool, locker, venv): def installer(package, pool, locker, venv, installed):
return Installer(NullIO(), venv, package, locker, pool) return Installer(NullIO(), venv, package, locker, pool, installed=installed)
def fixture(name): def fixture(name):
...@@ -461,7 +461,7 @@ def test_run_installs_extras_with_deps_if_requested(installer, locker, repo, pac ...@@ -461,7 +461,7 @@ def test_run_installs_extras_with_deps_if_requested(installer, locker, repo, pac
assert len(installer.installs) == 4 # A, B, C, D assert len(installer.installs) == 4 # A, B, C, D
def test_run_installs_extras_with_deps_if_requested_locked(installer, locker, repo, package, installed): def test_run_installs_extras_with_deps_if_requested_locked(installer, locker, repo, package):
locker.locked(True) locker.locked(True)
locker.mock_lock_data(fixture('extras-with-dependencies')) locker.mock_lock_data(fixture('extras-with-dependencies'))
package.extras['foo'] = [ package.extras['foo'] = [
......
...@@ -30,6 +30,11 @@ def installed(): ...@@ -30,6 +30,11 @@ def installed():
@pytest.fixture() @pytest.fixture()
def locked():
return Repository()
@pytest.fixture()
def repo(): def repo():
return Repository() return Repository()
...@@ -40,8 +45,8 @@ def pool(repo): ...@@ -40,8 +45,8 @@ def pool(repo):
@pytest.fixture() @pytest.fixture()
def solver(package, pool, installed, io): def solver(package, pool, installed, locked, io):
return Solver(package, pool, installed, io) return Solver(package, pool, installed, locked, io)
def check_solver_result(ops, expected): def check_solver_result(ops, expected):
...@@ -77,9 +82,9 @@ def test_solver_install_single(solver, repo): ...@@ -77,9 +82,9 @@ def test_solver_install_single(solver, repo):
]) ])
def test_solver_remove_if_not_installed(solver, installed): def test_solver_remove_if_no_longer_locked(solver, locked):
package_a = get_package('A', '1.0') package_a = get_package('A', '1.0')
installed.add_package(package_a) locked.add_package(package_a)
ops = solver.solve([]) ops = solver.solve([])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment