Merge pull request #1558 from ing-bank/fix/dedupeMatchImportsResults
Fix/dedupe match imports results
This commit is contained in:
commit
f282091750
12 changed files with 105 additions and 49 deletions
7
.changeset/kind-zoos-bathe.md
Normal file
7
.changeset/kind-zoos-bathe.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
'providence-analytics': patch
|
||||
---
|
||||
|
||||
- correctly dedupe match-imports exportSpecifiers
|
||||
- windows compatibility
|
||||
- example conf file esm compatible
|
||||
5
.changeset/polite-hairs-shave.md
Normal file
5
.changeset/polite-hairs-shave.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'rocket-preset-extend-lion-docs': patch
|
||||
---
|
||||
|
||||
windows compatibility
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
"scripts": {
|
||||
"dashboard": "node ./dashboard/src/server.js --serve-from-package-root",
|
||||
"match-lion-imports": "npm run providence analyze match-imports --search-target-collection @lion-targets --reference-collection @lion-references",
|
||||
"providence": "node --max-old-space-size=8192 ./src/cli/index.js",
|
||||
"providence": "node --max-old-space-size=8192 ./src/cli/index.mjs",
|
||||
"publish-docs": "node ../../packages-node/publish-docs/src/cli.js --github-url https://github.com/ing-bank/lion/ --git-root-dir ../../",
|
||||
"prepublishOnly": "npm run publish-docs",
|
||||
"test:node": "mocha './test-node/**/*.test.js'",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import pathLib from 'path';
|
||||
import pathLib, { dirname } from 'path';
|
||||
import fs from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
// This file is read by dashboard and cli and needs to be present under process.cwd()
|
||||
// It mainly serves as an example and it allows to run the dashboard locally
|
||||
|
|
|
|||
|
|
@ -115,7 +115,12 @@ async function appendProjectDependencyPaths(rootPaths, matchPattern, modes = ['n
|
|||
let matchFn;
|
||||
if (matchPattern) {
|
||||
if (matchPattern.startsWith('/') && matchPattern.endsWith('/')) {
|
||||
matchFn = (_, d) => new RegExp(matchPattern.slice(1, -1)).test(d);
|
||||
matchFn = (_, d) => {
|
||||
const reString = matchPattern.slice(1, -1);
|
||||
const result = new RegExp(reString).test(d);
|
||||
LogService.debug(`[appendProjectDependencyPaths]: /${reString}/.test(${d} => ${result})`);
|
||||
return result;
|
||||
};
|
||||
} else {
|
||||
LogService.error(
|
||||
`[appendProjectDependencyPaths] Please provide a matchPattern enclosed by '/'. Found: ${matchPattern}`,
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ const { LogService } = require('../program/services/LogService.js');
|
|||
const JsdocCommentParser = require('../program/utils/jsdoc-comment-parser.js');
|
||||
|
||||
/**
|
||||
* @desc extracts name, defaultValue, optional, type, desc from JsdocCommentParser.parse method
|
||||
* Extracts name, defaultValue, optional, type, desc from JsdocCommentParser.parse method
|
||||
* result
|
||||
* @param {array} jsdoc
|
||||
* @returns {object}
|
||||
* @param {string[]} jsdoc
|
||||
* @returns {{ name:string, defaultValue:string, optional:boolean, type:string, desc:string }}
|
||||
*/
|
||||
function getPropsFromParsedJsDoc(jsdoc) {
|
||||
const jsdocProps = jsdoc.filter(p => p.tagName === '@property');
|
||||
|
|
|
|||
|
|
@ -237,7 +237,9 @@ async function matchImportsPostprocess(exportsAnalyzerResult, importsAnalyzerRes
|
|||
* Add it to the results array
|
||||
*/
|
||||
const id = `${exportEntry.specifier}::${exportEntry.file}::${exportsAnalyzerResult.analyzerMeta.targetProject.name}`;
|
||||
const resultForCurrentExport = conciseResultsArray.find(entry => entry.id === id);
|
||||
const resultForCurrentExport = conciseResultsArray.find(
|
||||
entry => entry.exportSpecifier && entry.exportSpecifier.id === id,
|
||||
);
|
||||
if (resultForCurrentExport) {
|
||||
resultForCurrentExport.importProjectFiles.push(importEntry.file);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
const pathLib = require('path');
|
||||
const { nodeResolve } = require('@rollup/plugin-node-resolve');
|
||||
const { LogService } = require('../services/LogService.js');
|
||||
const { memoizeAsync } = require('./memoize.js');
|
||||
const { toPosixPath } = require('./to-posix-path.js');
|
||||
|
||||
const fakePluginContext = {
|
||||
meta: {
|
||||
|
|
@ -27,15 +29,6 @@ const fakePluginContext = {
|
|||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Based on importee (in a statement "import {x} from '@lion/core'", "@lion/core" is an
|
||||
* importee), which can be a bare module specifier, a filename without extension, or a folder
|
||||
* name without an extension.
|
||||
* @param {SpecifierSource} importee source like '@lion/core' or '../helpers/index.js'
|
||||
* @param {PathFromSystemRoot} importer importing file, like '/my/project/importing-file.js'
|
||||
* @param {{customResolveOptions?: {preserveSymlinks:boolean}}} [opts] nodeResolve options
|
||||
* @returns {Promise<PathFromSystemRoot|null>} the resolved file system path, like '/my/project/node_modules/@lion/core/index.js'
|
||||
*/
|
||||
async function resolveImportPath(importee, importer, opts = {}) {
|
||||
const rollupResolve = nodeResolve({
|
||||
rootDir: pathLib.dirname(importer),
|
||||
|
|
@ -59,7 +52,18 @@ async function resolveImportPath(importee, importer, opts = {}) {
|
|||
return null;
|
||||
}
|
||||
// @ts-ignore
|
||||
return result.id;
|
||||
return toPosixPath(result.id);
|
||||
}
|
||||
|
||||
module.exports = { resolveImportPath };
|
||||
/**
|
||||
* Based on importee (in a statement "import {x} from '@lion/core'", "@lion/core" is an
|
||||
* importee), which can be a bare module specifier, a filename without extension, or a folder
|
||||
* name without an extension.
|
||||
* @param {SpecifierSource} importee source like '@lion/core' or '../helpers/index.js'
|
||||
* @param {PathFromSystemRoot} importer importing file, like '/my/project/importing-file.js'
|
||||
* @param {{customResolveOptions?: {preserveSymlinks:boolean}}} [opts] nodeResolve options
|
||||
* @returns {Promise<PathFromSystemRoot|null>} the resolved file system path, like '/my/project/node_modules/@lion/core/index.js'
|
||||
*/
|
||||
const resolveImportPathMemoized = memoizeAsync(resolveImportPath);
|
||||
|
||||
module.exports = { resolveImportPath: resolveImportPathMemoized };
|
||||
|
|
|
|||
|
|
@ -92,57 +92,41 @@
|
|||
{
|
||||
"name": "getterSetter",
|
||||
"accessType": "public",
|
||||
"kind": [
|
||||
"get",
|
||||
"set"
|
||||
]
|
||||
"kind": ["get", "set"]
|
||||
},
|
||||
{
|
||||
"name": "staticGetterSetter",
|
||||
"accessType": "public",
|
||||
"static": true,
|
||||
"kind": [
|
||||
"get",
|
||||
"set"
|
||||
]
|
||||
"kind": ["get", "set"]
|
||||
},
|
||||
{
|
||||
"name": "attributes",
|
||||
"accessType": "public",
|
||||
"static": true,
|
||||
"kind": [
|
||||
"get"
|
||||
]
|
||||
"kind": ["get"]
|
||||
},
|
||||
{
|
||||
"name": "styles",
|
||||
"accessType": "public",
|
||||
"static": true,
|
||||
"kind": [
|
||||
"get"
|
||||
]
|
||||
"kind": ["get"]
|
||||
},
|
||||
{
|
||||
"name": "updateComplete",
|
||||
"accessType": "public",
|
||||
"kind": [
|
||||
"get"
|
||||
]
|
||||
"kind": ["get"]
|
||||
},
|
||||
{
|
||||
"name": "localizeNamespaces",
|
||||
"accessType": "public",
|
||||
"static": true,
|
||||
"kind": [
|
||||
"get"
|
||||
]
|
||||
"kind": ["get"]
|
||||
},
|
||||
{
|
||||
"name": "slots",
|
||||
"accessType": "public",
|
||||
"kind": [
|
||||
"get"
|
||||
]
|
||||
"kind": ["get"]
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
|
|
@ -180,7 +164,7 @@
|
|||
},
|
||||
{
|
||||
"name": "requestUpdate",
|
||||
"accessType": "protected"
|
||||
"accessType": "public"
|
||||
},
|
||||
{
|
||||
"name": "createRenderRoot",
|
||||
|
|
|
|||
|
|
@ -484,8 +484,18 @@ describe('CLI helpers', () => {
|
|||
});
|
||||
|
||||
it('allows a regex filter', async () => {
|
||||
const result = await appendProjectDependencyPaths(['/mocked/path/example-project'], '/b$/');
|
||||
const result = await appendProjectDependencyPaths(
|
||||
['/mocked/path/example-project'],
|
||||
'/^dependency-/',
|
||||
);
|
||||
expect(result).to.eql([
|
||||
'/mocked/path/example-project/node_modules/dependency-a',
|
||||
'/mocked/path/example-project/bower_components/dependency-b',
|
||||
'/mocked/path/example-project',
|
||||
]);
|
||||
|
||||
const result2 = await appendProjectDependencyPaths(['/mocked/path/example-project'], '/b$/');
|
||||
expect(result2).to.eql([
|
||||
'/mocked/path/example-project/bower_components/dependency-b',
|
||||
'/mocked/path/example-project',
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -441,6 +441,32 @@ describe('Analyzer "match-imports"', () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it(`correctly merges/dedupes double found exports`, async () => {
|
||||
const refProject = {
|
||||
path: '/target/node_modules/ref',
|
||||
name: 'ref',
|
||||
files: [{ file: './index.js', code: `export default function x() {};` }],
|
||||
};
|
||||
const targetProject = {
|
||||
path: '/target',
|
||||
name: 'target',
|
||||
files: [
|
||||
{ file: './importDefault1.js', code: `import myFn1 from 'ref/index.js';` },
|
||||
{ file: './importDefault2.js', code: `import myFn2 from 'ref/index.js';` },
|
||||
],
|
||||
};
|
||||
mockTargetAndReferenceProject(targetProject, refProject);
|
||||
await providence(matchImportsQueryConfig, {
|
||||
targetProjectPaths: [targetProject.path],
|
||||
referenceProjectPaths: [refProject.path],
|
||||
});
|
||||
const queryResult = queryResults[0];
|
||||
expect(queryResult.queryOutput[0].exportSpecifier.name).to.equal('[default]');
|
||||
expect(queryResult.queryOutput[0].matchesPerProject).to.eql([
|
||||
{ files: ['./importDefault1.js', './importDefault2.js'], project: 'target' },
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Inside small example project', () => {
|
||||
it(`produces a list of all matches, sorted by project`, async () => {
|
||||
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
||||
|
|
|
|||
|
|
@ -12,15 +12,26 @@ import visit from 'unist-util-visit';
|
|||
|
||||
/** @typedef {Node & UrlProperty} UrlNode */
|
||||
|
||||
/**
|
||||
* @param {string} pathStr C:\Example\path/like/this
|
||||
* @returns {string} /Example/path/like/this
|
||||
*/
|
||||
function toPosixPath(pathStr) {
|
||||
if (process.platform === 'win32') {
|
||||
return pathStr.replace(/^.:/, '').replace(/\\/g, '/');
|
||||
}
|
||||
return pathStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} opts
|
||||
* @param {string} opts.gitHubUrl
|
||||
* @param {object} opts.page
|
||||
* @param {string} opts.page.inputPath
|
||||
* @param {{inputPath:string}} opts.page
|
||||
* @param {string} opts.rootDir
|
||||
* @returns
|
||||
*/
|
||||
export function remarkUrlToLocal({ gitHubUrl, page, rootDir }) {
|
||||
const inputPath = toPosixPath(page.inputPath);
|
||||
|
||||
/**
|
||||
* @param {UrlNode} node
|
||||
*/
|
||||
|
|
@ -34,10 +45,9 @@ export function remarkUrlToLocal({ gitHubUrl, page, rootDir }) {
|
|||
urlParts.shift();
|
||||
urlParts.shift();
|
||||
const fullUrlPath = path.join(rootDir, urlParts.join('/'));
|
||||
const fullInputPath =
|
||||
page.inputPath[0] === '/' ? page.inputPath : path.join(rootDir, page.inputPath);
|
||||
const fullInputPath = inputPath[0] === '/' ? inputPath : path.join(rootDir, inputPath);
|
||||
const newPath = path.relative(path.dirname(fullInputPath), fullUrlPath);
|
||||
node.url = newPath;
|
||||
node.url = toPosixPath(newPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue