From 925a1eb733a25b33f52c9fd0381a3a1fa0542bef Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Mon, 28 Oct 2024 23:33:58 +0000 Subject: [PATCH 1/4] solution to cli issue TypeError: Cannot read properties of undefined (reading 'fsPath') #895 --- src/spec-configuration/lockfile.ts | 2 +- src/spec-node/featuresCLI/resolveDependencies.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/spec-configuration/lockfile.ts b/src/spec-configuration/lockfile.ts index 9de0ba0b2..ad100a00d 100644 --- a/src/spec-configuration/lockfile.ts +++ b/src/spec-configuration/lockfile.ts @@ -67,7 +67,7 @@ export async function writeLockfile(params: ContainerFeatureInternalParams, conf return; } -export async function readLockfile(config: DevContainerConfig): Promise<{ lockfile?: Lockfile; initLockfile?: boolean }> { +export async function readLockfile(config: DevContainerConfig | string): Promise<{ lockfile?: Lockfile; initLockfile?: boolean }> { try { const content = await readLocalFile(getLockfilePath(config)); // If empty file, use as marker to initialize lockfile when build completes. diff --git a/src/spec-node/featuresCLI/resolveDependencies.ts b/src/spec-node/featuresCLI/resolveDependencies.ts index c0a61b0c3..2db8a3aae 100644 --- a/src/spec-node/featuresCLI/resolveDependencies.ts +++ b/src/spec-node/featuresCLI/resolveDependencies.ts @@ -84,7 +84,9 @@ async function featuresResolveDependencies({ env: process.env, }; - const { lockfile } = await readLockfile(config); + let configObj: DevContainerConfig | string = config.hasOwnProperty('configFilePath') && config.configFilePath ? config : configPath; + + const { lockfile } = await readLockfile(configObj); const processFeature = async (_userFeature: DevContainerFeature) => { return await processFeatureIdentifier(params, configPath, workspaceFolder, _userFeature, lockfile); }; From d909b979a66ab7f98210e7a9e5eef3478e696a1c Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Wed, 30 Oct 2024 10:24:55 +0000 Subject: [PATCH 2/4] readDevContainerConfigFile - implemented logic like in other commands - used the fn --- .../featuresCLI/resolveDependencies.ts | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/spec-node/featuresCLI/resolveDependencies.ts b/src/spec-node/featuresCLI/resolveDependencies.ts index 2db8a3aae..077ea11c7 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,32 +68,31 @@ 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 | undefined = configPath ? URI.file(path.resolve(process.cwd(), configPath)) : undefined; + const configs = configFile && 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, - }; - - let configObj: DevContainerConfig | string = config.hasOwnProperty('configFilePath') && config.configFilePath ? config : configPath; - const { lockfile } = await readLockfile(configObj); + const { lockfile } = await readLockfile(config); const processFeature = async (_userFeature: DevContainerFeature) => { return await processFeatureIdentifier(params, configPath, workspaceFolder, _userFeature, lockfile); }; From cde4336372d14c9ccaeeadb5a135df9acb259f45 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Wed, 30 Oct 2024 15:59:06 +0530 Subject: [PATCH 3/4] Update lockfile.ts --- src/spec-configuration/lockfile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spec-configuration/lockfile.ts b/src/spec-configuration/lockfile.ts index ad100a00d..9de0ba0b2 100644 --- a/src/spec-configuration/lockfile.ts +++ b/src/spec-configuration/lockfile.ts @@ -67,7 +67,7 @@ export async function writeLockfile(params: ContainerFeatureInternalParams, conf return; } -export async function readLockfile(config: DevContainerConfig | string): Promise<{ lockfile?: Lockfile; initLockfile?: boolean }> { +export async function readLockfile(config: DevContainerConfig): Promise<{ lockfile?: Lockfile; initLockfile?: boolean }> { try { const content = await readLocalFile(getLockfilePath(config)); // If empty file, use as marker to initialize lockfile when build completes. From 0203a973e65fd868cbcbc6f2cad656876bc6bf97 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Thu, 31 Oct 2024 08:19:43 +0000 Subject: [PATCH 4/4] changes as suggested in review comments --- src/spec-node/featuresCLI/resolveDependencies.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/spec-node/featuresCLI/resolveDependencies.ts b/src/spec-node/featuresCLI/resolveDependencies.ts index 077ea11c7..93e569ff6 100644 --- a/src/spec-node/featuresCLI/resolveDependencies.ts +++ b/src/spec-node/featuresCLI/resolveDependencies.ts @@ -76,13 +76,12 @@ async function featuresResolveDependencies({ const cwd = workspaceFolder || process.cwd(); const cliHost = await getCLIHost(cwd, loadNativeModule, true); const workspace = workspaceFromPath(cliHost.path, workspaceFolder); - const configFile: URI | undefined = configPath ? URI.file(path.resolve(process.cwd(), configPath)) : undefined; - const configs = configFile && await readDevContainerConfigFile(cliHost, workspace, configFile, false, output, undefined, undefined); - + 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;