diff --git a/src/spec-node/featuresCLI/resolveDependencies.ts b/src/spec-node/featuresCLI/resolveDependencies.ts index c0a61b0c3..93e569ff6 100644 --- a/src/spec-node/featuresCLI/resolveDependencies.ts +++ b/src/spec-node/featuresCLI/resolveDependencies.ts @@ -1,16 +1,23 @@ import * as path from 'path'; -import * as jsonc from 'jsonc-parser'; import { Argv } from 'yargs'; import { LogLevel, mapLogLevel } from '../../spec-utils/log'; import { getPackageConfig } from '../../spec-utils/product'; import { createLog } from '../devContainers'; import { UnpackArgv } from '../devContainersSpecCLI'; -import { isLocalFile, readLocalFile } from '../../spec-utils/pfs'; -import { DevContainerConfig, DevContainerFeature } from '../../spec-configuration/configuration'; +import { isLocalFile } from '../../spec-utils/pfs'; +import { DevContainerFeature } from '../../spec-configuration/configuration'; import { buildDependencyGraph, computeDependsOnInstallationOrder, generateMermaidDiagram } from '../../spec-configuration/containerFeaturesOrder'; import { OCISourceInformation, processFeatureIdentifier, userFeaturesToArray } from '../../spec-configuration/containerFeaturesConfiguration'; import { readLockfile } from '../../spec-configuration/lockfile'; import { runAsyncHandler } from '../utils'; +import { loadNativeModule } from '../../spec-common/commonUtils'; +import { getCLIHost } from '../../spec-common/cliHost'; +import { ContainerError } from '../../spec-common/errors'; +import { uriToFsPath } from '../../spec-configuration/configurationCommonUtils'; +import { workspaceFromPath } from '../../spec-utils/workspaces'; +import { readDevContainerConfigFile } from '../configContainer'; +import { URI } from 'vscode-uri'; + interface JsonOutput { installOrder?: { @@ -61,28 +68,28 @@ async function featuresResolveDependencies({ configPath = path.join(workspaceFolder, '.devcontainer', 'devcontainer.json'); } - // Load dev container config - const buffer = await readLocalFile(configPath); - if (!buffer) { - output.write(`Could not load devcontainer.json file from path ${configPath}`, LogLevel.Error); - process.exit(1); - } + const params = { + output, + env: process.env, + }; - // Parse dev container config - const config: DevContainerConfig = jsonc.parse(buffer.toString()); - if (!config || !config.features) { - output.write(`No Features object in configuration '${configPath}'`, LogLevel.Error); - process.exit(1); + const cwd = workspaceFolder || process.cwd(); + const cliHost = await getCLIHost(cwd, loadNativeModule, true); + const workspace = workspaceFromPath(cliHost.path, workspaceFolder); + const configFile: URI = URI.file(path.resolve(process.cwd(), configPath)); + const configs = await readDevContainerConfigFile(cliHost, workspace, configFile, false, output, undefined, undefined); + + if (configFile && !configs) { + throw new ContainerError({ description: `Dev container config (${uriToFsPath(configFile, cliHost.platform)}) not found.` }); } + const configWithRaw = configs!.config; + const { config } = configWithRaw; + const userFeaturesConfig = userFeaturesToArray(config); if (!userFeaturesConfig) { output.write(`Could not parse features object in configuration '${configPath}'`, LogLevel.Error); process.exit(1); } - const params = { - output, - env: process.env, - }; const { lockfile } = await readLockfile(config); const processFeature = async (_userFeature: DevContainerFeature) => {