pipu-cli 0.2.1__py3-none-any.whl → 0.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pipu_cli/__init__.py +1 -1
- pipu_cli/cli.py +229 -198
- pipu_cli/package_management.py +5 -2
- {pipu_cli-0.2.1.dist-info → pipu_cli-0.2.3.dist-info}/METADATA +2 -1
- pipu_cli-0.2.3.dist-info/RECORD +16 -0
- {pipu_cli-0.2.1.dist-info → pipu_cli-0.2.3.dist-info}/WHEEL +1 -1
- pipu_cli-0.2.1.dist-info/RECORD +0 -16
- {pipu_cli-0.2.1.dist-info → pipu_cli-0.2.3.dist-info}/entry_points.txt +0 -0
- {pipu_cli-0.2.1.dist-info → pipu_cli-0.2.3.dist-info}/licenses/LICENSE +0 -0
- {pipu_cli-0.2.1.dist-info → pipu_cli-0.2.3.dist-info}/top_level.txt +0 -0
pipu_cli/__init__.py
CHANGED
pipu_cli/cli.py
CHANGED
|
@@ -267,6 +267,225 @@ def update(timeout: int, pre: bool, parallel: int, debug: bool, output: str) ->
|
|
|
267
267
|
sys.exit(1)
|
|
268
268
|
|
|
269
269
|
|
|
270
|
+
# --- Helper functions for upgrade command ---
|
|
271
|
+
|
|
272
|
+
def _step1_inspect_packages(
|
|
273
|
+
console: Console, output: str, timeout: int, debug: bool
|
|
274
|
+
) -> tuple[list, float]:
|
|
275
|
+
"""Step 1: Inspect installed packages."""
|
|
276
|
+
if output != "json":
|
|
277
|
+
console.print("[bold]Step 1/5:[/bold] Inspecting installed packages...")
|
|
278
|
+
|
|
279
|
+
step_start = time.time()
|
|
280
|
+
if output != "json":
|
|
281
|
+
with Progress(
|
|
282
|
+
SpinnerColumn(),
|
|
283
|
+
TextColumn("[progress.description]{task.description}"),
|
|
284
|
+
console=console,
|
|
285
|
+
transient=True
|
|
286
|
+
) as progress:
|
|
287
|
+
progress.add_task("Loading packages...", total=None)
|
|
288
|
+
installed_packages = inspect_installed_packages(timeout=timeout)
|
|
289
|
+
else:
|
|
290
|
+
installed_packages = inspect_installed_packages(timeout=timeout)
|
|
291
|
+
step_time = time.time() - step_start
|
|
292
|
+
|
|
293
|
+
if output != "json":
|
|
294
|
+
console.print(f" Found {len(installed_packages)} installed packages")
|
|
295
|
+
if debug:
|
|
296
|
+
console.print(f" [dim]Time: {step_time:.2f}s[/dim]")
|
|
297
|
+
|
|
298
|
+
return installed_packages, step_time
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def _step2_get_latest_versions(
|
|
302
|
+
console: Console, output: str, debug: bool,
|
|
303
|
+
installed_packages: list, use_cache: bool, cache_enabled: bool,
|
|
304
|
+
timeout: int, pre: bool, parallel: int
|
|
305
|
+
) -> tuple[dict, float, bool]:
|
|
306
|
+
"""Step 2: Get latest versions from cache or network."""
|
|
307
|
+
if output != "json":
|
|
308
|
+
if use_cache:
|
|
309
|
+
console.print("\n[bold]Step 2/5:[/bold] Loading cached version data...")
|
|
310
|
+
else:
|
|
311
|
+
console.print("\n[bold]Step 2/5:[/bold] Fetching latest versions from PyPI...")
|
|
312
|
+
|
|
313
|
+
step_start = time.time()
|
|
314
|
+
latest_versions: dict = {}
|
|
315
|
+
cache_was_used = False
|
|
316
|
+
|
|
317
|
+
if use_cache:
|
|
318
|
+
cache_data = load_cache()
|
|
319
|
+
if cache_data and cache_data.latest_versions:
|
|
320
|
+
for installed_pkg in installed_packages:
|
|
321
|
+
name_lower = installed_pkg.name.lower()
|
|
322
|
+
if name_lower in cache_data.latest_versions:
|
|
323
|
+
cached_version = cache_data.latest_versions[name_lower]
|
|
324
|
+
try:
|
|
325
|
+
latest_ver = Version(cached_version)
|
|
326
|
+
if latest_ver > installed_pkg.version:
|
|
327
|
+
latest_pkg = Package(name=installed_pkg.name, version=latest_ver)
|
|
328
|
+
latest_versions[installed_pkg] = latest_pkg
|
|
329
|
+
except Exception:
|
|
330
|
+
pass
|
|
331
|
+
cache_was_used = True
|
|
332
|
+
else:
|
|
333
|
+
use_cache = False
|
|
334
|
+
|
|
335
|
+
if not use_cache:
|
|
336
|
+
if output != "json":
|
|
337
|
+
with Progress(
|
|
338
|
+
TextColumn("[progress.description]{task.description}"),
|
|
339
|
+
BarColumn(),
|
|
340
|
+
TaskProgressColumn(),
|
|
341
|
+
console=console,
|
|
342
|
+
transient=True
|
|
343
|
+
) as progress:
|
|
344
|
+
task = progress.add_task("Checking packages...", total=len(installed_packages))
|
|
345
|
+
|
|
346
|
+
def update_progress(current: int, total: int) -> None:
|
|
347
|
+
progress.update(task, completed=current)
|
|
348
|
+
|
|
349
|
+
if parallel > 1:
|
|
350
|
+
latest_versions = get_latest_versions_parallel(
|
|
351
|
+
installed_packages, timeout=timeout, include_prereleases=pre,
|
|
352
|
+
max_workers=parallel, progress_callback=update_progress
|
|
353
|
+
)
|
|
354
|
+
else:
|
|
355
|
+
latest_versions = get_latest_versions(
|
|
356
|
+
installed_packages, timeout=timeout, include_prereleases=pre,
|
|
357
|
+
progress_callback=update_progress
|
|
358
|
+
)
|
|
359
|
+
else:
|
|
360
|
+
if parallel > 1:
|
|
361
|
+
latest_versions = get_latest_versions_parallel(
|
|
362
|
+
installed_packages, timeout=timeout, include_prereleases=pre, max_workers=parallel
|
|
363
|
+
)
|
|
364
|
+
else:
|
|
365
|
+
latest_versions = get_latest_versions(
|
|
366
|
+
installed_packages, timeout=timeout, include_prereleases=pre
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
if cache_enabled:
|
|
370
|
+
version_cache = build_version_cache(latest_versions)
|
|
371
|
+
save_cache(version_cache, include_prereleases=pre)
|
|
372
|
+
|
|
373
|
+
step_time = time.time() - step_start
|
|
374
|
+
|
|
375
|
+
if output != "json":
|
|
376
|
+
console.print(f" Found {len(latest_versions)} packages with newer versions available")
|
|
377
|
+
if cache_was_used:
|
|
378
|
+
console.print(" [dim](from cache)[/dim]")
|
|
379
|
+
if debug:
|
|
380
|
+
console.print(f" [dim]Time: {step_time:.2f}s[/dim]")
|
|
381
|
+
|
|
382
|
+
return latest_versions, step_time, cache_was_used
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def _step3_resolve_packages(
|
|
386
|
+
console: Console, output: str, debug: bool,
|
|
387
|
+
latest_versions: dict, installed_packages: list, show_blocked: bool,
|
|
388
|
+
exclude: str, packages: tuple
|
|
389
|
+
) -> tuple[list, list, dict, float]:
|
|
390
|
+
"""Step 3: Resolve upgradable packages and apply filters."""
|
|
391
|
+
if output != "json":
|
|
392
|
+
console.print("\n[bold]Step 3/5:[/bold] Resolving dependency constraints...")
|
|
393
|
+
step_start = time.time()
|
|
394
|
+
|
|
395
|
+
if show_blocked:
|
|
396
|
+
upgradable_packages, blocked_packages = resolve_upgradable_packages_with_reasons(
|
|
397
|
+
latest_versions, installed_packages
|
|
398
|
+
)
|
|
399
|
+
else:
|
|
400
|
+
all_upgradable = resolve_upgradable_packages(latest_versions, installed_packages)
|
|
401
|
+
upgradable_packages = [pkg for pkg in all_upgradable if pkg.upgradable]
|
|
402
|
+
blocked_packages = []
|
|
403
|
+
|
|
404
|
+
step_time = time.time() - step_start
|
|
405
|
+
|
|
406
|
+
# Apply exclusions
|
|
407
|
+
excluded_names = set()
|
|
408
|
+
if exclude:
|
|
409
|
+
excluded_names = {name.strip().lower() for name in exclude.split(',')}
|
|
410
|
+
if debug and excluded_names:
|
|
411
|
+
console.print(f" [dim]Excluding: {', '.join(sorted(excluded_names))}[/dim]")
|
|
412
|
+
|
|
413
|
+
can_upgrade = [pkg for pkg in upgradable_packages if pkg.name.lower() not in excluded_names]
|
|
414
|
+
|
|
415
|
+
# Parse package specifications and filter
|
|
416
|
+
package_constraints: dict = {}
|
|
417
|
+
if packages:
|
|
418
|
+
requested_packages = set()
|
|
419
|
+
for spec in packages:
|
|
420
|
+
name, constraint = parse_package_spec(spec)
|
|
421
|
+
requested_packages.add(name.lower())
|
|
422
|
+
if constraint:
|
|
423
|
+
package_constraints[name.lower()] = constraint
|
|
424
|
+
|
|
425
|
+
can_upgrade = [pkg for pkg in can_upgrade if pkg.name.lower() in requested_packages]
|
|
426
|
+
|
|
427
|
+
if debug:
|
|
428
|
+
console.print(f" [dim]Filtering to: {', '.join(packages)}[/dim]")
|
|
429
|
+
if package_constraints:
|
|
430
|
+
console.print(f" [dim]Version constraints: {package_constraints}[/dim]")
|
|
431
|
+
|
|
432
|
+
if output != "json":
|
|
433
|
+
console.print(f" {len(can_upgrade)} packages can be safely upgraded")
|
|
434
|
+
if debug:
|
|
435
|
+
console.print(f" [dim]Time: {step_time:.2f}s[/dim]")
|
|
436
|
+
|
|
437
|
+
return can_upgrade, blocked_packages, package_constraints, step_time
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def _step5_install_packages(
|
|
441
|
+
console: Console, output: str,
|
|
442
|
+
can_upgrade: list, package_constraints: dict
|
|
443
|
+
) -> tuple[list, float]:
|
|
444
|
+
"""Step 5: Install/upgrade packages."""
|
|
445
|
+
editable_packages = [pkg for pkg in can_upgrade if pkg.is_editable]
|
|
446
|
+
non_editable_packages = [pkg for pkg in can_upgrade if not pkg.is_editable]
|
|
447
|
+
|
|
448
|
+
if output != "json":
|
|
449
|
+
total_to_upgrade = len(non_editable_packages) + len(editable_packages)
|
|
450
|
+
console.print(f"[bold]Step 5/5:[/bold] Upgrading {total_to_upgrade} package(s)...\n")
|
|
451
|
+
step_start = time.time()
|
|
452
|
+
|
|
453
|
+
# Save state for potential rollback
|
|
454
|
+
from pipu_cli.rollback import save_state
|
|
455
|
+
pre_upgrade_packages = [
|
|
456
|
+
{"name": pkg.name, "version": str(pkg.version)}
|
|
457
|
+
for pkg in can_upgrade
|
|
458
|
+
]
|
|
459
|
+
save_state(pre_upgrade_packages, "Pre-upgrade state")
|
|
460
|
+
|
|
461
|
+
stream = ConsoleStream(console) if output != "json" else None
|
|
462
|
+
results = []
|
|
463
|
+
|
|
464
|
+
if non_editable_packages:
|
|
465
|
+
if output != "json":
|
|
466
|
+
console.print(f"Upgrading {len(non_editable_packages)} regular package(s)...\n")
|
|
467
|
+
regular_results = install_packages(
|
|
468
|
+
non_editable_packages,
|
|
469
|
+
output_stream=stream,
|
|
470
|
+
timeout=300,
|
|
471
|
+
version_constraints=package_constraints if package_constraints else None
|
|
472
|
+
)
|
|
473
|
+
results.extend(regular_results)
|
|
474
|
+
|
|
475
|
+
if editable_packages:
|
|
476
|
+
if output != "json":
|
|
477
|
+
console.print(f"\nReinstalling {len(editable_packages)} editable package(s)...\n")
|
|
478
|
+
editable_results = reinstall_editable_packages(
|
|
479
|
+
editable_packages,
|
|
480
|
+
output_stream=stream,
|
|
481
|
+
timeout=300
|
|
482
|
+
)
|
|
483
|
+
results.extend(editable_results)
|
|
484
|
+
|
|
485
|
+
step_time = time.time() - step_start
|
|
486
|
+
return results, step_time
|
|
487
|
+
|
|
488
|
+
|
|
270
489
|
@cli.command()
|
|
271
490
|
@click.argument('packages', nargs=-1)
|
|
272
491
|
@click.option(
|
|
@@ -418,29 +637,7 @@ def upgrade(packages: tuple[str, ...], timeout: int, pre: bool, yes: bool, debug
|
|
|
418
637
|
console.print(f"[dim]Using cached data ({format_cache_age(cache_age)})[/dim]\n")
|
|
419
638
|
|
|
420
639
|
# Step 1: Inspect installed packages
|
|
421
|
-
|
|
422
|
-
console.print("[bold]Step 1/5:[/bold] Inspecting installed packages...")
|
|
423
|
-
|
|
424
|
-
step1_start = time.time()
|
|
425
|
-
if output != "json":
|
|
426
|
-
with Progress(
|
|
427
|
-
SpinnerColumn(),
|
|
428
|
-
TextColumn("[progress.description]{task.description}"),
|
|
429
|
-
console=console,
|
|
430
|
-
transient=True
|
|
431
|
-
) as progress:
|
|
432
|
-
task = progress.add_task("Loading packages...", total=None)
|
|
433
|
-
installed_packages = inspect_installed_packages(timeout=timeout)
|
|
434
|
-
progress.update(task, completed=True)
|
|
435
|
-
else:
|
|
436
|
-
installed_packages = inspect_installed_packages(timeout=timeout)
|
|
437
|
-
step1_time = time.time() - step1_start
|
|
438
|
-
|
|
439
|
-
num_installed = len(installed_packages)
|
|
440
|
-
if output != "json":
|
|
441
|
-
console.print(f" Found {num_installed} installed packages")
|
|
442
|
-
if debug:
|
|
443
|
-
console.print(f" [dim]Time: {step1_time:.2f}s[/dim]")
|
|
640
|
+
installed_packages, step1_time = _step1_inspect_packages(console, output, timeout, debug)
|
|
444
641
|
|
|
445
642
|
if not installed_packages:
|
|
446
643
|
if output == "json":
|
|
@@ -450,90 +647,10 @@ def upgrade(packages: tuple[str, ...], timeout: int, pre: bool, yes: bool, debug
|
|
|
450
647
|
sys.exit(0)
|
|
451
648
|
|
|
452
649
|
# Step 2: Get latest versions (from cache or network)
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
console.print("\n[bold]Step 2/5:[/bold] Fetching latest versions from PyPI...")
|
|
458
|
-
|
|
459
|
-
step2_start = time.time()
|
|
460
|
-
latest_versions: dict = {}
|
|
461
|
-
cache_was_used = False
|
|
462
|
-
|
|
463
|
-
if use_cache:
|
|
464
|
-
# Load latest versions from cache (skip PyPI queries entirely)
|
|
465
|
-
cache_data = load_cache()
|
|
466
|
-
if cache_data and cache_data.latest_versions:
|
|
467
|
-
# Reconstruct latest_versions dict from cache
|
|
468
|
-
# Maps InstalledPackage -> Package with latest version
|
|
469
|
-
for installed_pkg in installed_packages:
|
|
470
|
-
name_lower = installed_pkg.name.lower()
|
|
471
|
-
if name_lower in cache_data.latest_versions:
|
|
472
|
-
cached_version = cache_data.latest_versions[name_lower]
|
|
473
|
-
try:
|
|
474
|
-
latest_ver = Version(cached_version)
|
|
475
|
-
# Only include if it's actually newer
|
|
476
|
-
if latest_ver > installed_pkg.version:
|
|
477
|
-
latest_pkg = Package(
|
|
478
|
-
name=installed_pkg.name,
|
|
479
|
-
version=latest_ver
|
|
480
|
-
)
|
|
481
|
-
latest_versions[installed_pkg] = latest_pkg
|
|
482
|
-
except Exception:
|
|
483
|
-
pass # Skip invalid versions
|
|
484
|
-
cache_was_used = True
|
|
485
|
-
else:
|
|
486
|
-
use_cache = False
|
|
487
|
-
|
|
488
|
-
if not use_cache:
|
|
489
|
-
# Fetch from network
|
|
490
|
-
if output != "json":
|
|
491
|
-
with Progress(
|
|
492
|
-
TextColumn("[progress.description]{task.description}"),
|
|
493
|
-
BarColumn(),
|
|
494
|
-
TaskProgressColumn(),
|
|
495
|
-
console=console,
|
|
496
|
-
transient=True
|
|
497
|
-
) as progress:
|
|
498
|
-
task = progress.add_task("Checking packages...", total=len(installed_packages))
|
|
499
|
-
|
|
500
|
-
def update_progress(current: int, total: int) -> None:
|
|
501
|
-
progress.update(task, completed=current)
|
|
502
|
-
|
|
503
|
-
if parallel > 1:
|
|
504
|
-
latest_versions = get_latest_versions_parallel(
|
|
505
|
-
installed_packages, timeout=timeout, include_prereleases=pre,
|
|
506
|
-
max_workers=parallel, progress_callback=update_progress
|
|
507
|
-
)
|
|
508
|
-
else:
|
|
509
|
-
latest_versions = get_latest_versions(
|
|
510
|
-
installed_packages, timeout=timeout, include_prereleases=pre,
|
|
511
|
-
progress_callback=update_progress
|
|
512
|
-
)
|
|
513
|
-
else:
|
|
514
|
-
if parallel > 1:
|
|
515
|
-
latest_versions = get_latest_versions_parallel(
|
|
516
|
-
installed_packages, timeout=timeout, include_prereleases=pre, max_workers=parallel
|
|
517
|
-
)
|
|
518
|
-
else:
|
|
519
|
-
latest_versions = get_latest_versions(
|
|
520
|
-
installed_packages, timeout=timeout, include_prereleases=pre
|
|
521
|
-
)
|
|
522
|
-
|
|
523
|
-
# Update cache with fresh data
|
|
524
|
-
if cache_enabled:
|
|
525
|
-
version_cache = build_version_cache(latest_versions)
|
|
526
|
-
save_cache(version_cache, include_prereleases=pre)
|
|
527
|
-
|
|
528
|
-
step2_time = time.time() - step2_start
|
|
529
|
-
|
|
530
|
-
num_updates = len(latest_versions)
|
|
531
|
-
if output != "json":
|
|
532
|
-
console.print(f" Found {num_updates} packages with newer versions available")
|
|
533
|
-
if cache_was_used:
|
|
534
|
-
console.print(" [dim](from cache)[/dim]")
|
|
535
|
-
if debug:
|
|
536
|
-
console.print(f" [dim]Time: {step2_time:.2f}s[/dim]")
|
|
650
|
+
latest_versions, step2_time, _ = _step2_get_latest_versions(
|
|
651
|
+
console, output, debug, installed_packages, use_cache, cache_enabled,
|
|
652
|
+
timeout, pre, parallel
|
|
653
|
+
)
|
|
537
654
|
|
|
538
655
|
if not latest_versions:
|
|
539
656
|
if output == "json":
|
|
@@ -543,47 +660,10 @@ def upgrade(packages: tuple[str, ...], timeout: int, pre: bool, yes: bool, debug
|
|
|
543
660
|
sys.exit(0)
|
|
544
661
|
|
|
545
662
|
# Step 3: Resolve upgradable packages
|
|
546
|
-
|
|
547
|
-
console
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
if show_blocked:
|
|
551
|
-
upgradable_packages, blocked_packages = resolve_upgradable_packages_with_reasons(
|
|
552
|
-
latest_versions, installed_packages
|
|
553
|
-
)
|
|
554
|
-
else:
|
|
555
|
-
all_upgradable = resolve_upgradable_packages(latest_versions, installed_packages)
|
|
556
|
-
upgradable_packages = [pkg for pkg in all_upgradable if pkg.upgradable]
|
|
557
|
-
blocked_packages = []
|
|
558
|
-
|
|
559
|
-
step3_time = time.time() - step3_start
|
|
560
|
-
|
|
561
|
-
# Apply exclusions
|
|
562
|
-
excluded_names = set()
|
|
563
|
-
if exclude:
|
|
564
|
-
excluded_names = {name.strip().lower() for name in exclude.split(',')}
|
|
565
|
-
if debug and excluded_names:
|
|
566
|
-
console.print(f" [dim]Excluding: {', '.join(sorted(excluded_names))}[/dim]")
|
|
567
|
-
|
|
568
|
-
# Filter to only upgradable packages (excluding excluded ones)
|
|
569
|
-
can_upgrade = [pkg for pkg in upgradable_packages if pkg.name.lower() not in excluded_names]
|
|
570
|
-
|
|
571
|
-
# Parse package specifications and filter to specific packages if provided
|
|
572
|
-
package_constraints = {}
|
|
573
|
-
if packages:
|
|
574
|
-
requested_packages = set()
|
|
575
|
-
for spec in packages:
|
|
576
|
-
name, constraint = parse_package_spec(spec)
|
|
577
|
-
requested_packages.add(name.lower())
|
|
578
|
-
if constraint:
|
|
579
|
-
package_constraints[name.lower()] = constraint
|
|
580
|
-
|
|
581
|
-
can_upgrade = [pkg for pkg in can_upgrade if pkg.name.lower() in requested_packages]
|
|
582
|
-
|
|
583
|
-
if debug:
|
|
584
|
-
console.print(f" [dim]Filtering to: {', '.join(packages)}[/dim]")
|
|
585
|
-
if package_constraints:
|
|
586
|
-
console.print(f" [dim]Version constraints: {package_constraints}[/dim]")
|
|
663
|
+
can_upgrade, blocked_packages, package_constraints, step3_time = _step3_resolve_packages(
|
|
664
|
+
console, output, debug, latest_versions, installed_packages, show_blocked,
|
|
665
|
+
exclude, packages
|
|
666
|
+
)
|
|
587
667
|
|
|
588
668
|
if not can_upgrade:
|
|
589
669
|
if output == "json":
|
|
@@ -600,12 +680,6 @@ def upgrade(packages: tuple[str, ...], timeout: int, pre: bool, yes: bool, debug
|
|
|
600
680
|
print_blocked_packages_table(blocked_packages, console=console)
|
|
601
681
|
sys.exit(0)
|
|
602
682
|
|
|
603
|
-
num_upgradable = len(can_upgrade)
|
|
604
|
-
if output != "json":
|
|
605
|
-
console.print(f" {num_upgradable} packages can be safely upgraded")
|
|
606
|
-
if debug:
|
|
607
|
-
console.print(f" [dim]Time: {step3_time:.2f}s[/dim]")
|
|
608
|
-
|
|
609
683
|
# Step 4: Display table and ask for confirmation
|
|
610
684
|
if output == "json":
|
|
611
685
|
assert json_formatter is not None
|
|
@@ -642,51 +716,8 @@ def upgrade(packages: tuple[str, ...], timeout: int, pre: bool, yes: bool, debug
|
|
|
642
716
|
console.print("[yellow]Upgrade cancelled.[/yellow]")
|
|
643
717
|
sys.exit(0)
|
|
644
718
|
|
|
645
|
-
# Separate editable and non-editable packages
|
|
646
|
-
editable_packages = [pkg for pkg in can_upgrade if pkg.is_editable]
|
|
647
|
-
non_editable_packages = [pkg for pkg in can_upgrade if not pkg.is_editable]
|
|
648
|
-
|
|
649
719
|
# Step 5: Install packages
|
|
650
|
-
|
|
651
|
-
total_to_upgrade = len(non_editable_packages) + len(editable_packages)
|
|
652
|
-
console.print(f"[bold]Step 5/5:[/bold] Upgrading {total_to_upgrade} package(s)...\n")
|
|
653
|
-
step5_start = time.time()
|
|
654
|
-
|
|
655
|
-
# Save state for potential rollback
|
|
656
|
-
from pipu_cli.rollback import save_state
|
|
657
|
-
pre_upgrade_packages = [
|
|
658
|
-
{"name": pkg.name, "version": str(pkg.version)}
|
|
659
|
-
for pkg in can_upgrade
|
|
660
|
-
]
|
|
661
|
-
save_state(pre_upgrade_packages, "Pre-upgrade state")
|
|
662
|
-
|
|
663
|
-
stream = ConsoleStream(console) if output != "json" else None
|
|
664
|
-
results = []
|
|
665
|
-
|
|
666
|
-
# First, upgrade non-editable packages via pip install --upgrade
|
|
667
|
-
if non_editable_packages:
|
|
668
|
-
if output != "json":
|
|
669
|
-
console.print(f"Upgrading {len(non_editable_packages)} regular package(s)...\n")
|
|
670
|
-
regular_results = install_packages(
|
|
671
|
-
non_editable_packages,
|
|
672
|
-
output_stream=stream,
|
|
673
|
-
timeout=300,
|
|
674
|
-
version_constraints=package_constraints if package_constraints else None
|
|
675
|
-
)
|
|
676
|
-
results.extend(regular_results)
|
|
677
|
-
|
|
678
|
-
# Then, reinstall editable packages to update their versions
|
|
679
|
-
if editable_packages:
|
|
680
|
-
if output != "json":
|
|
681
|
-
console.print(f"\nReinstalling {len(editable_packages)} editable package(s)...\n")
|
|
682
|
-
editable_results = reinstall_editable_packages(
|
|
683
|
-
editable_packages,
|
|
684
|
-
output_stream=stream,
|
|
685
|
-
timeout=300
|
|
686
|
-
)
|
|
687
|
-
results.extend(editable_results)
|
|
688
|
-
|
|
689
|
-
step5_time = time.time() - step5_start
|
|
720
|
+
results, step5_time = _step5_install_packages(console, output, can_upgrade, package_constraints)
|
|
690
721
|
|
|
691
722
|
# Update requirements file if requested
|
|
692
723
|
if update_requirements:
|
pipu_cli/package_management.py
CHANGED
|
@@ -18,6 +18,7 @@ from pip._internal.index.collector import LinkCollector
|
|
|
18
18
|
from pip._internal.models.search_scope import SearchScope
|
|
19
19
|
from pip._internal.network.session import PipSession
|
|
20
20
|
from pip._internal.models.selection_prefs import SelectionPreferences
|
|
21
|
+
from pip._internal.models.release_control import ReleaseControl
|
|
21
22
|
|
|
22
23
|
# Set up module logger
|
|
23
24
|
logger = logging.getLogger(__name__)
|
|
@@ -370,9 +371,10 @@ def get_latest_versions_parallel(
|
|
|
370
371
|
raise ConnectionError(f"Failed to create network session: {e}") from e
|
|
371
372
|
|
|
372
373
|
# Set up package finder with configured indexes
|
|
374
|
+
release_control = ReleaseControl(all_releases={":all:"}) if include_prereleases else None
|
|
373
375
|
selection_prefs = SelectionPreferences(
|
|
374
376
|
allow_yanked=False,
|
|
375
|
-
|
|
377
|
+
release_control=release_control
|
|
376
378
|
)
|
|
377
379
|
|
|
378
380
|
search_scope = SearchScope.create(
|
|
@@ -565,9 +567,10 @@ def get_latest_versions(
|
|
|
565
567
|
raise ConnectionError(f"Failed to create network session: {e}") from e
|
|
566
568
|
|
|
567
569
|
# Set up package finder with configured indexes
|
|
570
|
+
release_control = ReleaseControl(all_releases={":all:"}) if include_prereleases else None
|
|
568
571
|
selection_prefs = SelectionPreferences(
|
|
569
572
|
allow_yanked=False,
|
|
570
|
-
|
|
573
|
+
release_control=release_control
|
|
571
574
|
)
|
|
572
575
|
|
|
573
576
|
search_scope = SearchScope.create(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pipu-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: A cute Python package updater
|
|
5
5
|
Author-email: Scott Arne Johnson <scott.arne.johnson@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -13,6 +13,7 @@ License-File: LICENSE
|
|
|
13
13
|
Requires-Dist: rich_click<2.0,>=1.7
|
|
14
14
|
Requires-Dist: rich<15.0,>=13.0
|
|
15
15
|
Requires-Dist: packaging<26.0,>=23.0
|
|
16
|
+
Requires-Dist: pip<27.0,>=26.0
|
|
16
17
|
Requires-Dist: tomli>=2.0.0; python_version < "3.11"
|
|
17
18
|
Provides-Extra: dev
|
|
18
19
|
Requires-Dist: invoke; extra == "dev"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
pipu_cli/__init__.py,sha256=Flk9VrywBlPX9miUgrsZc20H4kQdTJOsLXOZ47F_o1E,1191
|
|
2
|
+
pipu_cli/cache.py,sha256=d5BOItcJSlNfPEnYb4tbMmntzIDjWIl1ZUb5Xo5bJiQ,8243
|
|
3
|
+
pipu_cli/cli.py,sha256=Sl3kHM5-yYVsomXYRy7KCL0e6dC_mSS5fFIdMgf6pVg,34963
|
|
4
|
+
pipu_cli/config.py,sha256=lixyWhJBz5GqdyRIygc4g5Wzc94HPC4sVFCgeINtQtw,1542
|
|
5
|
+
pipu_cli/config_file.py,sha256=0vJbaDS4WDR4RRYA8gKLDtQRi-Stzm9a85qjmnNCqys,2186
|
|
6
|
+
pipu_cli/output.py,sha256=9g64hxHIXxJlq0mmhRwZnbPMMGPpTfSRkH90rc-QPjA,3510
|
|
7
|
+
pipu_cli/package_management.py,sha256=WOzAl5J6JwiFj3zZN5eLdyLrm2bV5A3KIT8D2aqO3wc,50893
|
|
8
|
+
pipu_cli/pretty.py,sha256=6qBohKDtocm6vJc2rtH9RLgvvHYJiaGMnmhs6QyC0kE,9293
|
|
9
|
+
pipu_cli/requirements.py,sha256=zbh7XwxD9he_5csJitEGT0NfiE4qbXPw_-JSDuHv4G8,2665
|
|
10
|
+
pipu_cli/rollback.py,sha256=gL9ueYtAKDoALqRfJE2S5gnw1Id5QBLaPC1UL_WjzzY,2980
|
|
11
|
+
pipu_cli-0.2.3.dist-info/licenses/LICENSE,sha256=q6TxVbSI0WMB9ulF2V0FWQfeA5om3d-T9X7QwuhdiYE,1075
|
|
12
|
+
pipu_cli-0.2.3.dist-info/METADATA,sha256=Th3WenJaBluzER-g95FYSs9pmYP-3z1s4m08UxYtbQw,11950
|
|
13
|
+
pipu_cli-0.2.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
14
|
+
pipu_cli-0.2.3.dist-info/entry_points.txt,sha256=VSv6od00zOPblnFPflNLaci4jBtQIgLYJjL1BKxLz_o,42
|
|
15
|
+
pipu_cli-0.2.3.dist-info/top_level.txt,sha256=z3Yce93-jGQjGRpsGZUZvbS8osh3OyS7MVpzG0uBE5M,9
|
|
16
|
+
pipu_cli-0.2.3.dist-info/RECORD,,
|
pipu_cli-0.2.1.dist-info/RECORD
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
pipu_cli/__init__.py,sha256=DYhOEmnqarSXQjteuoviNNHqmkBb1xyBh7E49IDBJzs,1191
|
|
2
|
-
pipu_cli/cache.py,sha256=d5BOItcJSlNfPEnYb4tbMmntzIDjWIl1ZUb5Xo5bJiQ,8243
|
|
3
|
-
pipu_cli/cli.py,sha256=kj1ANOl_s-Ac02ZR-NLLREnM2_Av__KqMMBYr3cS2sY,34761
|
|
4
|
-
pipu_cli/config.py,sha256=lixyWhJBz5GqdyRIygc4g5Wzc94HPC4sVFCgeINtQtw,1542
|
|
5
|
-
pipu_cli/config_file.py,sha256=0vJbaDS4WDR4RRYA8gKLDtQRi-Stzm9a85qjmnNCqys,2186
|
|
6
|
-
pipu_cli/output.py,sha256=9g64hxHIXxJlq0mmhRwZnbPMMGPpTfSRkH90rc-QPjA,3510
|
|
7
|
-
pipu_cli/package_management.py,sha256=TXATyeu0RmoRbN1nsDKhZCwlnrZGgj-lK5GnL7opoh8,50661
|
|
8
|
-
pipu_cli/pretty.py,sha256=6qBohKDtocm6vJc2rtH9RLgvvHYJiaGMnmhs6QyC0kE,9293
|
|
9
|
-
pipu_cli/requirements.py,sha256=zbh7XwxD9he_5csJitEGT0NfiE4qbXPw_-JSDuHv4G8,2665
|
|
10
|
-
pipu_cli/rollback.py,sha256=gL9ueYtAKDoALqRfJE2S5gnw1Id5QBLaPC1UL_WjzzY,2980
|
|
11
|
-
pipu_cli-0.2.1.dist-info/licenses/LICENSE,sha256=q6TxVbSI0WMB9ulF2V0FWQfeA5om3d-T9X7QwuhdiYE,1075
|
|
12
|
-
pipu_cli-0.2.1.dist-info/METADATA,sha256=G39M3WDHd-oYkPEm4-pBTF6rlPNYIjUrKr717DyByVY,11919
|
|
13
|
-
pipu_cli-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
14
|
-
pipu_cli-0.2.1.dist-info/entry_points.txt,sha256=VSv6od00zOPblnFPflNLaci4jBtQIgLYJjL1BKxLz_o,42
|
|
15
|
-
pipu_cli-0.2.1.dist-info/top_level.txt,sha256=z3Yce93-jGQjGRpsGZUZvbS8osh3OyS7MVpzG0uBE5M,9
|
|
16
|
-
pipu_cli-0.2.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|