7
7
from packaging .utils import canonicalize_name
8
8
9
9
from poetry .installation .executor import Executor
10
- from poetry .installation .operations import Install
11
10
from poetry .installation .operations import Uninstall
12
11
from poetry .installation .operations import Update
13
12
from poetry .repositories import Repository
@@ -239,15 +238,17 @@ def _do_install(self) -> int:
239
238
source_root = self ._env .path .joinpath ("src" )
240
239
):
241
240
ops = solver .solve (use_latest = self ._whitelist ).calculate_operations ()
241
+
242
+ lockfile_repo = LockfileRepository ()
243
+ self ._populate_lockfile_repo (lockfile_repo , ops )
244
+
242
245
else :
243
246
self ._io .write_line ("<info>Installing dependencies from lock file</>" )
244
247
245
- locked_repository = self ._locker .locked_repository ()
246
-
247
248
if not self ._locker .is_fresh ():
248
249
raise ValueError (
249
- "pyproject.toml changed significantly since poetry.lock was last generated. "
250
- "Run `poetry lock [--no-update]` to fix the lock file."
250
+ "pyproject.toml changed significantly since poetry.lock was last"
251
+ " generated. Run `poetry lock [--no-update]` to fix the lock file."
251
252
)
252
253
253
254
locker_extras = {
@@ -258,30 +259,25 @@ def _do_install(self) -> int:
258
259
if extra not in locker_extras :
259
260
raise ValueError (f"Extra [{ extra } ] is not specified." )
260
261
261
- # If we are installing from lock
262
- # Filter the operations by comparing it with what is
263
- # currently installed
264
- ops = self ._get_operations_from_lock (locked_repository )
265
-
266
- lockfile_repo = LockfileRepository ()
267
- uninstalls = self ._populate_lockfile_repo (lockfile_repo , ops )
262
+ locked_repository = self ._locker .locked_repository ()
263
+ lockfile_repo = locked_repository
268
264
269
265
if not self .executor .enabled :
270
266
# If we are only in lock mode, no need to go any further
271
267
self ._write_lock_file (lockfile_repo )
272
268
return 0
273
269
274
- if self ._groups is not None :
275
- root = self ._package .with_dependency_groups (list (self ._groups ), only = True )
276
- else :
277
- root = self ._package .without_optional_dependency_groups ()
278
-
279
270
if self ._io .is_verbose ():
280
271
self ._io .write_line ("" )
281
272
self ._io .write_line (
282
273
"<info>Finding the necessary packages for the current system</>"
283
274
)
284
275
276
+ if self ._groups is not None :
277
+ root = self ._package .with_dependency_groups (list (self ._groups ), only = True )
278
+ else :
279
+ root = self ._package .without_optional_dependency_groups ()
280
+
285
281
# We resolve again by only using the lock file
286
282
packages = lockfile_repo .packages + locked_repository .packages
287
283
pool = RepositoryPool .from_packages (packages , self ._config )
@@ -299,31 +295,12 @@ def _do_install(self) -> int:
299
295
300
296
with solver .use_environment (self ._env ):
301
297
ops = solver .solve (use_latest = self ._whitelist ).calculate_operations (
302
- with_uninstalls = self ._requires_synchronization ,
298
+ with_uninstalls = self ._requires_synchronization or self . _update ,
303
299
synchronize = self ._requires_synchronization ,
304
300
skip_directory = self ._skip_directory ,
301
+ extras = set (self ._extras ),
305
302
)
306
303
307
- if not self ._requires_synchronization :
308
- # If no packages synchronisation has been requested we need
309
- # to calculate the uninstall operations
310
- from poetry .puzzle .transaction import Transaction
311
-
312
- transaction = Transaction (
313
- locked_repository .packages ,
314
- [(package , 0 ) for package in lockfile_repo .packages ],
315
- installed_packages = self ._installed_repository .packages ,
316
- root_package = root ,
317
- )
318
-
319
- ops = [
320
- op
321
- for op in transaction .calculate_operations (with_uninstalls = True )
322
- if op .job_type == "uninstall"
323
- ] + ops
324
- else :
325
- ops = uninstalls + ops
326
-
327
304
# We need to filter operations so that packages
328
305
# not compatible with the current system,
329
306
# or optional and not requested, are dropped
@@ -358,50 +335,15 @@ def _execute(self, operations: list[Operation]) -> int:
358
335
359
336
def _populate_lockfile_repo (
360
337
self , repo : LockfileRepository , ops : Iterable [Operation ]
361
- ) -> list [Uninstall ]:
362
- uninstalls = []
338
+ ) -> None :
363
339
for op in ops :
364
340
if isinstance (op , Uninstall ):
365
- uninstalls .append (op )
366
341
continue
367
342
368
343
package = op .target_package if isinstance (op , Update ) else op .package
369
344
if not repo .has_package (package ):
370
345
repo .add_package (package )
371
346
372
- return uninstalls
373
-
374
- def _get_operations_from_lock (
375
- self , locked_repository : Repository
376
- ) -> list [Operation ]:
377
- installed_repo = self ._installed_repository
378
- ops : list [Operation ] = []
379
-
380
- extra_packages = self ._get_extra_packages (locked_repository )
381
- for locked in locked_repository .packages :
382
- is_installed = False
383
- for installed in installed_repo .packages :
384
- if locked .name == installed .name :
385
- is_installed = True
386
- if locked .optional and locked .name not in extra_packages :
387
- # Installed but optional and not requested in extras
388
- ops .append (Uninstall (locked ))
389
- elif locked .version != installed .version :
390
- ops .append (Update (installed , locked ))
391
-
392
- # If it's optional and not in required extras
393
- # we do not install
394
- if locked .optional and locked .name not in extra_packages :
395
- continue
396
-
397
- op = Install (locked )
398
- if is_installed :
399
- op .skip ("Already installed" )
400
-
401
- ops .append (op )
402
-
403
- return ops
404
-
405
347
def _filter_operations (self , ops : Iterable [Operation ], repo : Repository ) -> None :
406
348
extra_packages = self ._get_extra_packages (repo )
407
349
for op in ops :
@@ -425,19 +367,11 @@ def _get_extra_packages(self, repo: Repository) -> set[NormalizedName]:
425
367
426
368
Maybe we just let the solver handle it?
427
369
"""
428
- extras : dict [NormalizedName , list [NormalizedName ]]
429
- if self ._update :
430
- extras = {k : [d .name for d in v ] for k , v in self ._package .extras .items ()}
431
- else :
432
- raw_extras = self ._locker .lock_data .get ("extras" , {})
433
- extras = {
434
- canonicalize_name (extra ): [
435
- canonicalize_name (dependency ) for dependency in dependencies
436
- ]
437
- for extra , dependencies in raw_extras .items ()
438
- }
439
-
440
- return get_extra_package_names (repo .packages , extras , self ._extras )
370
+ return get_extra_package_names (
371
+ repo .packages ,
372
+ {k : [d .name for d in v ] for k , v in self ._package .extras .items ()},
373
+ self ._extras ,
374
+ )
441
375
442
376
def _get_installed (self ) -> InstalledRepository :
443
377
return InstalledRepository .load (self ._env )
0 commit comments