diff --git a/lib/workers/branch/lock-files.js b/lib/workers/branch/lock-files.js index 28829ee73990810d3b6ce6e101e49f7dffaa0152..bef878c5f2f6ccb859512331d779a3a35ba44ee4 100644 --- a/lib/workers/branch/lock-files.js +++ b/lib/workers/branch/lock-files.js @@ -67,6 +67,11 @@ function determineLockFileDirs(config) { } } + // If yarn workspaces are in use, then we need to generate yarn.lock from root dir + if (config.updatedPackageFiles.length && config.hasYarnWorkspaces) { + yarnLockFileDirs.push(path.dirname('package.json')); + } + return { yarnLockFileDirs, packageLockFileDirs }; } diff --git a/lib/workers/package-file/index.js b/lib/workers/package-file/index.js index 46916f359dec71776d3e02d5a510528f3deaa492..b570401bdb799a10f8df370035408b77a6e22e67 100644 --- a/lib/workers/package-file/index.js +++ b/lib/workers/package-file/index.js @@ -23,17 +23,6 @@ async function renovatePackageFile(packageFileConfig) { return upgrades; } - // Warn if workspaces found - if (config.content.workspaces) { - logger.warn('Found workspaces'); - const warn = { ...config }; - warn.depName = 'workspaces'; - warn.type = 'warning'; - warn.message = - 'workspaces configuration detected in `package.json` but this is currently unsupported. Please see https://github.com/singapore/renovate/issues/473 for details.'; - upgrades.push(warn); - } - const depTypes = [ 'dependencies', 'devDependencies', diff --git a/lib/workers/repository/apis.js b/lib/workers/repository/apis.js index a8458b3e18974f667acf46f2bd0d13efbff244b3..55bfb0916885bc9d727a034dd7c11a59cd87103a 100644 --- a/lib/workers/repository/apis.js +++ b/lib/workers/repository/apis.js @@ -206,30 +206,42 @@ async function mergeRenovateJson(config, branchName) { async function detectPackageFiles(input) { const config = { ...input }; - config.logger.trace({ config }, 'detectPackageFiles'); + const { logger } = config; + logger.trace({ config }, 'detectPackageFiles'); config.packageFiles = await config.api.findFilePaths('package.json'); - config.logger.debug( + logger.debug( { packageFiles: config.packageFiles }, `Found ${config.packageFiles.length} package file(s)` ); if (Array.isArray(config.ignorePaths)) { + logger.debug('Checking ignorePaths'); const skippedPackageFiles = []; config.packageFiles = config.packageFiles.filter(packageFile => { + logger.trace(`Checking ${packageFile}`); if ( - config.ignorePaths.some(ignorePath => packageFile.includes(ignorePath)) + config.ignorePaths.some(ignorePath => { + logger.trace(` ..against ${ignorePath}`); + return packageFile.includes(ignorePath); + }) ) { + logger.trace('Filtered out'); skippedPackageFiles.push(packageFile); return false; } + logger.trace('Included'); return true; }); if (skippedPackageFiles.length) { + logger.debug( + { skippedPackageFiles }, + `Skipped ${skippedPackageFiles.length} file(s)` + ); config.foundIgnoredPaths = true; config.warnings.push({ depName: 'packageFiles', message: `Skipped package.json files found within ignored paths: \`${skippedPackageFiles}\``, }); - config.logger.debug( + logger.debug( `Now have ${config.packageFiles.length} package file(s) after filtering` ); } @@ -264,6 +276,14 @@ async function resolvePackageFiles(inputConfig) { config.baseBranch ); if (packageFile.content) { + // check for workspaces + if ( + packageFile.packageFile === 'package.json' && + packageFile.content.workspaces + ) { + config.logger.info('Found yarn workspaces configuration'); + config.hasYarnWorkspaces = true; + } // hoist renovate config if exists if (packageFile.content.renovate) { config.hasPackageJsonRenovateConfig = true; diff --git a/test/workers/branch/__snapshots__/lock-files.spec.js.snap b/test/workers/branch/__snapshots__/lock-files.spec.js.snap index 5e234a665e565d92fb9fbfd70788a961aa83a60e..dc3f6ab903bcef49386175b13446a55b29a447e5 100644 --- a/test/workers/branch/__snapshots__/lock-files.spec.js.snap +++ b/test/workers/branch/__snapshots__/lock-files.spec.js.snap @@ -22,6 +22,15 @@ Object { } `; +exports[`workers/branch/lock-files determineLockFileDirs returns root directory if using yarn workspaces 1`] = ` +Object { + "packageLockFileDirs": Array [], + "yarnLockFileDirs": Array [ + ".", + ], +} +`; + exports[`workers/branch/lock-files getUpdatedLockFiles adds multiple lock files 1`] = ` Object { "lockFileError": false, diff --git a/test/workers/branch/lock-files.spec.js b/test/workers/branch/lock-files.spec.js index d4231e658fc3cc14f0a61ec95cb89d2d0274cd2f..05cdbd3bf5b239d95d67097955523ad98062e356 100644 --- a/test/workers/branch/lock-files.spec.js +++ b/test/workers/branch/lock-files.spec.js @@ -149,6 +149,30 @@ describe('workers/branch/lock-files', () => { const res = determineLockFileDirs(config); expect(res).toMatchSnapshot(); }); + it('returns root directory if using yarn workspaces', () => { + config.hasYarnWorkspaces = true; + config.upgrades = [{}]; + config.packageFiles = [ + { + packageFile: 'package.json', + hasYarnLock: true, + }, + { + packageFile: 'backend/package.json', + }, + ]; + config.updatedPackageFiles = [ + { + name: 'backend/package.json', + contents: 'some contents', + }, + ]; + const res = determineLockFileDirs(config); + expect(res).toMatchSnapshot(); + expect(res.packageLockFileDirs).toHaveLength(0); + expect(res.yarnLockFileDirs).toHaveLength(1); + expect(res.yarnLockFileDirs[0]).toEqual('.'); + }); }); describe('writeExistingFiles', () => { let config; diff --git a/test/workers/package-file/index.spec.js b/test/workers/package-file/index.spec.js index 826d8f16eaf059251e61acd40495d335ac5936bf..453f1cd484696b01217622b8ca62beedd5191e8e 100644 --- a/test/workers/package-file/index.spec.js +++ b/test/workers/package-file/index.spec.js @@ -26,12 +26,6 @@ describe('packageFileWorker', () => { const res = await packageFileWorker.renovatePackageFile(config); expect(res).toEqual([]); }); - it('warns if using workspaces', async () => { - config.content.workspaces = {}; - const res = await packageFileWorker.renovatePackageFile(config); - expect(res).toHaveLength(1); - expect(res[0].type).toEqual('warning'); - }); it('returns upgrades', async () => { depTypeWorker.renovateDepType.mockReturnValueOnce([{}]); depTypeWorker.renovateDepType.mockReturnValueOnce([{}, {}]); diff --git a/test/workers/repository/__snapshots__/apis.spec.js.snap b/test/workers/repository/__snapshots__/apis.spec.js.snap index d27792d0035d8ce7f29d66035eaf43d4823d0608..f3a1a1a96dee0893a5cfa920fecfb1d0aa4db146 100644 --- a/test/workers/repository/__snapshots__/apis.spec.js.snap +++ b/test/workers/repository/__snapshots__/apis.spec.js.snap @@ -93,7 +93,9 @@ exports[`workers/repository/apis mergeRenovateJson(config) returns warning + err exports[`workers/repository/apis resolvePackageFiles includes files with content 1`] = ` Array [ Object { - "content": Object {}, + "content": Object { + "workspaces": Array [], + }, "errors": Array [], "hasPackageLock": true, "hasYarnLock": true, diff --git a/test/workers/repository/apis.spec.js b/test/workers/repository/apis.spec.js index 872bc8ab7c10b341730ef02b6183d54aa6c9cf65..346eee59e40520ac2354986bdb91f850219f2558 100644 --- a/test/workers/repository/apis.spec.js +++ b/test/workers/repository/apis.spec.js @@ -285,7 +285,10 @@ describe('workers/repository/apis', () => { expect(res.packageFiles).toEqual([]); }); it('includes files with content', async () => { - config.api.getFileJson.mockReturnValueOnce({ renovate: {} }); + config.api.getFileJson.mockReturnValueOnce({ + renovate: {}, + workspaces: [], + }); config.api.getFileJson.mockReturnValueOnce({}); config.api.getFileContent.mockReturnValueOnce(null); config.api.getFileContent.mockReturnValueOnce(null);