From f7c585ad633230d1097510e21a62ab43f385d38d Mon Sep 17 00:00:00 2001 From: parksb Date: Tue, 7 Oct 2025 23:33:57 +0900 Subject: [PATCH 1/3] Write unit tests for replaceEnvVariables --- packages/yarnpkg-core/tests/miscUtils.test.ts | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/packages/yarnpkg-core/tests/miscUtils.test.ts b/packages/yarnpkg-core/tests/miscUtils.test.ts index 9cdda3bc60d2..bcd7634d51a8 100644 --- a/packages/yarnpkg-core/tests/miscUtils.test.ts +++ b/packages/yarnpkg-core/tests/miscUtils.test.ts @@ -3,6 +3,31 @@ import CJSON from 'comment-json'; import * as miscUtils from '../sources/miscUtils'; describe(`miscUtils`, () => { + describe(`replaceEnvVariables`, () => { + it(`should replace environment variables with their values`, () => { + expect( + miscUtils.replaceEnvVariables( + `VAR_A: \${VAR_A}, VAR_B: \${VAR_B}`, + { + env: { + VAR_A: `ValueA`, + VAR_B: `ValueB`, + }, + }, + ), + ).toBe(`VAR_A: ValueA, VAR_B: ValueB`); + }); + + it(`should use fallback values when environment variables are not set`, () => { + expect( + miscUtils.replaceEnvVariables( + `VAR_A: \${VAR_A:-ValueA}, VAR_B: \${VAR_B:-ValueB}`, + {env: {}}, + ), + ).toBe(`VAR_A: ValueA, VAR_B: ValueB`); + }); + }); + describe(`mapAndFind`, () => { it(`should work with a simple example`, () => { expect( @@ -135,7 +160,9 @@ describe(`miscUtils`, () => { const b = {n: [4, 5, 6]}; const c = miscUtils.mergeIntoTarget(a, b); - expect(CJSON.stringify(c, null, 2)).toStrictEqual(CJSON.stringify(CJSON.parse(`{ + expect(CJSON.stringify(c, null, 2)).toStrictEqual( + CJSON.stringify( + CJSON.parse(`{ // n "n": // array @@ -150,7 +177,11 @@ describe(`miscUtils`, () => { 5, 6 ] - }`), null, 2)); + }`), + null, + 2, + ), + ); }); }); }); From 49fd12588c3727bfcd40648500a0f5ebcbec1ee5 Mon Sep 17 00:00:00 2001 From: parksb Date: Tue, 7 Oct 2025 23:37:08 +0900 Subject: [PATCH 2/3] Support escaping template variables --- packages/yarnpkg-core/sources/miscUtils.ts | 8 +++++--- packages/yarnpkg-core/tests/miscUtils.test.ts | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/yarnpkg-core/sources/miscUtils.ts b/packages/yarnpkg-core/sources/miscUtils.ts index e9735a24d3a5..e0450d8b5ddd 100644 --- a/packages/yarnpkg-core/sources/miscUtils.ts +++ b/packages/yarnpkg-core/sources/miscUtils.ts @@ -469,11 +469,13 @@ export function buildIgnorePattern(ignorePatterns: Array) { } export function replaceEnvVariables(value: string, {env}: {env: {[key: string]: string | undefined}}) { - const regex = /\${(?[\d\w_]+)(?:)?(?:-(?[^}]*))?}/g; + const regex = /\\?\${(?[\d\w_]+)(?:)?(?:-(?[^}]*))?}/g; - return value.replace(regex, (...args) => { - const {variableName, colon, fallback} = args[args.length - 1]; + return value.replace(regex, (match, ...args) => { + if (match.startsWith(`\\`)) + return match.slice(1); + const {variableName, colon, fallback} = args[args.length - 1]; const variableExist = Object.hasOwn(env, variableName); const variableValue = env[variableName]; diff --git a/packages/yarnpkg-core/tests/miscUtils.test.ts b/packages/yarnpkg-core/tests/miscUtils.test.ts index bcd7634d51a8..713dbb7dd3a5 100644 --- a/packages/yarnpkg-core/tests/miscUtils.test.ts +++ b/packages/yarnpkg-core/tests/miscUtils.test.ts @@ -26,6 +26,20 @@ describe(`miscUtils`, () => { ), ).toBe(`VAR_A: ValueA, VAR_B: ValueB`); }); + + it(`should not replace escaped environment variables`, () => { + expect( + miscUtils.replaceEnvVariables( + `VAR_A: \\\${VAR_A}, VAR_B: \\\${VAR_B}`, + { + env: { + VAR_A: `ValueA`, + VAR_B: `ValueB`, + }, + }, + ), + ).toBe(`VAR_A: \${VAR_A}, VAR_B: \${VAR_B}`); + }); }); describe(`mapAndFind`, () => { From 275ad520a33c7d0f56056ad7dac6b27a3dbdd1a5 Mon Sep 17 00:00:00 2001 From: parksb Date: Tue, 7 Oct 2025 23:40:09 +0900 Subject: [PATCH 3/3] Check version --- .yarn/versions/3e62b777.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .yarn/versions/3e62b777.yml diff --git a/.yarn/versions/3e62b777.yml b/.yarn/versions/3e62b777.yml new file mode 100644 index 000000000000..6c24923445d8 --- /dev/null +++ b/.yarn/versions/3e62b777.yml @@ -0,0 +1,36 @@ +releases: + "@yarnpkg/core": patch + +declined: + - "@yarnpkg/plugin-catalog" + - "@yarnpkg/plugin-compat" + - "@yarnpkg/plugin-constraints" + - "@yarnpkg/plugin-dlx" + - "@yarnpkg/plugin-essentials" + - "@yarnpkg/plugin-exec" + - "@yarnpkg/plugin-file" + - "@yarnpkg/plugin-git" + - "@yarnpkg/plugin-github" + - "@yarnpkg/plugin-http" + - "@yarnpkg/plugin-init" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-jsr" + - "@yarnpkg/plugin-link" + - "@yarnpkg/plugin-nm" + - "@yarnpkg/plugin-npm" + - "@yarnpkg/plugin-npm-cli" + - "@yarnpkg/plugin-pack" + - "@yarnpkg/plugin-patch" + - "@yarnpkg/plugin-pnp" + - "@yarnpkg/plugin-pnpm" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-typescript" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - "@yarnpkg/builder" + - "@yarnpkg/cli" + - "@yarnpkg/doctor" + - "@yarnpkg/extensions" + - "@yarnpkg/nm" + - "@yarnpkg/pnpify" + - "@yarnpkg/sdks"