@@ -22,6 +22,7 @@ use uv_distribution_types::{
22
22
Requirement , RequiresPython , UnresolvedRequirementSpecification ,
23
23
} ;
24
24
use uv_git:: ResolvedRepositoryReference ;
25
+ use uv_git_types:: GitOid ;
25
26
use uv_normalize:: { GroupName , PackageName } ;
26
27
use uv_pep440:: Version ;
27
28
use uv_preview:: { Preview , PreviewFeatures } ;
@@ -30,7 +31,7 @@ use uv_python::{Interpreter, PythonDownloads, PythonEnvironment, PythonPreferenc
30
31
use uv_requirements:: ExtrasResolver ;
31
32
use uv_requirements:: upgrade:: { LockedRequirements , read_lock_requirements} ;
32
33
use uv_resolver:: {
33
- FlatIndex , InMemoryIndex , Lock , Options , OptionsBuilder , PythonRequirement ,
34
+ FlatIndex , InMemoryIndex , Lock , Options , OptionsBuilder , Package , PythonRequirement ,
34
35
ResolverEnvironment , ResolverManifest , SatisfiesResult , UniversalMarker ,
35
36
} ;
36
37
use uv_scripts:: Pep723Script ;
@@ -1355,28 +1356,56 @@ impl ValidatedLock {
1355
1356
}
1356
1357
}
1357
1358
1359
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
1360
+ struct LockEventVersion < ' lock > {
1361
+ /// The version of the package, or `None` if the package has a dynamic version.
1362
+ version : Option < & ' lock Version > ,
1363
+ /// The short Git SHA of the package, if it was installed from a Git repository.
1364
+ sha : Option < & ' lock str > ,
1365
+ }
1366
+
1367
+ impl < ' lock > From < & ' lock Package > for LockEventVersion < ' lock > {
1368
+ fn from ( value : & ' lock Package ) -> Self {
1369
+ Self {
1370
+ version : value. version ( ) ,
1371
+ sha : value. git_sha ( ) . map ( GitOid :: as_tiny_str) ,
1372
+ }
1373
+ }
1374
+ }
1375
+
1376
+ impl std:: fmt:: Display for LockEventVersion < ' _ > {
1377
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
1378
+ match ( self . version , self . sha ) {
1379
+ ( Some ( version) , Some ( sha) ) => write ! ( f, "v{version} ({sha})" ) ,
1380
+ ( Some ( version) , None ) => write ! ( f, "v{version}" ) ,
1381
+ ( None , Some ( sha) ) => write ! ( f, "(dynamic) ({sha})" ) ,
1382
+ ( None , None ) => write ! ( f, "(dynamic)" ) ,
1383
+ }
1384
+ }
1385
+ }
1386
+
1358
1387
/// A modification to a lockfile.
1359
1388
#[ derive( Debug , Clone ) ]
1360
- pub ( crate ) enum LockEvent < ' lock > {
1389
+ enum LockEvent < ' lock > {
1361
1390
Update (
1362
1391
DryRun ,
1363
1392
PackageName ,
1364
- BTreeSet < Option < & ' lock Version > > ,
1365
- BTreeSet < Option < & ' lock Version > > ,
1393
+ BTreeSet < LockEventVersion < ' lock > > ,
1394
+ BTreeSet < LockEventVersion < ' lock > > ,
1366
1395
) ,
1367
- Add ( DryRun , PackageName , BTreeSet < Option < & ' lock Version > > ) ,
1368
- Remove ( DryRun , PackageName , BTreeSet < Option < & ' lock Version > > ) ,
1396
+ Add ( DryRun , PackageName , BTreeSet < LockEventVersion < ' lock > > ) ,
1397
+ Remove ( DryRun , PackageName , BTreeSet < LockEventVersion < ' lock > > ) ,
1369
1398
}
1370
1399
1371
1400
impl < ' lock > LockEvent < ' lock > {
1372
1401
/// Detect the change events between an (optional) existing and updated lockfile.
1373
- pub ( crate ) fn detect_changes (
1402
+ fn detect_changes (
1374
1403
existing_lock : Option < & ' lock Lock > ,
1375
1404
new_lock : & ' lock Lock ,
1376
1405
dry_run : DryRun ,
1377
1406
) -> impl Iterator < Item = Self > {
1378
1407
// Identify the package-versions in the existing lockfile.
1379
- let mut existing_packages: FxHashMap < & PackageName , BTreeSet < Option < & Version > > > =
1408
+ let mut existing_packages: FxHashMap < & PackageName , BTreeSet < LockEventVersion > > =
1380
1409
if let Some ( existing_lock) = existing_lock {
1381
1410
existing_lock. packages ( ) . iter ( ) . fold (
1382
1411
FxHashMap :: with_capacity_and_hasher (
@@ -1386,7 +1415,7 @@ impl<'lock> LockEvent<'lock> {
1386
1415
|mut acc, package| {
1387
1416
acc. entry ( package. name ( ) )
1388
1417
. or_default ( )
1389
- . insert ( package . version ( ) ) ;
1418
+ . insert ( LockEventVersion :: from ( package ) ) ;
1390
1419
acc
1391
1420
} ,
1392
1421
)
@@ -1395,13 +1424,13 @@ impl<'lock> LockEvent<'lock> {
1395
1424
} ;
1396
1425
1397
1426
// Identify the package-versions in the updated lockfile.
1398
- let mut new_packages: FxHashMap < & PackageName , BTreeSet < Option < & Version > > > =
1427
+ let mut new_packages: FxHashMap < & PackageName , BTreeSet < LockEventVersion > > =
1399
1428
new_lock. packages ( ) . iter ( ) . fold (
1400
1429
FxHashMap :: with_capacity_and_hasher ( new_lock. packages ( ) . len ( ) , FxBuildHasher ) ,
1401
1430
|mut acc, package| {
1402
1431
acc. entry ( package. name ( ) )
1403
1432
. or_default ( )
1404
- . insert ( package . version ( ) ) ;
1433
+ . insert ( LockEventVersion :: from ( package ) ) ;
1405
1434
acc
1406
1435
} ,
1407
1436
) ;
@@ -1435,23 +1464,16 @@ impl<'lock> LockEvent<'lock> {
1435
1464
1436
1465
impl std:: fmt:: Display for LockEvent < ' _ > {
1437
1466
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
1438
- /// Format a version for inclusion in the upgrade report.
1439
- fn format_version ( version : Option < & Version > ) -> String {
1440
- version
1441
- . map ( |version| format ! ( "v{version}" ) )
1442
- . unwrap_or_else ( || "(dynamic)" . to_string ( ) )
1443
- }
1444
-
1445
1467
match self {
1446
1468
Self :: Update ( dry_run, name, existing_versions, new_versions) => {
1447
1469
let existing_versions = existing_versions
1448
1470
. iter ( )
1449
- . map ( |version| format_version ( * version ) )
1471
+ . map ( std :: string :: ToString :: to_string )
1450
1472
. collect :: < Vec < _ > > ( )
1451
1473
. join ( ", " ) ;
1452
1474
let new_versions = new_versions
1453
1475
. iter ( )
1454
- . map ( |version| format_version ( * version ) )
1476
+ . map ( std :: string :: ToString :: to_string )
1455
1477
. collect :: < Vec < _ > > ( )
1456
1478
. join ( ", " ) ;
1457
1479
@@ -1470,7 +1492,7 @@ impl std::fmt::Display for LockEvent<'_> {
1470
1492
Self :: Add ( dry_run, name, new_versions) => {
1471
1493
let new_versions = new_versions
1472
1494
. iter ( )
1473
- . map ( |version| format_version ( * version ) )
1495
+ . map ( std :: string :: ToString :: to_string )
1474
1496
. collect :: < Vec < _ > > ( )
1475
1497
. join ( ", " ) ;
1476
1498
@@ -1485,7 +1507,7 @@ impl std::fmt::Display for LockEvent<'_> {
1485
1507
Self :: Remove ( dry_run, name, existing_versions) => {
1486
1508
let existing_versions = existing_versions
1487
1509
. iter ( )
1488
- . map ( |version| format_version ( * version ) )
1510
+ . map ( std :: string :: ToString :: to_string )
1489
1511
. collect :: < Vec < _ > > ( )
1490
1512
. join ( ", " ) ;
1491
1513
0 commit comments