feat(providence-analytics): add option skipCheckMatchCompatibility
This commit is contained in:
parent
7b4a0c4aef
commit
ca210dae73
8 changed files with 119 additions and 11 deletions
5
.changeset/tasty-rabbits-fry.md
Normal file
5
.changeset/tasty-rabbits-fry.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"providence-analytics": feat
|
||||||
|
---
|
||||||
|
|
||||||
|
add option skipCheckMatchCompatibility and enable for monorepos in extend-docs
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const pathLib = require('path');
|
const pathLib = require('path');
|
||||||
const { performance } = require('perf_hooks');
|
const { performance } = require('perf_hooks');
|
||||||
const { providence } = require('../program/providence.js');
|
const providenceModule = require('../program/providence.js');
|
||||||
const { QueryService } = require('../program/services/QueryService.js');
|
const { QueryService } = require('../program/services/QueryService.js');
|
||||||
const { InputDataService } = require('../program/services/InputDataService.js');
|
const { InputDataService } = require('../program/services/InputDataService.js');
|
||||||
const { LogService } = require('../program/services/LogService.js');
|
const { LogService } = require('../program/services/LogService.js');
|
||||||
|
|
@ -16,7 +16,9 @@ async function getExtendDocsResults({
|
||||||
allowlistReference,
|
allowlistReference,
|
||||||
cwd,
|
cwd,
|
||||||
}) {
|
}) {
|
||||||
const results = await providence(
|
const monoPkgs = InputDataService.getMonoRepoPackages(cwd);
|
||||||
|
|
||||||
|
const results = await providenceModule.providence(
|
||||||
QueryService.getQueryConfigFromAnalyzer('match-paths', { prefix: prefixCfg }),
|
QueryService.getQueryConfigFromAnalyzer('match-paths', { prefix: prefixCfg }),
|
||||||
{
|
{
|
||||||
gatherFilesConfig: {
|
gatherFilesConfig: {
|
||||||
|
|
@ -31,6 +33,9 @@ async function getExtendDocsResults({
|
||||||
report: false,
|
report: false,
|
||||||
targetProjectPaths: [pathLib.resolve(cwd)],
|
targetProjectPaths: [pathLib.resolve(cwd)],
|
||||||
referenceProjectPaths,
|
referenceProjectPaths,
|
||||||
|
// For mono repos, a match between root package.json and ref project will not exist.
|
||||||
|
// Disable this check, so it won't be a blocker for extendin docs
|
||||||
|
skipCheckMatchCompatibility: Boolean(monoPkgs),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -57,20 +62,18 @@ async function getExtendDocsResults({
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pkgs = InputDataService.getMonoRepoPackages(cwd);
|
if (monoPkgs) {
|
||||||
|
|
||||||
if (pkgs) {
|
|
||||||
queryOutputs.forEach(resultObj => {
|
queryOutputs.forEach(resultObj => {
|
||||||
if (resultObj.variable) {
|
if (resultObj.variable) {
|
||||||
resultObj.variable.paths.forEach(pathObj => {
|
resultObj.variable.paths.forEach(pathObj => {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
pathObj.to = replaceToMonoRepoPath(pathObj.to, pkgs);
|
pathObj.to = replaceToMonoRepoPath(pathObj.to, monoPkgs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (resultObj.tag) {
|
if (resultObj.tag) {
|
||||||
resultObj.tag.paths.forEach(pathObj => {
|
resultObj.tag.paths.forEach(pathObj => {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
pathObj.to = replaceToMonoRepoPath(pathObj.to, pkgs);
|
pathObj.to = replaceToMonoRepoPath(pathObj.to, monoPkgs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ class Analyzer {
|
||||||
|
|
||||||
// If we have a provided result cfg.referenceProjectResult, we assume the providing
|
// If we have a provided result cfg.referenceProjectResult, we assume the providing
|
||||||
// party provides compatible results for now...
|
// party provides compatible results for now...
|
||||||
if (cfg.referenceProjectPath) {
|
if (cfg.referenceProjectPath && !cfg.skipCheckMatchCompatibility) {
|
||||||
const { compatible, reason } = checkForMatchCompatibility(
|
const { compatible, reason } = checkForMatchCompatibility(
|
||||||
cfg.referenceProjectPath,
|
cfg.referenceProjectPath,
|
||||||
cfg.targetProjectPath,
|
cfg.targetProjectPath,
|
||||||
|
|
|
||||||
|
|
@ -249,6 +249,7 @@ class MatchImportsAnalyzer extends Analyzer {
|
||||||
referenceProjectResult = await findExportsAnalyzer.execute({
|
referenceProjectResult = await findExportsAnalyzer.execute({
|
||||||
metaConfig: cfg.metaConfig,
|
metaConfig: cfg.metaConfig,
|
||||||
targetProjectPath: cfg.referenceProjectPath,
|
targetProjectPath: cfg.referenceProjectPath,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,6 +259,7 @@ class MatchImportsAnalyzer extends Analyzer {
|
||||||
targetProjectResult = await findImportsAnalyzer.execute({
|
targetProjectResult = await findImportsAnalyzer.execute({
|
||||||
metaConfig: cfg.metaConfig,
|
metaConfig: cfg.metaConfig,
|
||||||
targetProjectPath: cfg.targetProjectPath,
|
targetProjectPath: cfg.targetProjectPath,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -216,8 +216,7 @@ function getTagPaths(
|
||||||
let targetResult;
|
let targetResult;
|
||||||
targetFindCustomelementsResult.queryOutput.some(({ file, result }) => {
|
targetFindCustomelementsResult.queryOutput.some(({ file, result }) => {
|
||||||
const targetPathMatch = result.find(entry => {
|
const targetPathMatch = result.find(entry => {
|
||||||
const sameRoot =
|
const sameRoot = entry.rootFile.file === targetMatchedFile;
|
||||||
entry.rootFile.file === targetMatchedFile || entry.rootFile.file === '[current]';
|
|
||||||
const sameIdentifier = entry.rootFile.specifier === toClass;
|
const sameIdentifier = entry.rootFile.specifier === toClass;
|
||||||
return sameRoot && sameIdentifier;
|
return sameRoot && sameIdentifier;
|
||||||
});
|
});
|
||||||
|
|
@ -429,6 +428,7 @@ class MatchPathsAnalyzer extends Analyzer {
|
||||||
referenceProjectPath: cfg.referenceProjectPath,
|
referenceProjectPath: cfg.referenceProjectPath,
|
||||||
gatherFilesConfig: cfg.gatherFilesConfig,
|
gatherFilesConfig: cfg.gatherFilesConfig,
|
||||||
gatherFilesConfigReference: cfg.gatherFilesConfigReference,
|
gatherFilesConfigReference: cfg.gatherFilesConfigReference,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
});
|
});
|
||||||
|
|
||||||
// [A2]
|
// [A2]
|
||||||
|
|
@ -437,6 +437,7 @@ class MatchPathsAnalyzer extends Analyzer {
|
||||||
const targetExportsResult = await targetFindExportsAnalyzer.execute({
|
const targetExportsResult = await targetFindExportsAnalyzer.execute({
|
||||||
targetProjectPath: cfg.targetProjectPath,
|
targetProjectPath: cfg.targetProjectPath,
|
||||||
gatherFilesConfig: cfg.gatherFilesConfig,
|
gatherFilesConfig: cfg.gatherFilesConfig,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
});
|
});
|
||||||
|
|
||||||
// [A3]
|
// [A3]
|
||||||
|
|
@ -445,6 +446,7 @@ class MatchPathsAnalyzer extends Analyzer {
|
||||||
const refFindExportsResult = await refFindExportsAnalyzer.execute({
|
const refFindExportsResult = await refFindExportsAnalyzer.execute({
|
||||||
targetProjectPath: cfg.referenceProjectPath,
|
targetProjectPath: cfg.referenceProjectPath,
|
||||||
gatherFilesConfig: cfg.gatherFilesConfigReference,
|
gatherFilesConfig: cfg.gatherFilesConfigReference,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -472,6 +474,7 @@ class MatchPathsAnalyzer extends Analyzer {
|
||||||
const targetFindCustomelementsResult = await targetFindCustomelementsAnalyzer.execute({
|
const targetFindCustomelementsResult = await targetFindCustomelementsAnalyzer.execute({
|
||||||
targetProjectPath: cfg.targetProjectPath,
|
targetProjectPath: cfg.targetProjectPath,
|
||||||
gatherFilesConfig: cfg.gatherFilesConfig,
|
gatherFilesConfig: cfg.gatherFilesConfig,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
});
|
});
|
||||||
|
|
||||||
// [B2]
|
// [B2]
|
||||||
|
|
@ -480,6 +483,7 @@ class MatchPathsAnalyzer extends Analyzer {
|
||||||
const refFindCustomelementsResult = await refFindCustomelementsAnalyzer.execute({
|
const refFindCustomelementsResult = await refFindCustomelementsAnalyzer.execute({
|
||||||
targetProjectPath: cfg.referenceProjectPath,
|
targetProjectPath: cfg.referenceProjectPath,
|
||||||
gatherFilesConfig: cfg.gatherFilesConfigReference,
|
gatherFilesConfig: cfg.gatherFilesConfigReference,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
});
|
});
|
||||||
// refFindExportsAnalyzer was already created in A3
|
// refFindExportsAnalyzer was already created in A3
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -297,17 +297,20 @@ class MatchSubclassesAnalyzer extends Analyzer {
|
||||||
const exportsAnalyzerResult = await findExportsAnalyzer.execute({
|
const exportsAnalyzerResult = await findExportsAnalyzer.execute({
|
||||||
targetProjectPath: cfg.referenceProjectPath,
|
targetProjectPath: cfg.referenceProjectPath,
|
||||||
gatherFilesConfig: cfg.gatherFilesConfigReference,
|
gatherFilesConfig: cfg.gatherFilesConfigReference,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
});
|
});
|
||||||
const findClassesAnalyzer = new FindClassesAnalyzer();
|
const findClassesAnalyzer = new FindClassesAnalyzer();
|
||||||
/** @type {FindClassesAnalyzerResult} */
|
/** @type {FindClassesAnalyzerResult} */
|
||||||
const targetClassesAnalyzerResult = await findClassesAnalyzer.execute({
|
const targetClassesAnalyzerResult = await findClassesAnalyzer.execute({
|
||||||
targetProjectPath: cfg.targetProjectPath,
|
targetProjectPath: cfg.targetProjectPath,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
});
|
});
|
||||||
const findRefClassesAnalyzer = new FindClassesAnalyzer();
|
const findRefClassesAnalyzer = new FindClassesAnalyzer();
|
||||||
/** @type {FindClassesAnalyzerResult} */
|
/** @type {FindClassesAnalyzerResult} */
|
||||||
const refClassesAnalyzerResult = await findRefClassesAnalyzer.execute({
|
const refClassesAnalyzerResult = await findRefClassesAnalyzer.execute({
|
||||||
targetProjectPath: cfg.referenceProjectPath,
|
targetProjectPath: cfg.referenceProjectPath,
|
||||||
gatherFilesConfig: cfg.gatherFilesConfigReference,
|
gatherFilesConfig: cfg.gatherFilesConfigReference,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
});
|
});
|
||||||
|
|
||||||
const queryOutput = matchSubclassesPostprocess(
|
const queryOutput = matchSubclassesPostprocess(
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ async function handleAnalyzerForProjectCombo(slicedQConfig, cfg) {
|
||||||
const queryResult = await QueryService.astSearch(slicedQConfig, {
|
const queryResult = await QueryService.astSearch(slicedQConfig, {
|
||||||
gatherFilesConfig: cfg.gatherFilesConfig,
|
gatherFilesConfig: cfg.gatherFilesConfig,
|
||||||
gatherFilesConfigReference: cfg.gatherFilesConfigReference,
|
gatherFilesConfigReference: cfg.gatherFilesConfigReference,
|
||||||
|
skipCheckMatchCompatibility: cfg.skipCheckMatchCompatibility,
|
||||||
...slicedQConfig.analyzerConfig,
|
...slicedQConfig.analyzerConfig,
|
||||||
});
|
});
|
||||||
if (queryResult) {
|
if (queryResult) {
|
||||||
|
|
@ -179,6 +180,7 @@ async function providenceMain(queryConfig, customConfig) {
|
||||||
report: true,
|
report: true,
|
||||||
debugEnabled: false,
|
debugEnabled: false,
|
||||||
writeLogFile: false,
|
writeLogFile: false,
|
||||||
|
skipCheckMatchCompatibility: false,
|
||||||
},
|
},
|
||||||
customConfig,
|
customConfig,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -515,7 +515,6 @@ describe('CLI helpers', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
restoreMockedProjects();
|
restoreMockedProjects();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rewrites monorepo package paths when analysis is run from monorepo root', async () => {
|
it('rewrites monorepo package paths when analysis is run from monorepo root', async () => {
|
||||||
const theirProjectFiles = {
|
const theirProjectFiles = {
|
||||||
'./package.json': JSON.stringify({
|
'./package.json': JSON.stringify({
|
||||||
|
|
@ -641,5 +640,95 @@ describe('CLI helpers', () => {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not check for match compatibility (target and reference) in monorepo targets', async () => {
|
||||||
|
// ===== REFERENCE AND TARGET PROJECTS =====
|
||||||
|
|
||||||
|
const theirProjectFiles = {
|
||||||
|
'./package.json': JSON.stringify({
|
||||||
|
name: 'their-components',
|
||||||
|
version: '1.0.0',
|
||||||
|
}),
|
||||||
|
'./src/TheirButton.js': `export class TheirButton extends HTMLElement {}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
// This will be detected as being a monorepo
|
||||||
|
const monoProjectFiles = {
|
||||||
|
'./package.json': JSON.stringify({
|
||||||
|
name: '@mono/root',
|
||||||
|
workspaces: ['packages/*'],
|
||||||
|
dependencies: {
|
||||||
|
'their-components': '1.0.0',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
// Package: @mono/button
|
||||||
|
'./packages/button/package.json': JSON.stringify({
|
||||||
|
name: '@mono/button',
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
// This will be detected as NOT being a monorepo
|
||||||
|
const nonMonoProjectFiles = {
|
||||||
|
'./package.json': JSON.stringify({
|
||||||
|
name: 'non-mono',
|
||||||
|
dependencies: {
|
||||||
|
'their-components': '1.0.0',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const theirProject = {
|
||||||
|
path: '/their-components',
|
||||||
|
name: 'their-components',
|
||||||
|
files: Object.entries(theirProjectFiles).map(([file, code]) => ({ file, code })),
|
||||||
|
};
|
||||||
|
|
||||||
|
const monoProject = {
|
||||||
|
path: '/mono-components',
|
||||||
|
name: 'mono-components',
|
||||||
|
files: Object.entries(monoProjectFiles).map(([file, code]) => ({ file, code })),
|
||||||
|
};
|
||||||
|
|
||||||
|
const nonMonoProject = {
|
||||||
|
path: '/non-mono-components',
|
||||||
|
name: 'non-mono-components',
|
||||||
|
files: Object.entries(nonMonoProjectFiles).map(([file, code]) => ({ file, code })),
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===== TESTS =====
|
||||||
|
|
||||||
|
const providenceStub = sinon.stub(providenceModule, 'providence').returns(
|
||||||
|
new Promise(resolve => {
|
||||||
|
resolve([]);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// ===== mono =====
|
||||||
|
|
||||||
|
mockTargetAndReferenceProject(theirProject, monoProject);
|
||||||
|
await getExtendDocsResults({
|
||||||
|
referenceProjectPaths: ['/their-components'],
|
||||||
|
prefixCfg: { from: 'their', to: 'my' },
|
||||||
|
extensions: ['.js'],
|
||||||
|
cwd: '/mono-components',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(providenceStub.args[0][1].skipCheckMatchCompatibility).to.equal(true);
|
||||||
|
providenceStub.resetHistory();
|
||||||
|
restoreMockedProjects();
|
||||||
|
|
||||||
|
// ===== non mono =====
|
||||||
|
|
||||||
|
mockTargetAndReferenceProject(theirProject, nonMonoProject);
|
||||||
|
await getExtendDocsResults({
|
||||||
|
referenceProjectPaths: ['/their-components'],
|
||||||
|
prefixCfg: { from: 'their', to: 'my' },
|
||||||
|
extensions: ['.js'],
|
||||||
|
cwd: '/non-mono-components',
|
||||||
|
});
|
||||||
|
expect(providenceStub.args[0][1].skipCheckMatchCompatibility).to.equal(false);
|
||||||
|
|
||||||
|
providenceStub.restore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue