codeshift 0.3.1__py3-none-any.whl → 0.3.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.
@@ -149,6 +149,12 @@ def run_single_upgrade(
149
149
  default=".",
150
150
  help="Path to the project to analyze",
151
151
  )
152
+ @click.option(
153
+ "--all",
154
+ "upgrade_all_pkgs",
155
+ is_flag=True,
156
+ help="Upgrade all outdated packages (not just Tier 1 or major upgrades)",
157
+ )
152
158
  @click.option(
153
159
  "--tier1-only",
154
160
  is_flag=True,
@@ -189,6 +195,7 @@ def run_single_upgrade(
189
195
  )
190
196
  def upgrade_all(
191
197
  path: str,
198
+ upgrade_all_pkgs: bool,
192
199
  tier1_only: bool,
193
200
  major_only: bool,
194
201
  include: tuple,
@@ -206,12 +213,15 @@ def upgrade_all(
206
213
  - All Tier 1 libraries (pydantic, fastapi, sqlalchemy, pandas, requests)
207
214
  - Any library with a major version upgrade available
208
215
 
216
+ Use --all to upgrade ALL outdated packages, regardless of tier or upgrade type.
217
+
209
218
  After migration, dependency files (pyproject.toml, requirements.txt) are
210
219
  automatically updated with the new versions unless --no-update-deps is specified.
211
220
 
212
221
  \b
213
222
  Examples:
214
223
  codeshift upgrade-all
224
+ codeshift upgrade-all --all
215
225
  codeshift upgrade-all --tier1-only
216
226
  codeshift upgrade-all --include pydantic --include fastapi
217
227
  codeshift upgrade-all --exclude pandas
@@ -247,6 +257,7 @@ def upgrade_all(
247
257
  BarColumn(),
248
258
  TaskProgressColumn(),
249
259
  console=console,
260
+ transient=True,
250
261
  ) as progress:
251
262
  task = progress.add_task("Checking for updates...", total=len(dependencies))
252
263
 
@@ -298,7 +309,8 @@ def upgrade_all(
298
309
  continue
299
310
 
300
311
  # By default, include Tier 1 libraries and major upgrades
301
- if not (tier1_only or major_only or include):
312
+ # Use --all to include all outdated packages
313
+ if not (tier1_only or major_only or include or upgrade_all_pkgs):
302
314
  if not (pkg["is_tier1"] or pkg["is_major"]):
303
315
  continue
304
316
 
@@ -306,7 +318,9 @@ def upgrade_all(
306
318
 
307
319
  if not upgradeable:
308
320
  console.print("\n[yellow]No upgradeable packages found matching the criteria.[/]")
309
- console.print("[dim]Use --verbose to see all outdated packages, or adjust filters.[/]")
321
+ console.print(
322
+ "[dim]Use --all to upgrade all outdated packages, or --verbose to see details.[/]"
323
+ )
310
324
 
311
325
  if verbose and outdated:
312
326
  console.print("\nOutdated packages (not matching criteria):")
@@ -334,9 +348,10 @@ def upgrade_all(
334
348
  table.add_row(str(pkg["name"]), str(pkg["current"]), str(pkg["latest"]), type_str, tier_str)
335
349
 
336
350
  console.print(table)
351
+ console.print() # Ensure table is fully rendered before progress bar
337
352
 
338
353
  # Run upgrades for each package
339
- console.print("\n[bold]Running migrations...[/]\n")
354
+ console.print("[bold]Running migrations...[/]\n")
340
355
 
341
356
  all_results: dict[str, list[dict]] = {}
342
357
  migration_summary: list[dict] = []
@@ -347,6 +362,7 @@ def upgrade_all(
347
362
  BarColumn(),
348
363
  TaskProgressColumn(),
349
364
  console=console,
365
+ transient=True,
350
366
  ) as progress:
351
367
  task = progress.add_task("Upgrading packages...", total=len(upgradeable))
352
368
 
@@ -398,75 +414,72 @@ def upgrade_all(
398
414
 
399
415
  progress.advance(task)
400
416
 
401
- # Display results summary
402
- if not migration_summary:
417
+ # Display code transformation results summary
418
+ if migration_summary:
419
+ console.print("\n[bold]Code Migration Summary[/]\n")
420
+
421
+ summary_table = Table()
422
+ summary_table.add_column("Library", style="cyan")
423
+ summary_table.add_column("Migration", justify="center")
424
+ summary_table.add_column("Files", justify="right")
425
+ summary_table.add_column("Changes", justify="right")
426
+ summary_table.add_column("Status", justify="center")
427
+
428
+ total_files = 0
429
+ total_changes = 0
430
+
431
+ for summary in migration_summary:
432
+ summary_table.add_row(
433
+ summary["library"],
434
+ f"{summary['from_version']} → {summary['to_version']}",
435
+ str(summary["files_changed"]),
436
+ str(summary["total_changes"]),
437
+ "[green]Ready[/]",
438
+ )
439
+ total_files += summary["files_changed"]
440
+ total_changes += summary["total_changes"]
441
+
442
+ console.print(summary_table)
403
443
  console.print(
404
- "[green]No changes needed![/] Your code appears to be compatible with the latest versions."
444
+ f"\n[bold]Total:[/] [cyan]{total_changes}[/] changes across [cyan]{total_files}[/] files"
405
445
  )
406
- return
407
446
 
408
- console.print("\n[bold]Migration Summary[/]\n")
409
-
410
- summary_table = Table()
411
- summary_table.add_column("Library", style="cyan")
412
- summary_table.add_column("Migration", justify="center")
413
- summary_table.add_column("Files", justify="right")
414
- summary_table.add_column("Changes", justify="right")
415
- summary_table.add_column("Status", justify="center")
416
-
417
- total_files = 0
418
- total_changes = 0
419
-
420
- for summary in migration_summary:
421
- summary_table.add_row(
422
- summary["library"],
423
- f"{summary['from_version']} → {summary['to_version']}",
424
- str(summary["files_changed"]),
425
- str(summary["total_changes"]),
426
- "[green]Ready[/]",
447
+ # Show detailed changes if verbose
448
+ if verbose:
449
+ console.print("\n[bold]Change Details[/]")
450
+ for lib_name, lib_results in all_results.items():
451
+ console.print(f"\n[bold cyan]{lib_name}[/]")
452
+ for result_dict in lib_results:
453
+ try:
454
+ display_path = str(
455
+ Path(str(result_dict["file_path"])).relative_to(project_path)
456
+ )
457
+ except ValueError:
458
+ display_path = str(result_dict["file_path"])
459
+ console.print(f" [cyan]{display_path}[/]:")
460
+ for change_dict in result_dict["changes"]:
461
+ console.print(f" • {change_dict['description']}")
462
+ else:
463
+ console.print(
464
+ "\n[green]No code changes needed.[/] Your code is compatible with the new versions."
427
465
  )
428
- total_files += summary["files_changed"]
429
- total_changes += summary["total_changes"]
430
-
431
- console.print(summary_table)
432
- console.print(
433
- f"\n[bold]Total:[/] [cyan]{total_changes}[/] changes across [cyan]{total_files}[/] files"
434
- )
435
466
 
436
- # Show detailed changes if verbose
437
- if verbose:
438
- console.print("\n[bold]Change Details[/]")
439
- for lib_name, lib_results in all_results.items():
440
- console.print(f"\n[bold cyan]{lib_name}[/]")
441
- for result_dict in lib_results:
442
- try:
443
- display_path = str(
444
- Path(str(result_dict["file_path"])).relative_to(project_path)
445
- )
446
- except ValueError:
447
- display_path = str(result_dict["file_path"])
448
- console.print(f" [cyan]{display_path}[/]:")
449
- for change_dict in result_dict["changes"]:
450
- console.print(f" • {change_dict['description']}")
451
-
452
- # Update dependency files with new versions
453
- if update_deps and migration_summary:
467
+ # Update dependency files with new versions for ALL upgradeable packages
468
+ if update_deps and upgradeable:
454
469
  console.print("\n[bold]Updating dependency files...[/]\n")
455
470
 
456
471
  dep_parser = DependencyParser(project_path)
457
472
  dep_updates: list[tuple[str, str, list[tuple[Path, bool]]]] = []
458
473
 
459
- for summary in migration_summary:
474
+ for pkg in upgradeable:
460
475
  if not dry_run:
461
476
  update_results = dep_parser.update_dependency_version(
462
- str(summary["library"]), str(summary["to_version"])
463
- )
464
- dep_updates.append(
465
- (str(summary["library"]), str(summary["to_version"]), update_results)
477
+ str(pkg["name"]), str(pkg["latest"])
466
478
  )
479
+ dep_updates.append((str(pkg["name"]), str(pkg["latest"]), update_results))
467
480
  else:
468
481
  # In dry run, just show what would be updated
469
- dep_updates.append((str(summary["library"]), str(summary["to_version"]), []))
482
+ dep_updates.append((str(pkg["name"]), str(pkg["latest"]), []))
470
483
 
471
484
  # Display update results
472
485
  if dry_run:
@@ -491,8 +504,8 @@ def upgrade_all(
491
504
  "[dim]No dependency files were updated (dependencies may not be pinned)[/]"
492
505
  )
493
506
 
494
- # Save state
495
- if not dry_run:
507
+ # Save state only if there are code changes to review
508
+ if not dry_run and migration_summary:
496
509
  # Merge all results into a combined state format
497
510
  # This maintains compatibility with diff/apply commands
498
511
  combined_results: list[dict[str, Any]] = []
@@ -514,5 +527,9 @@ def upgrade_all(
514
527
  console.print("\nNext steps:")
515
528
  console.print(" [cyan]codeshift diff[/] - View detailed diff of proposed changes")
516
529
  console.print(" [cyan]codeshift apply[/] - Apply changes to your files")
517
- else:
518
- console.print("\n[dim]Dry run mode - no state saved[/]")
530
+ elif dry_run:
531
+ console.print("\n[dim]Dry run mode - no changes applied[/]")
532
+ elif not migration_summary and upgradeable:
533
+ console.print(
534
+ "\n[green]Dependencies updated.[/] No code changes required for this upgrade."
535
+ )
@@ -370,7 +370,7 @@ class DependencyParser:
370
370
 
371
371
  # Pattern for standard dependencies: "pydantic>=1.0,<2.0" or "pydantic==1.10.0"
372
372
  # Match the package name followed by version specifiers
373
- pattern = rf'("{name})((?:[><=!~]+[^"]*)?)"'
373
+ pattern = rf'"({name})((?:[><=!~]+[^"]*)?)"'
374
374
  replacement = rf'"\1>={new_version}"'
375
375
  content = re.sub(pattern, replacement, content, flags=re.IGNORECASE)
376
376
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeshift
3
- Version: 0.3.1
3
+ Version: 0.3.3
4
4
  Summary: AI-powered CLI tool that migrates Python code to handle breaking dependency changes
5
5
  Author: PyResolve Team
6
6
  License: MIT
@@ -26,7 +26,7 @@ codeshift/cli/commands/auth.py,sha256=uXUtNEtAH17vhSlANfcFR5pCP8NQmFJ7Uw0bN30rYl
26
26
  codeshift/cli/commands/diff.py,sha256=4LjrVRu4lhj-aOBvClOnEnN0l2nZEU5S1_qzYoXL4dQ,6357
27
27
  codeshift/cli/commands/scan.py,sha256=JXR3MMKWOh1dlAEJ-OXh-EjCDBrBMxqzI6snZcBirqU,11386
28
28
  codeshift/cli/commands/upgrade.py,sha256=_V1BP15BJR6OZHg7jdq90kfdUpjquf_FoWNNEWNzrnI,15874
29
- codeshift/cli/commands/upgrade_all.py,sha256=Ef5xj0f-MHmmrFBpjD-UjDD6FEf7YDx3kWfyS-N6ebU,18103
29
+ codeshift/cli/commands/upgrade_all.py,sha256=v-fz9jWCzJWWW6d0QXTdOfd2M54okI9AA6qv7qxLPiE,18964
30
30
  codeshift/knowledge/__init__.py,sha256=_YwrLgjvsJQuYajfnIhUQqFeircF0MfkI9zJBPZTupc,1221
31
31
  codeshift/knowledge/cache.py,sha256=aEx9aNDfrzCYMzlPRBzBOYiFIAGDcZJfQvcXroa5vsA,4837
32
32
  codeshift/knowledge/generator.py,sha256=dFmvkg1PH73fvImuoFq8iykD2wVgmkOGbcD9tH-ruCs,7222
@@ -53,7 +53,7 @@ codeshift/migrator/transforms/requests_transformer.py,sha256=3HWT7OY-BJOrhwLXoPv
53
53
  codeshift/migrator/transforms/sqlalchemy_transformer.py,sha256=VEt50K8Aok0NGB63RvIvSaXP7EG0LBSyXGA3jiNNayA,7143
54
54
  codeshift/scanner/__init__.py,sha256=GFx9yMPZVuxBC8mGOPZoINsCsJgHV4TSjiV4KSF3fPU,300
55
55
  codeshift/scanner/code_scanner.py,sha256=YGuHVI1FN0h8cGSARFlF5duFd8WBCJUSVMcqCbsjqEQ,12859
56
- codeshift/scanner/dependency_parser.py,sha256=JzIfg_yUVmh3exzbXowhWuN_W8dbVTmY3bTGgAojc08,15372
56
+ codeshift/scanner/dependency_parser.py,sha256=Vd-wbgcG2trgLN7wntbNrGwuXvamn3u7B5SGvORdPiY,15372
57
57
  codeshift/utils/__init__.py,sha256=dNtKUzFwoMxuEl41d_V0Zggv5lprZnOowB8Qt_THwbg,148
58
58
  codeshift/utils/api_client.py,sha256=RUbKiox9dc_xc4z7IcrZ7plObYkkaKFa7Dw4qi75KGw,8010
59
59
  codeshift/utils/cache.py,sha256=WHwNToQVmzhLgmHvt9nWUlzDFmVLBp_Sax7R4rrQfOg,8793
@@ -62,9 +62,9 @@ codeshift/utils/llm_client.py,sha256=WkT3KftJi7rsj8MXH4MVJvznugicb2XpkKqnqRET1eo
62
62
  codeshift/validator/__init__.py,sha256=WRQSfJ7eLJdjR2_f_dXSaBtfawkvu1Dlu20Gh76D12c,280
63
63
  codeshift/validator/syntax_checker.py,sha256=FJeLIqhNhV7_Xj2RskHScJZks6A9fybaqv5Z1-MGDfo,5343
64
64
  codeshift/validator/test_runner.py,sha256=VX0OqkuI3AJxOUzRW2_BEjdDsMw1N4a0od-pPbSF6O8,6760
65
- codeshift-0.3.1.dist-info/licenses/LICENSE,sha256=SrjIFBfm7GQh90Giv7mEiPnYdgp1wsp0RnOTT6HkeVw,1066
66
- codeshift-0.3.1.dist-info/METADATA,sha256=k5VGEuELfjBQ6pK9mQLec6GlNhRCtDUt9CZaWl38Nvo,13314
67
- codeshift-0.3.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
68
- codeshift-0.3.1.dist-info/entry_points.txt,sha256=AlJ8V7a2pNyu-9UiRKUWiTMIJtaYAUnlg53Y-wFHiK0,53
69
- codeshift-0.3.1.dist-info/top_level.txt,sha256=Ct42mtGs5foZ4MyYSksd5rXP0qFhWSZz8Y8mON0EEds,10
70
- codeshift-0.3.1.dist-info/RECORD,,
65
+ codeshift-0.3.3.dist-info/licenses/LICENSE,sha256=SrjIFBfm7GQh90Giv7mEiPnYdgp1wsp0RnOTT6HkeVw,1066
66
+ codeshift-0.3.3.dist-info/METADATA,sha256=dozTkvNwyeeewqjv7XHU_94xM0QBbknpZYCBR1rdZPg,13314
67
+ codeshift-0.3.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
68
+ codeshift-0.3.3.dist-info/entry_points.txt,sha256=AlJ8V7a2pNyu-9UiRKUWiTMIJtaYAUnlg53Y-wFHiK0,53
69
+ codeshift-0.3.3.dist-info/top_level.txt,sha256=Ct42mtGs5foZ4MyYSksd5rXP0qFhWSZz8Y8mON0EEds,10
70
+ codeshift-0.3.3.dist-info/RECORD,,