diff --git a/src/spec-configuration/containerFeaturesConfiguration.ts b/src/spec-configuration/containerFeaturesConfiguration.ts index 1c9682473..8263b7446 100644 --- a/src/spec-configuration/containerFeaturesConfiguration.ts +++ b/src/spec-configuration/containerFeaturesConfiguration.ts @@ -521,13 +521,19 @@ export async function getFeatureIdType(output: Log, env: NodeJS.ProcessEnv, user } } -export function getBackwardCompatibleFeatureId(id: string) { +export function getBackwardCompatibleFeatureId(output: Log, id: string) { const migratedfeatures = ['aws-cli', 'azure-cli', 'desktop-lite', 'docker-in-docker', 'docker-from-docker', 'dotnet', 'git', 'git-lfs', 'github-cli', 'java', 'kubectl-helm-minikube', 'node', 'powershell', 'python', 'ruby', 'rust', 'sshd', 'terraform']; const renamedFeatures = new Map(); renamedFeatures.set('golang', 'go'); renamedFeatures.set('common', 'common-utils'); - // TODO: Add warning log messages only when auto-mapping is ready to be put in Remote-Containers STABLE version. - // const deprecatedFeatures = ['fish', 'gradle', 'homebrew', 'jupyterlab', 'maven']; + + const deprecatedFeaturesIntoOptions = new Map(); + deprecatedFeaturesIntoOptions.set('gradle', 'java'); + deprecatedFeaturesIntoOptions.set('maven', 'java'); + deprecatedFeaturesIntoOptions.set('jupyterlab', 'python'); + + // TODO: add warning logs once we have context on the new location for these Features. + // const deprecatedFeatures = ['fish', 'homebrew']; const newFeaturePath = 'ghcr.io/devcontainers/features'; // Note: Pin the versionBackwardComp to '1' to avoid breaking changes. @@ -535,17 +541,19 @@ export function getBackwardCompatibleFeatureId(id: string) { // Mapping feature references (old shorthand syntax) from "microsoft/vscode-dev-containers" to "ghcr.io/devcontainers/features" if (migratedfeatures.includes(id)) { + output.write(`(!) WARNING: Using the deprecated '${id}' Feature. See https://github.com/devcontainers/features/tree/main/src/${id}#example-usage for the updated Feature.`, LogLevel.Warning); return `${newFeaturePath}/${id}:${versionBackwardComp}`; } // Mapping feature references (renamed old shorthand syntax) from "microsoft/vscode-dev-containers" to "ghcr.io/devcontainers/features" if (renamedFeatures.get(id) !== undefined) { + output.write(`(!) WARNING: Using the deprecated '${id}' Feature. See https://github.com/devcontainers/features/tree/main/src/${renamedFeatures.get(id)}#example-usage for the updated Feature.`, LogLevel.Warning); return `${newFeaturePath}/${renamedFeatures.get(id)}:${versionBackwardComp}`; } - // if (deprecatedFeatures.includes(id)) { - // output.write(`(!) WARNING: Falling back to deprecated '${id}' feature.`, LogLevel.Warning); - // } + if (deprecatedFeaturesIntoOptions.get(id) !== undefined) { + output.write(`(!) WARNING: Falling back to the deprecated '${id}' Feature. It is now part of the '${deprecatedFeaturesIntoOptions.get(id)}' Feature. See https://github.com/devcontainers/features/tree/main/src/${deprecatedFeaturesIntoOptions.get(id)}#options for the updated Feature.`, LogLevel.Warning); + } // Deprecated and all other features references (eg. fish, ghcr.io/devcontainers/features/go, ghcr.io/owner/repo/id etc) return id; @@ -560,7 +568,7 @@ export async function processFeatureIdentifier(output: Log, configPath: string, const originalUserFeatureId = userFeature.id; // Adding backward compatibility if (!skipFeatureAutoMapping) { - userFeature.id = getBackwardCompatibleFeatureId(userFeature.id); + userFeature.id = getBackwardCompatibleFeatureId(output, userFeature.id); } const { type, manifest } = await getFeatureIdType(output, env, userFeature.id); diff --git a/src/test/container-features/featureHelpers.test.ts b/src/test/container-features/featureHelpers.test.ts index d3c510cd6..3788bc1cb 100644 --- a/src/test/container-features/featureHelpers.test.ts +++ b/src/test/container-features/featureHelpers.test.ts @@ -384,13 +384,13 @@ describe('validate function getBackwardCompatibleFeatureId', () => { it('should map the migrated (old shorthand syntax) features to ghcr.io/devcontainers/features/*', () => { let id = 'node'; let expectedId = 'ghcr.io/devcontainers/features/node:1'; - let mappedId = getBackwardCompatibleFeatureId(id); + let mappedId = getBackwardCompatibleFeatureId(output, id); assert.strictEqual(mappedId, expectedId); id = 'python'; expectedId = 'ghcr.io/devcontainers/features/python:1'; - mappedId = getBackwardCompatibleFeatureId(id); + mappedId = getBackwardCompatibleFeatureId(output, id); assert.strictEqual(mappedId, expectedId); }); @@ -398,13 +398,13 @@ describe('validate function getBackwardCompatibleFeatureId', () => { it('should map the renamed (old shorthand syntax) features to ghcr.io/devcontainers/features/*', () => { let id = 'golang'; let expectedId = 'ghcr.io/devcontainers/features/go:1'; - let mappedId = getBackwardCompatibleFeatureId(id); + let mappedId = getBackwardCompatibleFeatureId(output, id); assert.strictEqual(mappedId, expectedId); id = 'common'; expectedId = 'ghcr.io/devcontainers/features/common-utils:1'; - mappedId = getBackwardCompatibleFeatureId(id); + mappedId = getBackwardCompatibleFeatureId(output, id); assert.strictEqual(mappedId, expectedId); }); @@ -412,13 +412,13 @@ describe('validate function getBackwardCompatibleFeatureId', () => { it('should keep the deprecated (old shorthand syntax) features id intact', () => { let id = 'fish'; let expectedId = 'fish'; - let mappedId = getBackwardCompatibleFeatureId(id); + let mappedId = getBackwardCompatibleFeatureId(output, id); assert.strictEqual(mappedId, expectedId); id = 'maven'; expectedId = 'maven'; - mappedId = getBackwardCompatibleFeatureId(id); + mappedId = getBackwardCompatibleFeatureId(output, id); assert.strictEqual(mappedId, expectedId); }); @@ -426,19 +426,19 @@ describe('validate function getBackwardCompatibleFeatureId', () => { it('should keep all other features id intact', () => { let id = 'ghcr.io/devcontainers/features/node:1'; let expectedId = id; - let mappedId = getBackwardCompatibleFeatureId(id); + let mappedId = getBackwardCompatibleFeatureId(output, id); assert.strictEqual(mappedId, expectedId); id = 'ghcr.io/user/repo/go:1'; expectedId = id; - mappedId = getBackwardCompatibleFeatureId(id); + mappedId = getBackwardCompatibleFeatureId(output, id); assert.strictEqual(mappedId, expectedId); id = 'ghcr.io/user/repo/go'; expectedId = id; - mappedId = getBackwardCompatibleFeatureId(id); + mappedId = getBackwardCompatibleFeatureId(output, id); assert.strictEqual(mappedId, expectedId); });