diff --git a/lib/manager/common.ts b/lib/manager/common.ts index 654e79489835b6..3111fce942333f 100644 --- a/lib/manager/common.ts +++ b/lib/manager/common.ts @@ -93,7 +93,7 @@ export interface PackageFile> packageFileVersion?: string; parent?: string; skipInstalls?: boolean; - yarnrc?: string; + yarnrc?: RcFile; yarnWorkspacesPackages?: string[] | string; matchStrings?: string[]; } @@ -263,3 +263,8 @@ export interface PostUpdateConfig extends ManagerConfig, Record { branchName?: string; reuseExistingBranch?: boolean; } + +export interface RcFile { + content: string; + fileName: string; +} diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index 7f5e6f3372ac1e..a63dbe696706de 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -23,6 +23,7 @@ import { NpmPackage, NpmPackageDependency } from './common'; import { getLockedVersions } from './locked-versions'; import { detectMonorepos } from './monorepo'; import { mightBeABrowserLibrary } from './type'; +import { getYarnRc } from './yarn'; function parseDepName(depType: string, key: string): string { if (depType !== 'resolutions') { @@ -117,11 +118,8 @@ export async function extractPackageFile( npmrc = undefined; } } - const yarnrcFileName = getSiblingFileName(fileName, '.yarnrc'); - let yarnrc; - if (!is.string(config.yarnrc)) { - yarnrc = (await readLocalFile(yarnrcFileName, 'utf8')) || undefined; - } + + const yarnrc = await getYarnRc(fileName, config); let lernaDir: string; let lernaPackages: string[]; diff --git a/lib/manager/npm/extract/yarn.ts b/lib/manager/npm/extract/yarn.ts index 731f17dcd09752..bd7abe0bf5e95f 100644 --- a/lib/manager/npm/extract/yarn.ts +++ b/lib/manager/npm/extract/yarn.ts @@ -1,7 +1,12 @@ +import * as path from 'path'; +import is from '@sindresorhus/is'; import { structUtils } from '@yarnpkg/core'; import { parseSyml } from '@yarnpkg/parsers'; +import findUp from 'find-up'; +import { getEnv } from '../../../../tools/utils'; import { logger } from '../../../logger'; -import { readLocalFile } from '../../../util/fs'; +import { readFile, readLocalFile } from '../../../util/fs'; +import { ExtractConfig, RcFile } from '../../common'; export async function getYarnLock( filePath: string @@ -41,3 +46,29 @@ export async function getYarnLock( return { isYarn1: true, cacheVersion: NaN, lockedVersions: {} }; } } + +export async function getYarnRc( + packageFilePath: string, + config: ExtractConfig +): Promise { + if (is.string(config.yarnrc) || config.localDir === undefined) { + return undefined; + } + const yarnRcFileNames = [ + '.yarnrc', + '.yarnrc.yml', + getEnv('YARN_RC_FILENAME'), + ]; + const yarnRcPath = await findUp(yarnRcFileNames, { + cwd: path.dirname(path.join(config.localDir, packageFilePath)), + type: 'file', + }); + if (yarnRcPath?.startsWith(config.localDir) !== true) { + return undefined; + } + logger.debug({ yarnRcPath }, 'found Yarn config file'); + return { + content: await readFile(yarnRcPath, 'utf8'), + fileName: yarnRcPath, + }; +} diff --git a/lib/manager/npm/post-update/index.ts b/lib/manager/npm/post-update/index.ts index 0e034669be70ad..2226d0c08a584c 100644 --- a/lib/manager/npm/post-update/index.ts +++ b/lib/manager/npm/post-update/index.ts @@ -158,12 +158,15 @@ export async function writeExistingFiles( } } if (packageFile.yarnrc) { - logger.debug(`Writing .yarnrc to ${basedir}`); - const yarnrcFilename = upath.join(basedir, '.yarnrc'); + const { + fileName: yarnrcFilename, + content: yarnrcContent, + } = packageFile.yarnrc; + logger.debug(`Writing ${yarnrcFilename} to ${basedir}`); try { await outputFile( yarnrcFilename, - packageFile.yarnrc + yarnrcContent .replace('--install.pure-lockfile true', '') .replace('--install.frozen-lockfile true', '') );