From 40dbc86f2347bcd66476ad85f4ec5a56357fb860 Mon Sep 17 00:00:00 2001 From: Jay Lindquist Date: Mon, 3 Jun 2024 14:12:10 -0500 Subject: [PATCH] fix(yarn): search parent directories for yarn configuration (#29415) --- lib/modules/manager/npm/extract/index.spec.ts | 37 +++++++++++++++++++ lib/modules/manager/npm/extract/index.ts | 28 +++++++++++--- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/lib/modules/manager/npm/extract/index.spec.ts b/lib/modules/manager/npm/extract/index.spec.ts index 07bf5524a7cae6..032faf0a18ac95 100644 --- a/lib/modules/manager/npm/extract/index.spec.ts +++ b/lib/modules/manager/npm/extract/index.spec.ts @@ -260,6 +260,15 @@ describe('modules/manager/npm/extract/index', () => { }); it('reads registryUrls from .yarnrc.yml', async () => { + fs.findLocalSiblingOrParent.mockImplementation( + (packageFile, otherFile): Promise => { + if (packageFile === 'package.json' && otherFile === '.yarnrc.yml') { + return Promise.resolve('.yarnrc.yml'); + } + return Promise.resolve(null); + }, + ); + fs.readLocalFile.mockImplementation((fileName): Promise => { if (fileName === '.yarnrc.yml') { return Promise.resolve( @@ -279,12 +288,22 @@ describe('modules/manager/npm/extract/index', () => { }); it('reads registryUrls from .yarnrc', async () => { + fs.findLocalSiblingOrParent.mockImplementation( + (packageFile, otherFile): Promise => { + if (packageFile === 'package.json' && otherFile === '.yarnrc') { + return Promise.resolve('.yarnrc'); + } + return Promise.resolve(null); + }, + ); + fs.readLocalFile.mockImplementation((fileName): Promise => { if (fileName === '.yarnrc') { return Promise.resolve('registry "https://registry.example.com"'); } return Promise.resolve(null); }); + const res = await npmExtract.extractPackageFile( input02Content, 'package.json', @@ -296,6 +315,15 @@ describe('modules/manager/npm/extract/index', () => { }); it('resolves registry URLs using the package name if set', async () => { + fs.findLocalSiblingOrParent.mockImplementation( + (packageFile, otherFile): Promise => { + if (packageFile === 'package.json' && otherFile === '.yarnrc.yml') { + return Promise.resolve('.yarnrc.yml'); + } + return Promise.resolve(null); + }, + ); + fs.readLocalFile.mockImplementation((fileName): Promise => { if (fileName === '.yarnrc.yml') { return Promise.resolve(codeBlock` @@ -773,6 +801,15 @@ describe('modules/manager/npm/extract/index', () => { }); it('sets skipInstalls false if Yarn zero-install is used', async () => { + fs.findLocalSiblingOrParent.mockImplementation( + (packageFile, otherFile): Promise => { + if (packageFile === 'package.json' && otherFile === '.yarnrc.yml') { + return Promise.resolve('.yarnrc.yml'); + } + return Promise.resolve(null); + }, + ); + fs.readLocalFile.mockImplementation((fileName): Promise => { if (fileName === 'yarn.lock') { return Promise.resolve('# yarn.lock'); diff --git a/lib/modules/manager/npm/extract/index.ts b/lib/modules/manager/npm/extract/index.ts index a6606e1fb7f7e3..f9ed88faa9d6e5 100644 --- a/lib/modules/manager/npm/extract/index.ts +++ b/lib/modules/manager/npm/extract/index.ts @@ -1,7 +1,11 @@ import is from '@sindresorhus/is'; import { GlobalConfig } from '../../../../config/global'; import { logger } from '../../../../logger'; -import { getSiblingFileName, readLocalFile } from '../../../../util/fs'; +import { + findLocalSiblingOrParent, + getSiblingFileName, + readLocalFile, +} from '../../../../util/fs'; import { newlineRegex, regEx } from '../../../../util/regex'; import { NpmDatasource } from '../../../datasource/npm'; @@ -122,17 +126,29 @@ export async function extractPackageFile( npmrc = config.npmrc; } - const yarnrcYmlFileName = getSiblingFileName(packageFile, '.yarnrc.yml'); - const yarnZeroInstall = await isZeroInstall(yarnrcYmlFileName); + const yarnrcYmlFileName = await findLocalSiblingOrParent( + packageFile, + '.yarnrc.yml', + ); + const yarnZeroInstall = yarnrcYmlFileName + ? await isZeroInstall(yarnrcYmlFileName) + : false; let yarnConfig: YarnConfig | null = null; - const repoYarnrcYml = await readLocalFile(yarnrcYmlFileName, 'utf8'); + const repoYarnrcYml = yarnrcYmlFileName + ? await readLocalFile(yarnrcYmlFileName, 'utf8') + : null; if (is.string(repoYarnrcYml) && repoYarnrcYml.trim().length > 0) { yarnConfig = loadConfigFromYarnrcYml(repoYarnrcYml); } - const legacyYarnrcFileName = getSiblingFileName(packageFile, '.yarnrc'); - const repoLegacyYarnrc = await readLocalFile(legacyYarnrcFileName, 'utf8'); + const legacyYarnrcFileName = await findLocalSiblingOrParent( + packageFile, + '.yarnrc', + ); + const repoLegacyYarnrc = legacyYarnrcFileName + ? await readLocalFile(legacyYarnrcFileName, 'utf8') + : null; if (is.string(repoLegacyYarnrc) && repoLegacyYarnrc.trim().length > 0) { yarnConfig = loadConfigFromLegacyYarnrc(repoLegacyYarnrc); }