@@ -1194,13 +1194,6 @@ func (c *KpmClient) downloadDeps(deps pkg.Dependencies, lockDeps pkg.Dependencie
1194
1194
1195
1195
depGraph := graph .New (graph .StringHash , graph .Directed ())
1196
1196
1197
- for _ , d := range newDeps .Deps {
1198
- err := depGraph .AddVertex (fmt .Sprintf ("%s@%s" , d .Name , d .Version ))
1199
- if err != nil {
1200
- return nil , nil , err
1201
- }
1202
- }
1203
-
1204
1197
// Recursively download the dependencies of the new dependencies.
1205
1198
for _ , d := range newDeps .Deps {
1206
1199
// Load kcl.mod file of the new downloaded dependencies.
@@ -1223,20 +1216,27 @@ func (c *KpmClient) downloadDeps(deps pkg.Dependencies, lockDeps pkg.Dependencie
1223
1216
}
1224
1217
1225
1218
source := fmt .Sprintf ("%s@%s" , d .Name , d .Version )
1219
+ err = depGraph .AddVertex (source )
1220
+ if err != nil {
1221
+ if err != graph .ErrVertexAlreadyExists {
1222
+ return nil , nil , err
1223
+ }
1224
+ }
1225
+
1226
1226
sourcesOfNestedDepGraph , err := FindSource (nestedDepGraph )
1227
1227
if err != nil {
1228
1228
return nil , nil , err
1229
1229
}
1230
1230
1231
- depGraph , err = graph . Union (depGraph , nestedDepGraph )
1231
+ depGraph , err = Union (depGraph , nestedDepGraph )
1232
1232
if err != nil {
1233
1233
return nil , nil , err
1234
1234
}
1235
1235
1236
1236
// make an edge between the source of all nested dep graph and main dep graph
1237
1237
for _ , sourceOfNestedDepGraph := range sourcesOfNestedDepGraph {
1238
1238
err = depGraph .AddEdge (source , sourceOfNestedDepGraph )
1239
- if err != nil {
1239
+ if err != nil && err != graph . ErrEdgeAlreadyExists {
1240
1240
return nil , nil , err
1241
1241
}
1242
1242
}
@@ -1341,3 +1341,61 @@ func FindSource[K comparable, T any](g graph.Graph[K, T]) ([]K, error) {
1341
1341
}
1342
1342
return sources , nil
1343
1343
}
1344
+
1345
+ // Union combines two given graphs into a new graph. The vertex hashes in both
1346
+ // graphs are expected to be unique. The two input graphs will remain unchanged.
1347
+ //
1348
+ // Both graphs should be either directed or undirected. All traits for the new
1349
+ // graph will be derived from g.
1350
+ //
1351
+ // If the same vertex happens to be in both g and h, then an error will not be
1352
+ // thrown as happens in original Union function and successful operation takes place.
1353
+ func Union [K comparable , T any ](g , h graph.Graph [K , T ]) (graph.Graph [K , T ], error ) {
1354
+ union , err := g .Clone ()
1355
+ if err != nil {
1356
+ return union , fmt .Errorf ("failed to clone g: %w" , err )
1357
+ }
1358
+
1359
+ adjacencyMap , err := h .AdjacencyMap ()
1360
+ if err != nil {
1361
+ return union , fmt .Errorf ("failed to get adjacency map: %w" , err )
1362
+ }
1363
+
1364
+ addedEdges := make (map [K ]map [K ]struct {})
1365
+
1366
+ for currentHash := range adjacencyMap {
1367
+ vertex , err := h .Vertex (currentHash )
1368
+ if err != nil {
1369
+ return union , fmt .Errorf ("failed to get vertex %v: %w" , currentHash , err )
1370
+ }
1371
+
1372
+ err = union .AddVertex (vertex )
1373
+ if err != nil && err != graph .ErrVertexAlreadyExists {
1374
+ return union , fmt .Errorf ("failed to add vertex %v: %w" , currentHash , err )
1375
+ }
1376
+ }
1377
+
1378
+ for _ , adjacencies := range adjacencyMap {
1379
+ for _ , edge := range adjacencies {
1380
+ if _ , sourceOK := addedEdges [edge .Source ]; sourceOK {
1381
+ if _ , targetOK := addedEdges [edge.Source ][edge.Target ]; targetOK {
1382
+ // If the edge addedEdges[source][target] exists, the edge
1383
+ // has already been created and thus can be skipped here.
1384
+ continue
1385
+ }
1386
+ }
1387
+
1388
+ err = union .AddEdge (edge .Source , edge .Target )
1389
+ if err != nil && err != graph .ErrEdgeAlreadyExists {
1390
+ return union , fmt .Errorf ("failed to add edge (%v, %v): %w" , edge .Source , edge .Target , err )
1391
+ }
1392
+
1393
+ if _ , ok := addedEdges [edge .Source ]; ! ok {
1394
+ addedEdges [edge .Source ] = make (map [K ]struct {})
1395
+ }
1396
+ addedEdges [edge.Source ][edge.Target ] = struct {}{}
1397
+ }
1398
+ }
1399
+
1400
+ return union , nil
1401
+ }
0 commit comments