Commit 6223d061 by Sébastien Eustace

Improve dependency resolution to avoid unnecessary operations

parent b128854a
# Change Log
## [Unreleased]
### Changed
- Improved dependency resolution to avoid unnecessary operations.
## [0.6.5] - 2018-03-22
### Fixed
......
......@@ -28,7 +28,8 @@ class Installer:
venv,
package: Package,
locker: Locker,
pool: Pool):
pool: Pool,
installed: InstalledRepository = None):
self._io = io
self._venv = venv
self._package = package
......@@ -47,6 +48,7 @@ class Installer:
self._extras = []
self._installer = self._get_installer()
self._installed_repository = installed or self._get_installed()
@property
def installer(self):
......@@ -116,11 +118,10 @@ class Installer:
def _do_install(self, local_repo):
locked_repository = Repository()
# initialize locked repo if we are installing from lock
if not self._update or (self._update and self._locker.is_locked()):
if self._update:
if self._locker.is_locked():
locked_repository = self._locker.locked_repository(True)
if self._update:
# Checking extras
for extra in self._extras:
if extra not in self._package.extras:
......@@ -152,6 +153,7 @@ class Installer:
solver = Solver(
self._package,
self._pool,
self._installed_repository,
locked_repository,
self._io
)
......@@ -162,6 +164,11 @@ class Installer:
ops = solver.solve(request, fixed=fixed)
else:
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():
self._io.writeln(
'<warning>'
......@@ -342,7 +349,7 @@ class Installer:
def _get_operations_from_lock(self,
locked_repository: Repository
) -> List[Operation]:
installed_repo = InstalledRepository.load(self._venv)
installed_repo = self._installed_repository
ops = []
extra_packages = [
......@@ -460,3 +467,6 @@ class Installer:
def _get_installer(self) -> BaseInstaller:
return PipInstaller(self._venv, self._io)
def _get_installed(self) -> InstalledRepository:
return InstalledRepository.load(self._venv)
......@@ -18,9 +18,10 @@ from .ui import UI
class Solver:
def __init__(self, package, pool, locked, io):
def __init__(self, package, pool, installed, locked, io):
self._package = package
self._pool = pool
self._installed = installed
self._locked = locked
self._io = io
......@@ -79,7 +80,7 @@ class Solver:
operations = []
for package in packages:
installed = False
for pkg in self._locked.packages:
for pkg in self._installed.packages:
if package.name == pkg.name:
installed = True
# Checking version
......@@ -100,8 +101,12 @@ class Solver:
break
if remove:
for locked in self._locked.packages:
if locked.name == pkg.name:
operations.append(Uninstall(pkg))
break
return list(reversed(operations))
def _get_tags_for_vertex(self, vertex, requested):
......
......@@ -36,7 +36,6 @@ class Venv:
if self._venv:
self._venv = Path(self._venv)
self._windows = sys.platform == 'win32'
self._bin_dir = None
......
......@@ -115,8 +115,8 @@ def venv():
@pytest.fixture()
def installer(package, pool, locker, venv):
return Installer(NullIO(), venv, package, locker, pool)
def installer(package, pool, locker, venv, installed):
return Installer(NullIO(), venv, package, locker, pool, installed=installed)
def fixture(name):
......@@ -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
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.mock_lock_data(fixture('extras-with-dependencies'))
package.extras['foo'] = [
......
......@@ -30,6 +30,11 @@ def installed():
@pytest.fixture()
def locked():
return Repository()
@pytest.fixture()
def repo():
return Repository()
......@@ -40,8 +45,8 @@ def pool(repo):
@pytest.fixture()
def solver(package, pool, installed, io):
return Solver(package, pool, installed, io)
def solver(package, pool, installed, locked, io):
return Solver(package, pool, installed, locked, io)
def check_solver_result(ops, expected):
......@@ -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')
installed.add_package(package_a)
locked.add_package(package_a)
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