@@ -205,10 +205,12 @@ private func createResolvedPackages(
205
205
return nil
206
206
}
207
207
let isAllowedToVendUnsafeProducts = unsafeAllowedPackages. contains { $0. location == package . manifest. packageLocation }
208
+ let allowedToOverride = rootManifestSet. contains ( node. manifest)
208
209
return ResolvedPackageBuilder (
209
210
package ,
210
211
productFilter: node. productFilter,
211
- isAllowedToVendUnsafeProducts: isAllowedToVendUnsafeProducts
212
+ isAllowedToVendUnsafeProducts: isAllowedToVendUnsafeProducts,
213
+ allowedToOverride: allowedToOverride
212
214
)
213
215
}
214
216
@@ -218,21 +220,15 @@ private func createResolvedPackages(
218
220
return ( $0. package . identity, $0)
219
221
}
220
222
221
- // in case packages have same manifest name this map can miss packages which will lead to missing product errors
222
- // our plan is to deprecate the use of manifest + dependency explicit name in target dependency lookup and instead lean 100% on identity
223
- // which means this map would go away too
224
- let packageMapByNameForTargetDependencyResolutionOnly = packageBuilders. reduce ( into: [ String: ResolvedPackageBuilder] ( ) , { partial, item in
225
- partial [ item. package . manifestName] = item
226
- } )
227
-
228
223
// Scan and validate the dependencies
229
224
for packageBuilder in packageBuilders {
230
225
let package = packageBuilder. package
231
226
232
227
var dependencies = [ ResolvedPackageBuilder] ( )
228
+ var dependenciesByNameForTargetDependencyResolution = [ String: ResolvedPackageBuilder] ( )
229
+
233
230
// Establish the manifest-declared package dependencies.
234
231
package . manifest. dependenciesRequired ( for: packageBuilder. productFilter) . forEach { dependency in
235
- let dependencyIdentity = dependency. identity
236
232
// FIXME: change this validation logic to use identity instead of location
237
233
let dependencyLocation : String
238
234
switch dependency {
@@ -245,57 +241,57 @@ private func createResolvedPackages(
245
241
fatalError ( " registry based dependencies not implemented yet " )
246
242
}
247
243
248
- // Use the package name to lookup the dependency. The package name will be present in packages with tools version >= 5.2.
249
- if let explicitDependencyName = dependency. explicitNameForTargetDependencyResolutionOnly, let resolvedPackage = packageMapByNameForTargetDependencyResolutionOnly [ explicitDependencyName] {
244
+ // Otherwise, look it up by its identity.
245
+ if let resolvedPackage = packageMapByIdentity [ dependency. identity] {
246
+ // check if this resolved package already listed in the dependencies
247
+ // this means that the dependencies share the same identity
248
+ // FIXME: this works but the way we find out about this is based on a side effect, need to improve it
250
249
guard !dependencies. contains ( resolvedPackage) else {
251
- // check if this resolvedPackage already listed in the dependencies
252
- // this means that the dependencies share the same name
253
- // FIXME: this works but the way we find out about this is based on a side effect, need to improve it when working on identity
254
- let error = PackageGraphError . dependencyAlreadySatisfiedByName (
250
+ let error = PackageGraphError . dependencyAlreadySatisfiedByIdentifier (
255
251
package : package . identity. description,
256
252
dependencyLocation: dependencyLocation,
257
253
otherDependencyURL: resolvedPackage. package . manifest. packageLocation,
258
- name : explicitDependencyName )
254
+ identity : dependency . identity )
259
255
return diagnostics. emit ( error, location: package . diagnosticLocation)
260
256
}
261
- return dependencies. append ( resolvedPackage)
262
- }
263
257
264
- // Otherwise, look it up by its identity.
265
- if let resolvedPackage = packageMapByIdentity [ dependencyIdentity] {
266
- // check if this resolvedPackage already listed in the dependencies
267
- // this means that the dependencies share the same identity
268
- // FIXME: this works but the way we find out about this is based on a side effect, need to improve it when working on identity
269
- guard !dependencies. contains ( resolvedPackage) else {
258
+ // check if the resolved package url is the same as the dependency one
259
+ // if not, this means that the dependencies share the same identity
260
+ // FIXME: this works but the way we find out about this is based on a side effect, need to improve it
261
+ if resolvedPackage. package . manifest. packageLocation != dependencyLocation && !resolvedPackage. allowedToOverride {
270
262
let error = PackageGraphError . dependencyAlreadySatisfiedByIdentifier (
271
263
package : package . identity. description,
272
264
dependencyLocation: dependencyLocation,
273
265
otherDependencyURL: resolvedPackage. package . manifest. packageLocation,
274
- identity: dependencyIdentity )
266
+ identity: dependency . identity )
275
267
return diagnostics. emit ( error, location: package . diagnosticLocation)
276
268
}
277
- // check that the explicit package dependency name matches the package name.
278
- if let explicitDependencyName = dependency. explicitNameForTargetDependencyResolutionOnly, resolvedPackage. package . manifestName != explicitDependencyName {
279
- // check if this resolvedPackage url is the same as the dependency one
280
- // if not, this means that the dependencies share the same identity
281
- // FIXME: this works but the way we find out about this is based on a side effect, need to improve it when working on identity
282
- if resolvedPackage. package . manifest. packageLocation != dependencyLocation {
283
- let error = PackageGraphError . dependencyAlreadySatisfiedByIdentifier (
284
- package : package . identity. description,
285
- dependencyLocation: dependencyLocation,
286
- otherDependencyURL: resolvedPackage. package . manifest. packageLocation,
287
- identity: dependencyIdentity)
288
- return diagnostics. emit ( error, location: package . diagnosticLocation)
289
- } else {
290
- let error = PackageGraphError . incorrectPackageDependencyName (
269
+
270
+ // checks if two dependencies have the same explicit name which can cause target based dependency package lookup issue
271
+ if let explicitDependencyName = dependency. explicitNameForTargetDependencyResolutionOnly {
272
+ if let previouslyResolvedPackage = dependenciesByNameForTargetDependencyResolution [ explicitDependencyName] {
273
+ let error = PackageGraphError . dependencyAlreadySatisfiedByName (
291
274
package : package . identity. description,
292
- dependencyName: explicitDependencyName,
293
275
dependencyLocation: dependencyLocation,
294
- resolvedPackageManifestName : resolvedPackage . package . manifestName ,
295
- resolvedPackageURL : resolvedPackage . package . manifest . packageLocation )
276
+ otherDependencyURL : previouslyResolvedPackage . package . manifest . packageLocation ,
277
+ name : explicitDependencyName )
296
278
return diagnostics. emit ( error, location: package . diagnosticLocation)
297
279
}
298
280
}
281
+
282
+ // checks if two dependencies have the same implicit (identity based) name which can cause target based dependency package lookup issue
283
+ if let previouslyResolvedPackage = dependenciesByNameForTargetDependencyResolution [ dependency. identity. description] {
284
+ let error = PackageGraphError . dependencyAlreadySatisfiedByName (
285
+ package : package . identity. description,
286
+ dependencyLocation: dependencyLocation,
287
+ otherDependencyURL: previouslyResolvedPackage. package . manifest. packageLocation,
288
+ name: dependency. identity. description)
289
+ return diagnostics. emit ( error, location: package . diagnosticLocation)
290
+ }
291
+
292
+ let nameForTargetDependencyResolution = dependency. explicitNameForTargetDependencyResolutionOnly ?? dependency. identity. description
293
+ dependenciesByNameForTargetDependencyResolution [ nameForTargetDependencyResolution] = resolvedPackage
294
+
299
295
dependencies. append ( resolvedPackage)
300
296
}
301
297
}
@@ -588,10 +584,13 @@ private final class ResolvedPackageBuilder: ResolvedBuilder<ResolvedPackage> {
588
584
589
585
let isAllowedToVendUnsafeProducts : Bool
590
586
591
- init ( _ package : Package , productFilter: ProductFilter , isAllowedToVendUnsafeProducts: Bool ) {
587
+ let allowedToOverride : Bool
588
+
589
+ init ( _ package : Package , productFilter: ProductFilter , isAllowedToVendUnsafeProducts: Bool , allowedToOverride: Bool ) {
592
590
self . package = package
593
591
self . productFilter = productFilter
594
592
self . isAllowedToVendUnsafeProducts = isAllowedToVendUnsafeProducts
593
+ self . allowedToOverride = allowedToOverride
595
594
}
596
595
597
596
override func constructImpl( ) throws -> ResolvedPackage {
0 commit comments