@@ -1035,13 +1035,6 @@ internal final class PubGrubPackageContainer {
1035
1035
/// Reference to the pins map.
1036
1036
private let pinsMap : PinsStore . PinsMap
1037
1037
1038
- /// The map of dependencies to version set that indicates the versions that have had their
1039
- /// incompatibilities emitted.
1040
- private var emittedIncompatibilities = ThreadSafeKeyValueStore < DependencyResolutionNode , VersionSetSpecifier > ( )
1041
-
1042
- /// Whether we've emitted the incompatibilities for the pinned versions.
1043
- private var emittedPinnedVersionIncompatibilities = ThreadSafeKeyValueStore < DependencyResolutionNode , Bool > ( )
1044
-
1045
1038
init ( underlying: PackageContainer , pinsMap: PinsStore . PinsMap ) {
1046
1039
self . underlying = underlying
1047
1040
self . pinsMap = pinsMap
@@ -1189,55 +1182,17 @@ internal final class PubGrubPackageContainer {
1189
1182
continue
1190
1183
}
1191
1184
1192
- // Skip if we already emitted incompatibilities for this dependency such that the selected
1193
- // falls within the previously computed bounds.
1194
- if emittedIncompatibilities [ node] ? . contains ( version) != true {
1195
- for node in dep. nodes ( ) {
1196
- constraints. append (
1197
- PackageContainerConstraint (
1198
- package : node. package ,
1199
- requirement: dep. requirement,
1200
- products: node. productFilter
1201
- )
1185
+ for node in dep. nodes ( ) {
1186
+ constraints. append (
1187
+ PackageContainerConstraint (
1188
+ package : node. package ,
1189
+ requirement: dep. requirement,
1190
+ products: node. productFilter
1202
1191
)
1203
- }
1204
- }
1205
- }
1206
-
1207
- // Emit the dependencies at the pinned version if we haven't emitted anything else yet.
1208
- if version == pinnedVersion, emittedIncompatibilities. isEmpty {
1209
- // We don't need to emit anything if we already emitted the incompatibilities at the
1210
- // pinned version.
1211
- if self . emittedPinnedVersionIncompatibilities [ node] ?? false {
1212
- return [ ]
1213
- }
1214
-
1215
- self . emittedPinnedVersionIncompatibilities [ node] = true
1216
-
1217
- // Since the pinned version is most likely to succeed, we don't compute bounds for its
1218
- // incompatibilities.
1219
- return try constraints. flatMap { constraint -> [ Incompatibility ] in
1220
- // We only have version-based requirements at this point.
1221
- guard case . versionSet( let constraintRequirement) = constraint. requirement else {
1222
- throw InternalError ( " Unexpected unversioned requirement: \( constraint) " )
1223
- }
1224
- return try constraint. nodes ( ) . map { dependencyNode in
1225
- var terms : OrderedSet < Term > = [ ]
1226
- // the package version requirement
1227
- terms. append ( Term ( node, . exact( version) ) )
1228
- // the dependency's version requirement
1229
- terms. append ( Term ( not: dependencyNode, constraintRequirement) )
1230
- return try Incompatibility ( terms, root: root, cause: . dependency( node: node) )
1231
- }
1192
+ )
1232
1193
}
1233
1194
}
1234
1195
1235
- let ( lowerBounds, upperBounds) = try self . computeBounds (
1236
- for: node,
1237
- constraints: constraints,
1238
- startingWith: version
1239
- )
1240
-
1241
1196
return try constraints. flatMap { constraint -> [ Incompatibility ] in
1242
1197
// We only have version-based requirements at this point.
1243
1198
guard case . versionSet( let constraintRequirement) = constraint. requirement else {
@@ -1249,13 +1204,6 @@ internal final class PubGrubPackageContainer {
1249
1204
return nil
1250
1205
}
1251
1206
1252
- // Make a record for this dependency so we don't have to recompute the bounds when the selected version falls within the bounds.
1253
- if let lowerBound = lowerBounds [ constraintNode] , let upperBound = upperBounds [ constraintNode] {
1254
- assert ( lowerBound < upperBound)
1255
- let requirement : VersionSetSpecifier = . range( lowerBound ..< upperBound)
1256
- self . emittedIncompatibilities [ constraintNode] = requirement. union ( emittedIncompatibilities [ constraintNode] ?? . empty)
1257
- }
1258
-
1259
1207
var terms : OrderedSet < Term > = [ ]
1260
1208
// the package version requirement
1261
1209
terms. append ( Term ( node, . exact( version) ) )
@@ -1266,110 +1214,6 @@ internal final class PubGrubPackageContainer {
1266
1214
}
1267
1215
}
1268
1216
}
1269
-
1270
- /// Method for computing bounds of the given dependencies.
1271
- ///
1272
- /// This will return a dictionary which contains mapping of a package dependency to its bound.
1273
- /// If a dependency is absent in the dictionary, it is present in all versions of the package
1274
- /// above or below the given version. As with regular version ranges, the lower bound is
1275
- /// inclusive and the upper bound is exclusive.
1276
- private func computeBounds(
1277
- for node: DependencyResolutionNode ,
1278
- constraints: [ PackageContainerConstraint ] ,
1279
- startingWith firstVersion: Version
1280
- ) throws -> ( lowerBounds: [ DependencyResolutionNode : Version ] , upperBounds: [ DependencyResolutionNode : Version ] ) {
1281
- let preloadCount = 3
1282
-
1283
- // nothing to do
1284
- if constraints. isEmpty {
1285
- return ( [ : ] , [ : ] )
1286
- }
1287
-
1288
- func preload( _ versions: [ Version ] ) {
1289
- let sync = DispatchGroup ( )
1290
- for version in versions {
1291
- DispatchQueue . sharedConcurrent. async ( group: sync) {
1292
- if self . underlying. isToolsVersionCompatible ( at: version) {
1293
- _ = try ? self . underlying. getDependencies ( at: version, productFilter: node. productFilter)
1294
- }
1295
- }
1296
- }
1297
- sync. wait ( )
1298
- }
1299
-
1300
- func compute( _ versions: [ Version ] , upperBound: Bool ) -> [ DependencyResolutionNode : Version ] {
1301
- var result : [ DependencyResolutionNode : Version ] = [ : ]
1302
- var previousVersion = firstVersion
1303
-
1304
- for (index, version) in versions. enumerated ( ) {
1305
- // optimization to preload few version in parallel.
1306
- // we cant preload all versions ahead of time since it will be more
1307
- // costly given the early termination condition
1308
- if index. isMultiple ( of: preloadCount) {
1309
- preload ( Array ( versions [ index ..< min ( index + preloadCount, versions. count) ] ) )
1310
- }
1311
-
1312
- // Record this version as the bound if we're finding upper bounds since
1313
- // upper bound is exclusive and record the previous version if we're
1314
- // finding the lower bound since that is inclusive.
1315
- let bound = upperBound ? version : previousVersion
1316
-
1317
- let isToolsVersionCompatible = self . underlying. isToolsVersionCompatible ( at: version)
1318
- for constraint in constraints {
1319
- for constraintNode in constraint. nodes ( ) where !result. keys. contains ( constraintNode) {
1320
- // If we hit a version which doesn't have a compatible tools version then that's the boundary.
1321
- // Record the bound if the tools version isn't compatible at the current version.
1322
- if !isToolsVersionCompatible {
1323
- result [ constraintNode] = bound
1324
- } else {
1325
- // Get the dependencies at this version.
1326
- if let currentDependencies = try ? self . underlying. getDependencies ( at: version, productFilter: constraintNode. productFilter) {
1327
- // Record this version as the bound for our list of dependencies, if appropriate.
1328
- if currentDependencies. first ( where: { $0. package == constraint. package } ) != constraint {
1329
- result [ constraintNode] = bound
1330
- }
1331
- }
1332
- }
1333
- }
1334
- }
1335
-
1336
- // We're done if we found bounds for all of our dependencies.
1337
- if result. count == constraints. count {
1338
- break
1339
- }
1340
-
1341
- previousVersion = version
1342
- }
1343
-
1344
- return result
1345
- }
1346
-
1347
- let versions : [ Version ] = try self . underlying. versionsAscending ( )
1348
-
1349
- guard let idx = versions. firstIndex ( of: firstVersion) else {
1350
- throw InternalError ( " from version \( firstVersion) not found in \( node. package . identity) " )
1351
- }
1352
-
1353
- let sync = DispatchGroup ( )
1354
-
1355
- var upperBounds = [ DependencyResolutionNode: Version] ( )
1356
- DispatchQueue . sharedConcurrent. async ( group: sync) {
1357
- upperBounds = compute ( Array ( versions. dropFirst ( idx + 1 ) ) , upperBound: true )
1358
- }
1359
-
1360
- var lowerBounds = [ DependencyResolutionNode: Version] ( )
1361
- DispatchQueue . sharedConcurrent. async ( group: sync) {
1362
- lowerBounds = compute ( Array ( versions. dropLast ( versions. count - idx) . reversed ( ) ) , upperBound: false )
1363
- }
1364
-
1365
- // timeout is a function of # of versions since we need to make several git operations per tag/version
1366
- let timeout = DispatchTimeInterval . seconds ( 60 + versions. count)
1367
- guard case . success = sync. wait ( timeout: . now( ) + timeout) else {
1368
- throw StringError ( " timeout computing ' \( node. package . identity) ' bounds " )
1369
- }
1370
-
1371
- return ( lowerBounds, upperBounds)
1372
- }
1373
1217
}
1374
1218
1375
1219
/// An utility class around PackageContainerProvider that allows "prefetching" the containers
0 commit comments