(
params: CommonParams,
processFeature: (userFeature: DevContainerFeature) => Promise<FeatureSet | undefined>,
userFeatures: DevContainerFeature[],
config: { overrideFeatureInstallOrder?: string[] },
lockfile: Lockfile | undefined)
| 533 | |
| 534 | // Creates the directed acyclic graph (DAG) of Features and their dependencies. |
| 535 | export async function buildDependencyGraph( |
| 536 | params: CommonParams, |
| 537 | processFeature: (userFeature: DevContainerFeature) => Promise<FeatureSet | undefined>, |
| 538 | userFeatures: DevContainerFeature[], |
| 539 | config: { overrideFeatureInstallOrder?: string[] }, |
| 540 | lockfile: Lockfile | undefined): Promise<DependencyGraph | undefined> { |
| 541 | |
| 542 | const { output } = params; |
| 543 | |
| 544 | const rootNodes = |
| 545 | userFeatures.map<FNode>(f => { |
| 546 | return { |
| 547 | type: 'user-provided', // This Feature was provided by the user in the 'features' object of devcontainer.json. |
| 548 | userFeatureId: f.userFeatureId, |
| 549 | options: f.options, |
| 550 | dependsOn: [], |
| 551 | installsAfter: [], |
| 552 | roundPriority: 0, |
| 553 | }; |
| 554 | }); |
| 555 | |
| 556 | output.write(`[* user-provided] ${rootNodes.map(n => n.userFeatureId).join(', ')}`, LogLevel.Trace); |
| 557 | |
| 558 | const { worklist } = await _buildDependencyGraph(params, processFeature, rootNodes, [], lockfile); |
| 559 | |
| 560 | output.write(`[* resolved worklist] ${worklist.map(n => n.userFeatureId).join(', ')}`, LogLevel.Trace); |
| 561 | |
| 562 | // Apply the 'overrideFeatureInstallOrder' to the worklist. |
| 563 | if (config?.overrideFeatureInstallOrder) { |
| 564 | await applyOverrideFeatureInstallOrder(params, processFeature, worklist, config); |
| 565 | } |
| 566 | |
| 567 | return { worklist }; |
| 568 | } |
| 569 | |
| 570 | // Returns the ordered list of FeatureSets to fetch and install, or undefined on error. |
| 571 | export async function computeDependsOnInstallationOrder( |
no test coverage detected