mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-25 14:06:27 +00:00
feat: use package names for ignoring when lerna or workspaces (#787)
* add minimatch * feat: use package names for ignoring when lerna or workspaces Renovate will now: - Find all package.json files matching lerna or yarn workspaces glob pattern - Retrieve package names from within those package.json files - Implicitly ignore (not renvoate) any of those names Closes #781
This commit is contained in:
parent
6acef47c87
commit
8fa94141a1
8 changed files with 114 additions and 100 deletions
|
@ -26,14 +26,11 @@ async function renovateDepType(packageContent, config) {
|
|||
logger.debug(`currentDeps length is ${currentDeps.length}`);
|
||||
logger.debug({ currentDeps }, `currentDeps`);
|
||||
// Filter out ignored dependencies
|
||||
let filteredDeps = currentDeps.filter(
|
||||
dependency => config.ignoreDeps.indexOf(dependency.depName) === -1
|
||||
const filteredDeps = currentDeps.filter(
|
||||
dependency =>
|
||||
config.ignoreDeps.indexOf(dependency.depName) === -1 &&
|
||||
config.monorepoPackages.indexOf(dependency.depName) === -1
|
||||
);
|
||||
if (config.lernaPackages) {
|
||||
filteredDeps = filteredDeps.filter(
|
||||
dependency => config.lernaPackages.indexOf(dependency.depName) === -1
|
||||
);
|
||||
}
|
||||
logger.debug(`filteredDeps length is ${filteredDeps.length}`);
|
||||
logger.debug({ filteredDeps }, `filteredDeps`);
|
||||
// Obtain full config for each dependency
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
const minimatch = require('minimatch');
|
||||
const conventionalCommitsDetector = require('conventional-commits-detector');
|
||||
const path = require('path');
|
||||
const jsonValidator = require('json-dup-key-validator');
|
||||
|
@ -12,10 +13,10 @@ const gitlabApi = require('../../api/gitlab');
|
|||
|
||||
module.exports = {
|
||||
detectSemanticCommits,
|
||||
checkMonorepos,
|
||||
getNpmrc,
|
||||
initApis,
|
||||
mergeRenovateJson,
|
||||
checkForLerna,
|
||||
detectPackageFiles,
|
||||
resolvePackageFiles,
|
||||
migrateAndValidate,
|
||||
|
@ -35,6 +36,50 @@ async function detectSemanticCommits(config) {
|
|||
return true;
|
||||
}
|
||||
|
||||
async function checkMonorepos(input) {
|
||||
const config = { ...input };
|
||||
const { logger } = config;
|
||||
config.monorepoPackages = [];
|
||||
// yarn workspaces
|
||||
if (config.hasYarnWorkspaces) {
|
||||
let workspaces = [];
|
||||
for (const packageFile of config.packageFiles) {
|
||||
if (packageFile.packageFile === 'package.json') {
|
||||
workspaces = packageFile.content.workspaces;
|
||||
}
|
||||
}
|
||||
logger.debug({ workspaces }, 'workspaces');
|
||||
for (const workspace of workspaces) {
|
||||
for (const packageFile of config.packageFiles) {
|
||||
if (minimatch(path.dirname(packageFile.packageFile), workspace)) {
|
||||
const depName = packageFile.content.name;
|
||||
config.monorepoPackages.push(depName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// lerna
|
||||
const lernaJson = await config.api.getFileJson('lerna.json');
|
||||
if (!lernaJson) {
|
||||
return config;
|
||||
}
|
||||
config.logger.debug({ lernaJson }, 'Found lerna config');
|
||||
if (!lernaJson.packages) {
|
||||
return config;
|
||||
}
|
||||
for (const packageGlob of lernaJson.packages) {
|
||||
for (const packageFile of config.packageFiles) {
|
||||
if (minimatch(path.dirname(packageFile.packageFile), packageGlob)) {
|
||||
const depName = packageFile.content.name;
|
||||
if (!config.monorepoPackages.includes(depName)) {
|
||||
config.monorepoPackages.push(depName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
// Check for .npmrc in repository and pass it to npm api if found
|
||||
async function getNpmrc(config) {
|
||||
let npmrc;
|
||||
|
@ -49,27 +94,6 @@ async function getNpmrc(config) {
|
|||
return { ...config, npmrc };
|
||||
}
|
||||
|
||||
async function checkForLerna(config) {
|
||||
const lernaJson = await config.api.getFileJson('lerna.json');
|
||||
if (!lernaJson) {
|
||||
return {};
|
||||
}
|
||||
config.logger.debug({ lernaJson }, 'Found lerna config');
|
||||
try {
|
||||
const packagesPath = lernaJson.packages
|
||||
? lernaJson.packages[0].slice(0, -2)
|
||||
: 'packages';
|
||||
const lernaPackages = await config.api.getSubDirectories(packagesPath);
|
||||
if (lernaPackages.length === 0) {
|
||||
return {};
|
||||
}
|
||||
return { lernaPackages };
|
||||
} catch (err) {
|
||||
config.logger.info('could not find any lerna subdirectories');
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
async function initApis(inputConfig, token) {
|
||||
function getPlatformApi(platform) {
|
||||
if (platform === 'github') {
|
||||
|
@ -88,10 +112,7 @@ async function initApis(inputConfig, token) {
|
|||
config.endpoint,
|
||||
config.logger
|
||||
);
|
||||
// Check for presence of .npmrc in repository
|
||||
Object.assign(config, platformConfig);
|
||||
const lernaConfig = await module.exports.checkForLerna(config);
|
||||
Object.assign(config, lernaConfig);
|
||||
if (config.semanticCommits === null) {
|
||||
config.semanticCommits = await module.exports.detectSemanticCommits(config);
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ async function renovateRepository(repoConfig, token) {
|
|||
}
|
||||
logger.debug('Resolving package files and content');
|
||||
config = await apis.resolvePackageFiles(config);
|
||||
config = await apis.checkMonorepos(config);
|
||||
logger.trace({ config }, 'post-packageFiles config');
|
||||
// TODO: why is this fix needed?!
|
||||
config.logger = logger;
|
||||
|
@ -108,6 +109,7 @@ async function renovateRepository(repoConfig, token) {
|
|||
}
|
||||
}
|
||||
config = await apis.resolvePackageFiles(config);
|
||||
config = await apis.checkMonorepos(config);
|
||||
config = await presets.resolveConfigPresets(config);
|
||||
config.logger = logger;
|
||||
logger.trace({ config }, 'onboarding config');
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
"jsonwebtoken": "7.4.3",
|
||||
"later": "1.2.0",
|
||||
"lodash": "4.17.4",
|
||||
"minimatch": "3.0.4",
|
||||
"moment": "2.18.1",
|
||||
"moment-timezone": "0.5.13",
|
||||
"registry-auth-token": "3.3.1",
|
||||
|
|
|
@ -15,7 +15,7 @@ describe('lib/workers/dep-type/index', () => {
|
|||
beforeEach(() => {
|
||||
config = {
|
||||
ignoreDeps: ['a', 'b'],
|
||||
lernaPackages: ['e'],
|
||||
monorepoPackages: ['e'],
|
||||
};
|
||||
});
|
||||
it('returns empty if config is disabled', async () => {
|
||||
|
|
|
@ -7,28 +7,20 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`workers/repository/apis checkForLerna(config) ignores zero length lerna 1`] = `Object {}`;
|
||||
|
||||
exports[`workers/repository/apis checkForLerna(config) implies lerna package path 1`] = `
|
||||
Object {
|
||||
"lernaPackages": Array [
|
||||
"a",
|
||||
"b",
|
||||
],
|
||||
}
|
||||
exports[`workers/repository/apis checkMonorepos adds lerna packages 1`] = `
|
||||
Array [
|
||||
"@a/b",
|
||||
"@a/c",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`workers/repository/apis checkForLerna(config) returns lerna package names 1`] = `
|
||||
Object {
|
||||
"lernaPackages": Array [
|
||||
"a",
|
||||
"b",
|
||||
],
|
||||
}
|
||||
exports[`workers/repository/apis checkMonorepos adds yarn workspaces 1`] = `
|
||||
Array [
|
||||
"@a/b",
|
||||
"@a/c",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`workers/repository/apis checkForLerna(config) swallows lerna 404 1`] = `Object {}`;
|
||||
|
||||
exports[`workers/repository/apis detectPackageFiles(config) adds package files to object 1`] = `
|
||||
Array [
|
||||
"package.json",
|
||||
|
|
|
@ -45,6 +45,55 @@ describe('workers/repository/apis', () => {
|
|||
expect(await apis.getNpmrc(config)).toMatchObject(config);
|
||||
});
|
||||
});
|
||||
describe('checkMonorepos', () => {
|
||||
let config;
|
||||
beforeEach(() => {
|
||||
config = {
|
||||
...defaultConfig,
|
||||
api: {
|
||||
getFileJson: jest.fn(),
|
||||
},
|
||||
logger,
|
||||
};
|
||||
});
|
||||
it('adds yarn workspaces', async () => {
|
||||
config.hasYarnWorkspaces = true;
|
||||
config.packageFiles = [
|
||||
{
|
||||
packageFile: 'package.json',
|
||||
content: { workspaces: ['packages/*'] },
|
||||
},
|
||||
{
|
||||
packageFile: 'packages/something/package.json',
|
||||
content: { name: '@a/b' },
|
||||
},
|
||||
{
|
||||
packageFile: 'packages/something-else/package.json',
|
||||
content: { name: '@a/c' },
|
||||
},
|
||||
];
|
||||
const res = await apis.checkMonorepos(config);
|
||||
expect(res.monorepoPackages).toMatchSnapshot();
|
||||
});
|
||||
it('adds lerna packages', async () => {
|
||||
config.packageFiles = [
|
||||
{
|
||||
packageFile: 'package.json',
|
||||
},
|
||||
{
|
||||
packageFile: 'packages/something/package.json',
|
||||
content: { name: '@a/b' },
|
||||
},
|
||||
{
|
||||
packageFile: 'packages/something-else/package.json',
|
||||
content: { name: '@a/c' },
|
||||
},
|
||||
];
|
||||
config.api.getFileJson.mockReturnValue({ packages: ['packages/*'] });
|
||||
const res = await apis.checkMonorepos(config);
|
||||
expect(res.monorepoPackages).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('detectSemanticCommits', () => {
|
||||
it('disables semantic commits', async () => {
|
||||
const config = {
|
||||
|
@ -68,54 +117,6 @@ describe('workers/repository/apis', () => {
|
|||
expect(res).toEqual(true);
|
||||
});
|
||||
});
|
||||
describe('checkForLerna(config)', () => {
|
||||
it('swallows lerna 404', async () => {
|
||||
const config = {
|
||||
api: {
|
||||
getFileJson: jest.fn(() => ({})),
|
||||
getSubDirectories: jest.fn(() => {
|
||||
throw new Error('some-error');
|
||||
}),
|
||||
},
|
||||
logger,
|
||||
};
|
||||
const res = await apis.checkForLerna(config);
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
it('ignores zero length lerna', async () => {
|
||||
const config = {
|
||||
api: {
|
||||
getFileJson: jest.fn(() => ({ packages: ['packages/*'] })),
|
||||
getSubDirectories: jest.fn(() => []),
|
||||
},
|
||||
logger,
|
||||
};
|
||||
const res = await apis.checkForLerna(config);
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
it('implies lerna package path', async () => {
|
||||
const config = {
|
||||
api: {
|
||||
getFileJson: jest.fn(() => ({})),
|
||||
getSubDirectories: jest.fn(() => ['a', 'b']),
|
||||
},
|
||||
logger,
|
||||
};
|
||||
const res = await apis.checkForLerna(config);
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
it('returns lerna package names', async () => {
|
||||
const config = {
|
||||
api: {
|
||||
getFileJson: jest.fn(() => ({ packages: ['packages/*'] })),
|
||||
getSubDirectories: jest.fn(() => ['a', 'b']),
|
||||
},
|
||||
logger,
|
||||
};
|
||||
const res = await apis.checkForLerna(config);
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('initApis(config)', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
|
|
@ -2958,7 +2958,7 @@ mimic-response@^1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e"
|
||||
|
||||
"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
|
||||
"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
dependencies:
|
||||
|
|
Loading…
Reference in a new issue