Skip to content

Commit

Permalink
feat: yarn workspaces lock file support
Browse files Browse the repository at this point in the history
This feature adds explicit support for correctly generating the yarn.lock file for workspaces. Specifically, it means that the yarn.lock in the root directory is regenerated whenever *any* package.json is modified. Previously lock files were only every updated if its corresponding package.json changes, but that is not the way yarn workspaces works.

Closes #473
  • Loading branch information
rarkins committed Aug 27, 2017
1 parent d98130f commit 1bf1fae
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 23 deletions.
5 changes: 5 additions & 0 deletions lib/workers/branch/lock-files.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
}

Expand Down
11 changes: 0 additions & 11 deletions lib/workers/package-file/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
28 changes: 24 additions & 4 deletions lib/workers/repository/apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -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`
);
}
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions test/workers/branch/__snapshots__/lock-files.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
24 changes: 24 additions & 0 deletions test/workers/branch/lock-files.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 0 additions & 6 deletions test/workers/package-file/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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([{}, {}]);
Expand Down
4 changes: 3 additions & 1 deletion test/workers/repository/__snapshots__/apis.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion test/workers/repository/apis.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 1bf1fae

Please sign in to comment.