@@ -356,6 +356,10 @@ export class DatapackDeployment extends AsyncEventEmitter<DatapackDeploymentEven
356
356
if ( this . options . strictOrder && isExternalDependency ) {
357
357
const dependencyStatus = this . getDatapackStatus ( dependentRecord . datapackKey ) ;
358
358
if ( dependencyStatus !== undefined && dependencyStatus < DeploymentStatus . Deployed ) {
359
+ if ( this . isCircularDatapackDependency ( record . datapackKey , dependentRecord . datapackKey ) ) {
360
+ this . reportWarning ( record , `Circular datapack dependency: ${ record . datapackKey } ->${ dependentRecord . datapackKey } ->${ record . datapackKey } ` ) ;
361
+ continue ;
362
+ }
359
363
return true ;
360
364
}
361
365
}
@@ -372,14 +376,44 @@ export class DatapackDeployment extends AsyncEventEmitter<DatapackDeploymentEven
372
376
}
373
377
}
374
378
379
+ /**
380
+ * Checks if there is a circular dependency between two datapacks.
381
+ * @param datapackKeyA - The key of the first datapack.
382
+ * @param datapackKeyB - The key of the second datapack.
383
+ * @returns True if there is a circular dependency, false otherwise.
384
+ */
385
+ private isCircularDatapackDependency ( datapackKeyA : string , datapackKeyB : string , visited = new Set < string > ( ) ) : boolean {
386
+ if ( visited . has ( datapackKeyB ) ) {
387
+ // Prevent a circular dependency check from going into an infinite loop
388
+ return false ;
389
+ } else {
390
+ visited . add ( datapackKeyB ) ;
391
+ }
392
+
393
+ for ( const record of this . getRecords ( datapackKeyB ) ) {
394
+ for ( const dependency of record . getDependencies ( ) ) {
395
+ const dependentRecord = this . records . get ( dependency . VlocityMatchingRecordSourceKey ?? dependency . VlocityLookupRecordSourceKey ) ;
396
+ if ( ! dependentRecord || dependentRecord . datapackKey === datapackKeyB ) {
397
+ continue ;
398
+ }
399
+ if ( dependentRecord . datapackKey === datapackKeyA ) {
400
+ return true ;
401
+ } else if ( this . isCircularDatapackDependency ( datapackKeyA , dependentRecord . datapackKey , visited ) ) {
402
+ return true ;
403
+ }
404
+ }
405
+ }
406
+ return false ;
407
+ }
408
+
375
409
private hasCircularDependencies ( record : DatapackDeploymentRecord , graph = Array < string > ( ) ) : Array < string > | false {
376
410
if ( ! graph . length ) {
377
411
graph . push ( record . sourceKey ) ;
378
412
}
379
413
380
414
for ( const key of record . getDependencySourceKeys ( ) ) {
381
415
if ( graph . includes ( key ) ) {
382
- return graph ;
416
+ return [ ... graph , key ] ;
383
417
}
384
418
385
419
const depedency = this . records . get ( key ) ;
0 commit comments