From d214864b666d3551fe25a648b82832fcbd241b2e Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Wed, 29 May 2019 20:53:08 +0200 Subject: Allow PathProbe to search multiple files Change-Id: I6ae2dd130cbafb03e51bc6e8e8a3e262d6d45fc6 Reviewed-by: Qbs CI Bot Reviewed-by: Christian Kandeler --- share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs | 19 ++-- share/qbs/imports/qbs/Probes/NpmProbe.qbs | 18 ++-- share/qbs/imports/qbs/Probes/PathProbe.qbs | 12 ++- share/qbs/imports/qbs/Probes/TypeScriptProbe.qbs | 14 +-- share/qbs/imports/qbs/Probes/path-probe.js | 110 +++++++++++++++++------ 5 files changed, 119 insertions(+), 54 deletions(-) (limited to 'share/qbs') diff --git a/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs b/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs index 6ebaff8be..e0ca3e654 100644 --- a/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs +++ b/share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs @@ -47,14 +47,17 @@ BinaryProbe { } configure: { - var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, searchPaths, - pathSuffixes, platformSearchPaths, environmentPaths, - platformEnvironmentPaths, pathListSeparator); - found = result.found; - candidatePaths = result.candidatePaths; - path = result.path; - filePath = result.filePath; - fileName = result.fileName; + var selectors; + var _results = PathProbeConfigure.configure( + selectors, names, nameSuffixes, nameFilter, searchPaths, pathSuffixes, + platformSearchPaths, environmentPaths, platformEnvironmentPaths, + pathListSeparator); + found = _results.found; + var resultFile = _results.files[0]; + candidatePaths = resultFile.candidatePaths; + path = resultFile.path; + filePath = resultFile.filePath; + fileName = resultFile.fileName; (nameSuffixes || [""]).forEach(function(suffix) { var end = _compilerName + suffix; if (fileName.endsWith(end)) diff --git a/share/qbs/imports/qbs/Probes/NpmProbe.qbs b/share/qbs/imports/qbs/Probes/NpmProbe.qbs index 4e8124d56..d0a77b421 100644 --- a/share/qbs/imports/qbs/Probes/NpmProbe.qbs +++ b/share/qbs/imports/qbs/Probes/NpmProbe.qbs @@ -47,26 +47,28 @@ NodeJsProbe { if (!interpreterPath) throw '"interpreterPath" must be specified'; - var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, searchPaths, - pathSuffixes, platformSearchPaths, - environmentPaths, platformEnvironmentPaths, - pathListSeparator); + var selectors; + var results = PathProbeConfigure.configure( + selectors, names, nameSuffixes, nameFilter, searchPaths, pathSuffixes, + platformSearchPaths, environmentPaths, platformEnvironmentPaths, + pathListSeparator); var v = new ModUtils.EnvironmentVariable("PATH", pathListSeparator, hostOS.contains("windows")); v.prepend(interpreterPath); - result.npmBin = result.found + var result = results.files[0]; + result.npmBin = results.found ? NodeJs.findLocation(result.filePath, "bin", v.value) : undefined; - result.npmRoot = result.found + result.npmRoot = results.found ? NodeJs.findLocation(result.filePath, "root", v.value) : undefined; - result.npmPrefix = result.found + result.npmPrefix = results.found ? NodeJs.findLocation(result.filePath, "prefix", v.value) : undefined; - found = result.found; + found = results.found; candidatePaths = result.candidatePaths; path = result.path; filePath = result.filePath; diff --git a/share/qbs/imports/qbs/Probes/PathProbe.qbs b/share/qbs/imports/qbs/Probes/PathProbe.qbs index 1235ce211..42e3a45d4 100644 --- a/share/qbs/imports/qbs/Probes/PathProbe.qbs +++ b/share/qbs/imports/qbs/Probes/PathProbe.qbs @@ -36,6 +36,7 @@ Probe { property stringList names property stringList nameSuffixes property var nameFilter + property varList selectors property pathList pathPrefixes property pathList searchPaths property stringList pathSuffixes @@ -52,6 +53,8 @@ Probe { property string filePath property string fileName + property varList allResults + configure: { if (pathPrefixes) console.warn("PathProbe.pathPrefixes is deprecated, use searchPaths instead"); @@ -59,11 +62,14 @@ Probe { console.warn("PathProbe.platformPaths is deprecated, use platformSearchPaths instead"); var _searchPaths = ModUtils.concatAll(pathPrefixes, searchPaths); var _platformSearchPaths = ModUtils.concatAll(platformPaths, platformSearchPaths); - var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, _searchPaths, - pathSuffixes, _platformSearchPaths, + var results = PathProbeConfigure.configure(selectors, names, nameSuffixes, nameFilter, + _searchPaths, pathSuffixes, _platformSearchPaths, environmentPaths, platformEnvironmentPaths, pathListSeparator); - found = result.found; + found = results.found; + allResults = results.files; + + var result = allResults[0]; candidatePaths = result.candidatePaths; path = result.path; filePath = result.filePath; diff --git a/share/qbs/imports/qbs/Probes/TypeScriptProbe.qbs b/share/qbs/imports/qbs/Probes/TypeScriptProbe.qbs index de28fa327..5696b78c8 100644 --- a/share/qbs/imports/qbs/Probes/TypeScriptProbe.qbs +++ b/share/qbs/imports/qbs/Probes/TypeScriptProbe.qbs @@ -57,16 +57,18 @@ BinaryProbe { if (!packageManagerRootPath) throw '"packageManagerRootPath" must be specified'; - var result = PathProbeConfigure.configure(names, nameSuffixes, nameFilter, searchPaths, - pathSuffixes, platformSearchPaths, - environmentPaths, platformEnvironmentPaths, - pathListSeparator); + var selectors; + var results = PathProbeConfigure.configure( + selectors, names, nameSuffixes, nameFilter, searchPaths, pathSuffixes, + platformSearchPaths, environmentPaths, platformEnvironmentPaths, + pathListSeparator); var v = new ModUtils.EnvironmentVariable("PATH", pathListSeparator, hostOS.contains("windows")); v.prepend(interpreterPath); - result.version = result.found + var result = results.files[0]; + result.version = results.found ? TypeScript.findTscVersion(result.filePath, v.value) : undefined; if (FileInfo.fromNativeSeparators(packageManagerBinPath) !== result.path || @@ -74,7 +76,7 @@ BinaryProbe { result = { found: false }; } - found = result.found; + found = results.found; candidatePaths = result.candidatePaths; path = result.path; filePath = result.filePath; diff --git a/share/qbs/imports/qbs/Probes/path-probe.js b/share/qbs/imports/qbs/Probes/path-probe.js index a48a7e4fe..9e338712f 100644 --- a/share/qbs/imports/qbs/Probes/path-probe.js +++ b/share/qbs/imports/qbs/Probes/path-probe.js @@ -33,17 +33,60 @@ var File = require("qbs.File"); var FileInfo = require("qbs.FileInfo"); var ModUtils = require("qbs.ModUtils"); -function configure(names, nameSuffixes, nameFilter, searchPaths, pathSuffixes, platformSearchPaths, - environmentPaths, platformEnvironmentPaths, pathListSeparator) { - var result = { found: false, candidatePaths: [] }; - if (!names) - throw '"names" must be specified'; - var _names = ModUtils.concatAll(names); - if (nameFilter) - _names = _names.map(function(n) { return nameFilter(n); }); - _names = ModUtils.concatAll.apply(undefined, _names.map(function(name) { - return (nameSuffixes || [""]).map(function(suffix) { return name + suffix; }); - })); +function asStringList(key, value) { + if (typeof(value) === "string") + return [value]; + if (Array.isArray(value)) + return value; + throw key + " must be a string or a stringList"; +} + +function canonicalSelectors(selectors) { + var mapper = function(selector) { + if (typeof(selector) === "string") + return {names : [selector]}; + if (Array.isArray(selector)) + return {names : selector}; + // dict + if (!selector.names) + throw '"names" must be specified'; + selector.names = asStringList("names", selector.names); + if (selector.nameSuffixes) + selector.nameSuffixes = asStringList("nameSuffixes", selector.nameSuffixes); + return selector; + }; + return selectors.map(mapper); +} + +function configure(selectors, names, nameSuffixes, nameFilter, searchPaths, pathSuffixes, + platformSearchPaths, environmentPaths, platformEnvironmentPaths, + pathListSeparator) { + var result = { found: false, files: [] }; + if (!selectors && !names) + throw '"names" or "selectors" must be specified'; + + if (!selectors) { + selectors = [ + {names: names, nameSuffixes: nameSuffixes} + ]; + } else { + selectors = canonicalSelectors(selectors); + } + + if (nameFilter) { + selectors.forEach(function(selector) { + selector.names = selector.names.map(nameFilter); + }); + } + + selectors.forEach(function(selector) { + selector.names = ModUtils.concatAll.apply(undefined, selector.names.map(function(name) { + return (selector.nameSuffixes || [""]).map(function(suffix) { + return name + suffix; + }); + })); + }); + // FIXME: Suggest how to obtain paths from system var _paths = ModUtils.concatAll(searchPaths, platformSearchPaths); // FIXME: Add getenv support @@ -56,28 +99,37 @@ function configure(names, nameSuffixes, nameFilter, searchPaths, pathSuffixes, p var _suffixes = ModUtils.concatAll('', pathSuffixes); _paths = _paths.map(function(p) { return FileInfo.fromNativeSeparators(p); }); _suffixes = _suffixes.map(function(p) { return FileInfo.fromNativeSeparators(p); }); - for (i = 0; i < _names.length; ++i) { - for (var j = 0; j < _paths.length; ++j) { - for (var k = 0; k < _suffixes.length; ++k) { - var _filePath = FileInfo.joinPaths(_paths[j], _suffixes[k], _names[i]); - result.candidatePaths.push(_filePath); - if (File.exists(_filePath)) { - result.found = true; - result.filePath = _filePath; - // Manually specify the path components that constitute _filePath rather - // than using the FileInfo.path and FileInfo.fileName functions because we - // want to break _filePath into its constituent parts based on the input - // originally given by the user. For example, the FileInfo functions would - // produce a different result if any of the items in the names property - // contained more than a single path component. - result.fileName = _names[i]; - result.path = FileInfo.joinPaths(_paths[j], _suffixes[k]); - return result; + var findFile = function(selector) { + var file = { found: false, candidatePaths: [] }; + for (var i = 0; i < selector.names.length; ++i) { + for (var j = 0; j < _paths.length; ++j) { + for (var k = 0; k < _suffixes.length; ++k) { + var _filePath = FileInfo.joinPaths(_paths[j], _suffixes[k], selector.names[i]); + file.candidatePaths.push(_filePath); + if (File.exists(_filePath)) { + file.found = true; + file.filePath = _filePath; + + // Manually specify the path components that constitute _filePath rather + // than using the FileInfo.path and FileInfo.fileName functions because we + // want to break _filePath into its constituent parts based on the input + // originally given by the user. For example, the FileInfo functions would + // produce a different result if any of the items in the names property + // contained more than a single path component. + file.fileName = selector.names[i]; + file.path = FileInfo.joinPaths(_paths[j], _suffixes[k]); + return file; + } } } } - } + + return file; + }; + + result.files = selectors.map(findFile); + result.found = result.files.reduce(function(acc, value) { return acc && value.found }, true); return result; } -- cgit v1.2.3