feat(providence-analytics): add windows support

This commit is contained in:
Ahmet Yesil 2020-10-07 15:23:26 +02:00
parent 928a673a2f
commit 66388a1a25
8 changed files with 81 additions and 18 deletions

View file

@ -6,6 +6,7 @@ const readPackageTree = require('../program/utils/read-package-tree-with-bower-s
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');
const { aForEach } = require('../program/utils/async-array-utils.js'); const { aForEach } = require('../program/utils/async-array-utils.js');
const { toPosixPath } = require('../program/utils/to-posix-path.js');
function flatten(arr) { function flatten(arr) {
return Array.prototype.concat.apply([], arr); return Array.prototype.concat.apply([], arr);
@ -47,9 +48,9 @@ function pathsArrayFromCs(t, cwd = process.cwd()) {
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
t = `${t}/`; t = `${t}/`;
} }
return glob.sync(t, { cwd, absolute: true }); return glob.sync(t, { cwd, absolute: true }).map(toPosixPath);
} }
return pathLib.resolve(cwd, t.trim()); return toPosixPath(pathLib.resolve(cwd, t.trim()));
}), }),
); );
} }
@ -144,7 +145,7 @@ async function appendProjectDependencyPaths(rootPaths, matchPattern, modes = ['n
// depProjectPaths.filter(depP => depP.startsWith(rootP)).; // depProjectPaths.filter(depP => depP.startsWith(rootP)).;
// }); // });
return depProjectPaths.concat(rootPaths); return depProjectPaths.concat(rootPaths).map(toPosixPath);
} }
async function installDeps(searchTargetPaths) { async function installDeps(searchTargetPaths) {

View file

@ -11,6 +11,7 @@ const { InputDataService } = require('../program/services/InputDataService.js');
const promptModule = require('./prompt-analyzer-menu.js'); const promptModule = require('./prompt-analyzer-menu.js');
const cliHelpers = require('./cli-helpers.js'); const cliHelpers = require('./cli-helpers.js');
const extendDocsModule = require('./generate-extend-docs-data.js'); const extendDocsModule = require('./generate-extend-docs-data.js');
const { toPosixPath } = require('../program/utils/to-posix-path.js');
const { extensionsFromCs, setQueryMethod, targetDefault, installDeps } = cliHelpers; const { extensionsFromCs, setQueryMethod, targetDefault, installDeps } = cliHelpers;
@ -282,7 +283,7 @@ async function cli({ cwd } = {}) {
.option( .option(
'--output-folder [output-folder]', '--output-folder [output-folder]',
`This is the file path where the result file "providence-extend-docs-data.json" will be written to`, `This is the file path where the result file "providence-extend-docs-data.json" will be written to`,
p => pathLib.resolve(process.cwd(), p.trim()), p => toPosixPath(pathLib.resolve(process.cwd(), p.trim())),
process.cwd(), process.cwd(),
) )
.action(options => { .action(options => {

View file

@ -7,6 +7,7 @@ const { QueryService } = require('../../services/QueryService.js');
const { ReportService } = require('../../services/ReportService.js'); const { ReportService } = require('../../services/ReportService.js');
const { InputDataService } = require('../../services/InputDataService.js'); const { InputDataService } = require('../../services/InputDataService.js');
const { aForEach } = require('../../utils/async-array-utils.js'); const { aForEach } = require('../../utils/async-array-utils.js');
const { toPosixPath } = require('../../utils/to-posix-path.js');
const { getFilePathRelativeFromRoot } = require('../../utils/get-file-path-relative-from-root.js'); const { getFilePathRelativeFromRoot } = require('../../utils/get-file-path-relative-from-root.js');
/** /**
@ -27,6 +28,29 @@ async function analyzePerAstEntry(projectData, astAnalysis) {
return filteredEntries; return filteredEntries;
} }
/**
* Transforms QueryResult entries to posix path notations on Windows
* @param {array|object} data
*/
function posixify(data) {
if (!data) {
return;
}
if (Array.isArray(data)) {
data.forEach(posixify);
} else if (typeof data === 'object') {
Object.entries(data).forEach(([k, v]) => {
if (Array.isArray(v) || typeof v === 'object') {
posixify(v);
}
// TODO: detect whether filePath instead of restricting by key name?
else if (typeof v === 'string' && k === 'file') {
data[k] = toPosixPath(v);
}
});
}
}
/** /**
* @desc This method ensures that the result returned by an analyzer always has a consistent format. * @desc This method ensures that the result returned by an analyzer always has a consistent format.
* By returning the configuration for the queryOutput, it will be possible to run later queries * By returning the configuration for the queryOutput, it will be possible to run later queries
@ -81,6 +105,11 @@ function ensureAnalyzerResultFormat(queryOutput, configuration, analyzer) {
} }
}); });
} }
if (process.platform === 'win32') {
posixify(aResult);
}
return aResult; return aResult;
} }

View file

@ -6,6 +6,7 @@ const {
} = require('../../utils/relative-source-path.js'); } = require('../../utils/relative-source-path.js');
const { resolveImportPath } = require('../../utils/resolve-import-path.js'); const { resolveImportPath } = require('../../utils/resolve-import-path.js');
const { aMap } = require('../../utils/async-array-utils.js'); const { aMap } = require('../../utils/async-array-utils.js');
const { toPosixPath } = require('../../utils/to-posix-path.js');
function toLocalPath(currentDirPath, resolvedPath) { function toLocalPath(currentDirPath, resolvedPath) {
let relativeSourcePath = pathLib.relative(currentDirPath, resolvedPath); let relativeSourcePath = pathLib.relative(currentDirPath, resolvedPath);
@ -15,7 +16,7 @@ function toLocalPath(currentDirPath, resolvedPath) {
// so 'my-local-files.js' -> './my-local-files.js' // so 'my-local-files.js' -> './my-local-files.js'
relativeSourcePath = `./${relativeSourcePath}`; relativeSourcePath = `./${relativeSourcePath}`;
} }
return relativeSourcePath; return toPosixPath(relativeSourcePath);
} }
/** /**

View file

@ -4,6 +4,7 @@ require('../types/index.js');
const fs = require('fs'); const fs = require('fs');
const pathLib = require('path'); const pathLib = require('path');
const child_process = require('child_process'); // eslint-disable-line camelcase const child_process = require('child_process'); // eslint-disable-line camelcase
const glob = require('glob'); const glob = require('glob');
const anymatch = require('anymatch'); const anymatch = require('anymatch');
@ -11,6 +12,7 @@ const isNegatedGlob = require('is-negated-glob');
const { LogService } = require('./LogService.js'); const { LogService } = require('./LogService.js');
const { AstService } = require('./AstService.js'); const { AstService } = require('./AstService.js');
const { getFilePathRelativeFromRoot } = require('../utils/get-file-path-relative-from-root.js'); const { getFilePathRelativeFromRoot } = require('../utils/get-file-path-relative-from-root.js');
const { toPosixPath } = require('../utils/to-posix-path.js');
function getGitignoreFile(rootPath) { function getGitignoreFile(rootPath) {
try { try {
@ -39,7 +41,7 @@ function getGitIgnorePaths(rootPath) {
// normalize entries to be compatible with anymatch // normalize entries to be compatible with anymatch
const normalizedEntries = entries.map(e => { const normalizedEntries = entries.map(e => {
let entry = e; let entry = toPosixPath(e);
if (entry.startsWith('/')) { if (entry.startsWith('/')) {
entry = entry.slice(1); entry = entry.slice(1);
@ -87,11 +89,11 @@ function ensureArray(v) {
return Array.isArray(v) ? v : [v]; return Array.isArray(v) ? v : [v];
} }
function multiGlobSync(patterns, { keepDirs = false } = {}) { function multiGlobSync(patterns, { keepDirs = false, root } = {}) {
patterns = ensureArray(patterns); patterns = ensureArray(patterns);
const res = new Set(); const res = new Set();
patterns.forEach(pattern => { patterns.forEach(pattern => {
const files = glob.sync(pattern); const files = glob.sync(pattern, { root });
files.forEach(filePath => { files.forEach(filePath => {
if (fs.lstatSync(filePath).isDirectory() && !keepDirs) { if (fs.lstatSync(filePath).isDirectory() && !keepDirs) {
return; return;
@ -211,7 +213,10 @@ class InputDataService {
const newEntries = []; const newEntries = [];
projectObj.entries.forEach(entry => { projectObj.entries.forEach(entry => {
const code = fs.readFileSync(entry, 'utf8'); const code = fs.readFileSync(entry, 'utf8');
const file = getFilePathRelativeFromRoot(entry, projectObj.project.path); const file = getFilePathRelativeFromRoot(
toPosixPath(entry),
toPosixPath(projectObj.project.path),
);
if (pathLib.extname(file) === '.html') { if (pathLib.extname(file) === '.html') {
const extractedScripts = AstService.getScriptsFromHtml(code); const extractedScripts = AstService.getScriptsFromHtml(code);
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
@ -223,7 +228,7 @@ class InputDataService {
} }
}); });
const project = this.getProjectMeta(projectObj.project.path); const project = this.getProjectMeta(toPosixPath(projectObj.project.path));
return { project, entries: newEntries }; return { project, entries: newEntries };
}); });
@ -289,6 +294,11 @@ class InputDataService {
static getGlobPattern(startPath, cfg, withoutDepth = false) { static getGlobPattern(startPath, cfg, withoutDepth = false) {
// if startPath ends with '/', remove // if startPath ends with '/', remove
let globPattern = startPath.replace(/\/$/, ''); let globPattern = startPath.replace(/\/$/, '');
// let globPattern = '';
if (process.platform === 'win32') {
// root = root.replace(/^.\:/, '').replace(/\\/g, '/');
globPattern = globPattern.replace(/^.:/, '').replace(/\\/g, '/');
}
if (!withoutDepth) { if (!withoutDepth) {
if (cfg.depth !== Infinity) { if (cfg.depth !== Infinity) {
globPattern += `/*`.repeat(cfg.depth + 1); globPattern += `/*`.repeat(cfg.depth + 1);
@ -296,7 +306,8 @@ class InputDataService {
globPattern += `/**/*`; globPattern += `/**/*`;
} }
} }
return globPattern; // globPattern = globPattern.slice(1)
return { globPattern };
} }
/** /**
@ -350,14 +361,14 @@ class InputDataService {
} }
}); });
let globPattern = this.getGlobPattern(startPath, cfg); let { globPattern } = this.getGlobPattern(startPath, cfg);
globPattern += `.{${cfg.extensions.map(e => e.slice(1)).join(',')},}`; globPattern += `.{${cfg.extensions.map(e => e.slice(1)).join(',')},}`;
const globRes = multiGlobSync(globPattern); const globRes = multiGlobSync(globPattern);
let filteredGlobRes; let filteredGlobRes;
if (removeFilter.length || keepFilter.length) { if (removeFilter.length || keepFilter.length) {
filteredGlobRes = globRes.filter(filePath => { filteredGlobRes = globRes.filter(filePath => {
const localFilePath = filePath.replace(`${startPath}/`, ''); const localFilePath = toPosixPath(filePath).replace(`${toPosixPath(startPath)}/`, '');
let shouldRemove = removeFilter.length && anymatch(removeFilter, localFilePath); let shouldRemove = removeFilter.length && anymatch(removeFilter, localFilePath);
let shouldKeep = keepFilter.length && anymatch(keepFilter, localFilePath); let shouldKeep = keepFilter.length && anymatch(keepFilter, localFilePath);
@ -382,10 +393,14 @@ class InputDataService {
return shouldKeep; return shouldKeep;
}); });
} }
if (!filteredGlobRes || !filteredGlobRes.length) { if (!filteredGlobRes || !filteredGlobRes.length) {
LogService.warn(`No files found for path '${startPath}'`); LogService.warn(`No files found for path '${startPath}'`);
} }
return filteredGlobRes;
// reappend startPath
// const res = filteredGlobRes.map(f => pathLib.resolve(startPath, f));
return filteredGlobRes.map(toPosixPath);
} }
/** /**

View file

@ -1,3 +1,5 @@
const { toPosixPath } = require('./to-posix-path.js');
/** /**
* @desc determines for a source path of an import- or export specifier, whether * @desc determines for a source path of an import- or export specifier, whether
* it is relative (an internal import/export) or absolute (external) * it is relative (an internal import/export) or absolute (external)
@ -18,7 +20,7 @@ function isRelativeSourcePath(source) {
* @param {string} rootPath like '/path/to/repo' * @param {string} rootPath like '/path/to/repo'
*/ */
function toRelativeSourcePath(fullPath, rootPath) { function toRelativeSourcePath(fullPath, rootPath) {
return fullPath.replace(rootPath, '.'); return toPosixPath(fullPath).replace(rootPath, '.');
} }
module.exports = { isRelativeSourcePath, toRelativeSourcePath }; module.exports = { isRelativeSourcePath, toRelativeSourcePath };

View file

@ -0,0 +1,12 @@
/**
* @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;
}
module.exports = { toPosixPath };

View file

@ -21,6 +21,7 @@ const extendDocsModule = require('../../src/cli/generate-extend-docs-data.js');
const cliHelpersModule = require('../../src/cli/cli-helpers.js'); const cliHelpersModule = require('../../src/cli/cli-helpers.js');
const { cli } = require('../../src/cli/cli.js'); const { cli } = require('../../src/cli/cli.js');
const promptAnalyzerModule = require('../../src/cli/prompt-analyzer-menu.js'); const promptAnalyzerModule = require('../../src/cli/prompt-analyzer-menu.js');
const { toPosixPath } = require('../../src/program/utils/to-posix-path.js');
const { const {
pathsArrayFromCs, pathsArrayFromCs,
@ -29,7 +30,8 @@ const {
} = cliHelpersModule; } = cliHelpersModule;
const queryResults = []; const queryResults = [];
const rootDir = pathLib.resolve(__dirname, '../../');
const rootDir = toPosixPath(pathLib.resolve(__dirname, '../../'));
const externalCfgMock = { const externalCfgMock = {
searchTargetCollections: { searchTargetCollections: {
@ -429,7 +431,7 @@ describe('CLI helpers', () => {
pathsArrayFromCollectionName('lion-collection', 'search-target', externalCfgMock, rootDir), pathsArrayFromCollectionName('lion-collection', 'search-target', externalCfgMock, rootDir),
).to.eql( ).to.eql(
externalCfgMock.searchTargetCollections['lion-collection'].map(p => externalCfgMock.searchTargetCollections['lion-collection'].map(p =>
pathLib.join(rootDir, p), toPosixPath(pathLib.join(rootDir, p)),
), ),
); );
}); });
@ -444,7 +446,7 @@ describe('CLI helpers', () => {
), ),
).to.eql( ).to.eql(
externalCfgMock.referenceCollections['lion-based-ui-collection'].map(p => externalCfgMock.referenceCollections['lion-based-ui-collection'].map(p =>
pathLib.join(rootDir, p), toPosixPath(pathLib.join(rootDir, p)),
), ),
); );
}); });