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 { LogService } = require('../program/services/LogService.js');
const { aForEach } = require('../program/utils/async-array-utils.js');
const { toPosixPath } = require('../program/utils/to-posix-path.js');
function flatten(arr) {
return Array.prototype.concat.apply([], arr);
@ -47,9 +48,9 @@ function pathsArrayFromCs(t, cwd = process.cwd()) {
// eslint-disable-next-line no-param-reassign
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)).;
// });
return depProjectPaths.concat(rootPaths);
return depProjectPaths.concat(rootPaths).map(toPosixPath);
}
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 cliHelpers = require('./cli-helpers.js');
const extendDocsModule = require('./generate-extend-docs-data.js');
const { toPosixPath } = require('../program/utils/to-posix-path.js');
const { extensionsFromCs, setQueryMethod, targetDefault, installDeps } = cliHelpers;
@ -282,7 +283,7 @@ async function cli({ cwd } = {}) {
.option(
'--output-folder [output-folder]',
`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(),
)
.action(options => {

View file

@ -7,6 +7,7 @@ const { QueryService } = require('../../services/QueryService.js');
const { ReportService } = require('../../services/ReportService.js');
const { InputDataService } = require('../../services/InputDataService.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');
/**
@ -27,6 +28,29 @@ async function analyzePerAstEntry(projectData, astAnalysis) {
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.
* 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;
}

View file

@ -6,6 +6,7 @@ const {
} = require('../../utils/relative-source-path.js');
const { resolveImportPath } = require('../../utils/resolve-import-path.js');
const { aMap } = require('../../utils/async-array-utils.js');
const { toPosixPath } = require('../../utils/to-posix-path.js');
function toLocalPath(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'
relativeSourcePath = `./${relativeSourcePath}`;
}
return relativeSourcePath;
return toPosixPath(relativeSourcePath);
}
/**

View file

@ -4,6 +4,7 @@ require('../types/index.js');
const fs = require('fs');
const pathLib = require('path');
const child_process = require('child_process'); // eslint-disable-line camelcase
const glob = require('glob');
const anymatch = require('anymatch');
@ -11,6 +12,7 @@ const isNegatedGlob = require('is-negated-glob');
const { LogService } = require('./LogService.js');
const { AstService } = require('./AstService.js');
const { getFilePathRelativeFromRoot } = require('../utils/get-file-path-relative-from-root.js');
const { toPosixPath } = require('../utils/to-posix-path.js');
function getGitignoreFile(rootPath) {
try {
@ -39,7 +41,7 @@ function getGitIgnorePaths(rootPath) {
// normalize entries to be compatible with anymatch
const normalizedEntries = entries.map(e => {
let entry = e;
let entry = toPosixPath(e);
if (entry.startsWith('/')) {
entry = entry.slice(1);
@ -87,11 +89,11 @@ function ensureArray(v) {
return Array.isArray(v) ? v : [v];
}
function multiGlobSync(patterns, { keepDirs = false } = {}) {
function multiGlobSync(patterns, { keepDirs = false, root } = {}) {
patterns = ensureArray(patterns);
const res = new Set();
patterns.forEach(pattern => {
const files = glob.sync(pattern);
const files = glob.sync(pattern, { root });
files.forEach(filePath => {
if (fs.lstatSync(filePath).isDirectory() && !keepDirs) {
return;
@ -211,7 +213,10 @@ class InputDataService {
const newEntries = [];
projectObj.entries.forEach(entry => {
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') {
const extractedScripts = AstService.getScriptsFromHtml(code);
// 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 };
});
@ -289,6 +294,11 @@ class InputDataService {
static getGlobPattern(startPath, cfg, withoutDepth = false) {
// if startPath ends with '/', remove
let globPattern = startPath.replace(/\/$/, '');
// let globPattern = '';
if (process.platform === 'win32') {
// root = root.replace(/^.\:/, '').replace(/\\/g, '/');
globPattern = globPattern.replace(/^.:/, '').replace(/\\/g, '/');
}
if (!withoutDepth) {
if (cfg.depth !== Infinity) {
globPattern += `/*`.repeat(cfg.depth + 1);
@ -296,7 +306,8 @@ class InputDataService {
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(',')},}`;
const globRes = multiGlobSync(globPattern);
let filteredGlobRes;
if (removeFilter.length || keepFilter.length) {
filteredGlobRes = globRes.filter(filePath => {
const localFilePath = filePath.replace(`${startPath}/`, '');
const localFilePath = toPosixPath(filePath).replace(`${toPosixPath(startPath)}/`, '');
let shouldRemove = removeFilter.length && anymatch(removeFilter, localFilePath);
let shouldKeep = keepFilter.length && anymatch(keepFilter, localFilePath);
@ -382,10 +393,14 @@ class InputDataService {
return shouldKeep;
});
}
if (!filteredGlobRes || !filteredGlobRes.length) {
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
* it is relative (an internal import/export) or absolute (external)
@ -18,7 +20,7 @@ function isRelativeSourcePath(source) {
* @param {string} rootPath like '/path/to/repo'
*/
function toRelativeSourcePath(fullPath, rootPath) {
return fullPath.replace(rootPath, '.');
return toPosixPath(fullPath).replace(rootPath, '.');
}
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 { cli } = require('../../src/cli/cli.js');
const promptAnalyzerModule = require('../../src/cli/prompt-analyzer-menu.js');
const { toPosixPath } = require('../../src/program/utils/to-posix-path.js');
const {
pathsArrayFromCs,
@ -29,7 +30,8 @@ const {
} = cliHelpersModule;
const queryResults = [];
const rootDir = pathLib.resolve(__dirname, '../../');
const rootDir = toPosixPath(pathLib.resolve(__dirname, '../../'));
const externalCfgMock = {
searchTargetCollections: {
@ -429,7 +431,7 @@ describe('CLI helpers', () => {
pathsArrayFromCollectionName('lion-collection', 'search-target', externalCfgMock, rootDir),
).to.eql(
externalCfgMock.searchTargetCollections['lion-collection'].map(p =>
pathLib.join(rootDir, p),
toPosixPath(pathLib.join(rootDir, p)),
),
);
});
@ -444,7 +446,7 @@ describe('CLI helpers', () => {
),
).to.eql(
externalCfgMock.referenceCollections['lion-based-ui-collection'].map(p =>
pathLib.join(rootDir, p),
toPosixPath(pathLib.join(rootDir, p)),
),
);
});