aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Komissarov <ABBAPOH@gmail.com>2019-05-29 20:53:08 +0200
committerIvan Komissarov <ABBAPOH@gmail.com>2019-06-25 17:01:11 +0000
commitd214864b666d3551fe25a648b82832fcbd241b2e (patch)
tree855d473b8b8f8ccb5dbed42fed1410777ad6f5ad
parent636ee64eea7461e09070b34ec80ee193dd46767f (diff)
Allow PathProbe to search multiple files
Change-Id: I6ae2dd130cbafb03e51bc6e8e8a3e262d6d45fc6 Reviewed-by: Qbs CI Bot <travis-bot@weickelt.de> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--doc/reference/items/probe/path-probe.qdoc41
-rw-r--r--share/qbs/imports/qbs/Probes/GccBinaryProbe.qbs19
-rw-r--r--share/qbs/imports/qbs/Probes/NpmProbe.qbs18
-rw-r--r--share/qbs/imports/qbs/Probes/PathProbe.qbs12
-rw-r--r--share/qbs/imports/qbs/Probes/TypeScriptProbe.qbs14
-rw-r--r--share/qbs/imports/qbs/Probes/path-probe.js110
-rw-r--r--tests/auto/blackbox/testdata/path-probe/BaseApp.qbs74
-rw-r--r--tests/auto/blackbox/testdata/path-probe/bin/super-tool.10
-rw-r--r--tests/auto/blackbox/testdata/path-probe/bin/tool0
-rw-r--r--tests/auto/blackbox/testdata/path-probe/bin/tool.10
-rw-r--r--tests/auto/blackbox/testdata/path-probe/bin/tool.20
-rw-r--r--tests/auto/blackbox/testdata/path-probe/bin/tool.30
-rw-r--r--tests/auto/blackbox/testdata/path-probe/bin/tool.40
-rw-r--r--tests/auto/blackbox/testdata/path-probe/main.cpp1
-rw-r--r--tests/auto/blackbox/testdata/path-probe/mult-files-mult-suffixes.qbs8
-rw-r--r--tests/auto/blackbox/testdata/path-probe/mult-files-mult-variants.qbs9
-rw-r--r--tests/auto/blackbox/testdata/path-probe/mult-files-suffixes.qbs8
-rw-r--r--tests/auto/blackbox/testdata/path-probe/mult-files.qbs10
-rw-r--r--tests/auto/blackbox/testdata/path-probe/name-filter.qbs10
-rw-r--r--tests/auto/blackbox/testdata/path-probe/non-existent-selector.qbs8
-rw-r--r--tests/auto/blackbox/testdata/path-probe/non-existent.qbs4
-rw-r--r--tests/auto/blackbox/testdata/path-probe/single-file-mult-variants.qbs5
-rw-r--r--tests/auto/blackbox/testdata/path-probe/single-file-selector-array.qbs5
-rw-r--r--tests/auto/blackbox/testdata/path-probe/single-file-selector.qbs5
-rw-r--r--tests/auto/blackbox/testdata/path-probe/single-file-suffixes.qbs6
-rw-r--r--tests/auto/blackbox/testdata/path-probe/single-file.qbs5
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp30
-rw-r--r--tests/auto/blackbox/tst_blackbox.h2
28 files changed, 348 insertions, 56 deletions
diff --git a/doc/reference/items/probe/path-probe.qdoc b/doc/reference/items/probe/path-probe.qdoc
index 298ce9d95..5b0cc1bb6 100644
--- a/doc/reference/items/probe/path-probe.qdoc
+++ b/doc/reference/items/probe/path-probe.qdoc
@@ -58,6 +58,23 @@
*/
/*!
+ \qmlproperty varList PathProbe::allResults
+
+ This property contains the list of objects, each object representing a single found file:
+ \code
+ {
+ found: true,
+ candidatePaths: ["path1/to/file", "path2/to/file", ...]
+ filePath: "path/to/file"
+ fileName: "file"
+ path: "path/to"
+ }
+ \endcode
+ \sa {PathProbe::filePath}{filePath}, {PathProbe::fileName}{fileName},
+ {PathProbe::path}{path}
+*/
+
+/*!
\qmlproperty stringList PathProbe::names
The list of file names to search for.
@@ -69,8 +86,7 @@
\qmlproperty stringList PathProbe::nameSuffixes
The list of file suffixes to search for. These suffixes are appended to every file name passed
- via the \l names property. If \l names is empty, the probe looks for any file that ends with the
- given suffix.
+ via the \l names property.
\nodefaultvalue
*/
@@ -161,3 +177,24 @@
\nodefaultvalue
*/
+
+/*!
+ \qmlproperty varList PathProbe::selectors
+
+ This property should be used to search for multiple files. It contains the list of selectors
+ each of which describes a single file to search for. A selector can be either a string, a
+ stringList, or a dictionary.
+
+ The following example searches for three files and illustrates different ways to specify
+ selectors:
+ \code
+ selectors: [
+ // 1st file with a single name
+ "header.h",
+ // 2nd file with possible name variants
+ ["config.h", "foo-config.h", "bar-config.h"],
+ // 3rd file with possible name and suffix variants
+ {names: ["footk", "footk-version"], nameSuffixes: [".h", ".hpp"]}
+ ]
+ \endcode
+*/
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;
}
diff --git a/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs b/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs
new file mode 100644
index 000000000..944a95a93
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/BaseApp.qbs
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Ivan Komissarov (abbapoh@gmail.com).
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs.Probes
+
+CppApplication {
+
+ property varList inputSelectors
+ property varList inputNames
+ property varList inputNameSuffixes
+ property pathList inputSearchPaths
+ property var inputNameFilter
+
+ property stringList outputFilePaths
+
+ Probes.PathProbe {
+ id: probe
+ selectors: inputSelectors
+ names: inputNames
+ nameSuffixes: inputNameSuffixes
+ nameFilter: inputNameFilter
+ searchPaths: inputSearchPaths
+ }
+
+ property bool validate: {
+ var compareArrays = function(lhs, rhs) {
+ if (lhs.length !== rhs.length)
+ return false;
+ for (var i = 0; i < lhs.length; ++i) {
+ if (lhs[i] !== rhs[i])
+ return false;
+ }
+ return true;
+ };
+
+ if (!probe.found)
+ throw "Probe failed to find files";
+
+ if (outputFilePaths) {
+ var actual = probe.allResults.map(function(file) { return file.filePath; });
+ if (!compareArrays(actual, outputFilePaths))
+ throw "Invalid filePaths: actual = " + actual + ", expected = " + outputFilePaths;
+ }
+ }
+
+ files: ["main.cpp"]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/bin/super-tool.1 b/tests/auto/blackbox/testdata/path-probe/bin/super-tool.1
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/bin/super-tool.1
diff --git a/tests/auto/blackbox/testdata/path-probe/bin/tool b/tests/auto/blackbox/testdata/path-probe/bin/tool
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/bin/tool
diff --git a/tests/auto/blackbox/testdata/path-probe/bin/tool.1 b/tests/auto/blackbox/testdata/path-probe/bin/tool.1
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/bin/tool.1
diff --git a/tests/auto/blackbox/testdata/path-probe/bin/tool.2 b/tests/auto/blackbox/testdata/path-probe/bin/tool.2
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/bin/tool.2
diff --git a/tests/auto/blackbox/testdata/path-probe/bin/tool.3 b/tests/auto/blackbox/testdata/path-probe/bin/tool.3
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/bin/tool.3
diff --git a/tests/auto/blackbox/testdata/path-probe/bin/tool.4 b/tests/auto/blackbox/testdata/path-probe/bin/tool.4
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/bin/tool.4
diff --git a/tests/auto/blackbox/testdata/path-probe/main.cpp b/tests/auto/blackbox/testdata/path-probe/main.cpp
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/main.cpp
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/tests/auto/blackbox/testdata/path-probe/mult-files-mult-suffixes.qbs b/tests/auto/blackbox/testdata/path-probe/mult-files-mult-suffixes.qbs
new file mode 100644
index 000000000..b112db44d
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/mult-files-mult-suffixes.qbs
@@ -0,0 +1,8 @@
+BaseApp {
+ inputSelectors: [
+ {names : "tool", nameSuffixes: [".1", ".2"]},
+ {names : "super-tool", nameSuffixes: [".1"]},
+ ]
+ inputSearchPaths: "bin"
+ outputFilePaths: ["bin/tool.1", "bin/super-tool.1"]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/mult-files-mult-variants.qbs b/tests/auto/blackbox/testdata/path-probe/mult-files-mult-variants.qbs
new file mode 100644
index 000000000..60c56e6b4
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/mult-files-mult-variants.qbs
@@ -0,0 +1,9 @@
+BaseApp {
+ inputSelectors: [
+ "tool",
+ ["tool.1", "tool.2"],
+ {names : ["tool.3", "tool.4"]},
+ ]
+ inputSearchPaths: "bin"
+ outputFilePaths: ["bin/tool", "bin/tool.1", "bin/tool.3"]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/mult-files-suffixes.qbs b/tests/auto/blackbox/testdata/path-probe/mult-files-suffixes.qbs
new file mode 100644
index 000000000..5e4fc27ca
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/mult-files-suffixes.qbs
@@ -0,0 +1,8 @@
+BaseApp {
+ inputSelectors: [
+ {names : "tool", nameSuffixes: ".2"},
+ {names : "super-tool", nameSuffixes: ".1"},
+ ]
+ inputSearchPaths: "bin"
+ outputFilePaths: ["bin/tool.2", "bin/super-tool.1"]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/mult-files.qbs b/tests/auto/blackbox/testdata/path-probe/mult-files.qbs
new file mode 100644
index 000000000..08727ac01
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/mult-files.qbs
@@ -0,0 +1,10 @@
+BaseApp {
+ inputSelectors: [
+ "tool.1",
+ ["tool.2"],
+ {names : "tool.3"},
+ {names : ["tool.4"]}
+ ]
+ inputSearchPaths: "bin"
+ outputFilePaths: ["bin/tool.1", "bin/tool.2", "bin/tool.3", "bin/tool.4"]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/name-filter.qbs b/tests/auto/blackbox/testdata/path-probe/name-filter.qbs
new file mode 100644
index 000000000..406988fed
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/name-filter.qbs
@@ -0,0 +1,10 @@
+BaseApp {
+ inputNames: "tool"
+ inputSearchPaths: "bin"
+ inputNameFilter: {
+ return function(n) {
+ return n + ".2"
+ };
+ }
+ outputFilePaths: ["bin/tool.2"]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/non-existent-selector.qbs b/tests/auto/blackbox/testdata/path-probe/non-existent-selector.qbs
new file mode 100644
index 000000000..aaa27042c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/non-existent-selector.qbs
@@ -0,0 +1,8 @@
+BaseApp {
+ inputSelectors: [
+ "tool.1",
+ "nonexistent",
+ "tool.2",
+ ]
+ inputSearchPaths: "bin"
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/non-existent.qbs b/tests/auto/blackbox/testdata/path-probe/non-existent.qbs
new file mode 100644
index 000000000..f0c58fa6c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/non-existent.qbs
@@ -0,0 +1,4 @@
+BaseApp {
+ inputNames: "nonexistent"
+ inputSearchPaths: "bin"
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/single-file-mult-variants.qbs b/tests/auto/blackbox/testdata/path-probe/single-file-mult-variants.qbs
new file mode 100644
index 000000000..992a0bea4
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/single-file-mult-variants.qbs
@@ -0,0 +1,5 @@
+BaseApp {
+ inputNames: ["tool.1", "tool.2"]
+ inputSearchPaths: "bin"
+ outputFilePaths: ["bin/tool.1"]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/single-file-selector-array.qbs b/tests/auto/blackbox/testdata/path-probe/single-file-selector-array.qbs
new file mode 100644
index 000000000..697665242
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/single-file-selector-array.qbs
@@ -0,0 +1,5 @@
+BaseApp {
+ inputSelectors: ["tool"]
+ inputSearchPaths: "bin"
+ outputFilePaths: ["bin/tool"]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/single-file-selector.qbs b/tests/auto/blackbox/testdata/path-probe/single-file-selector.qbs
new file mode 100644
index 000000000..d57700baf
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/single-file-selector.qbs
@@ -0,0 +1,5 @@
+BaseApp {
+ inputSelectors: "tool"
+ inputSearchPaths: "bin"
+ outputFilePaths: ["bin/tool"]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/single-file-suffixes.qbs b/tests/auto/blackbox/testdata/path-probe/single-file-suffixes.qbs
new file mode 100644
index 000000000..4442e719a
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/single-file-suffixes.qbs
@@ -0,0 +1,6 @@
+BaseApp {
+ inputNames: "tool"
+ inputSearchPaths: "bin"
+ inputNameSuffixes: [".1", ".2"]
+ outputFilePaths: ["bin/tool.1"]
+}
diff --git a/tests/auto/blackbox/testdata/path-probe/single-file.qbs b/tests/auto/blackbox/testdata/path-probe/single-file.qbs
new file mode 100644
index 000000000..3590e7664
--- /dev/null
+++ b/tests/auto/blackbox/testdata/path-probe/single-file.qbs
@@ -0,0 +1,5 @@
+BaseApp {
+ inputNames: "tool"
+ inputSearchPaths: "bin"
+ outputFilePaths: ["bin/tool"]
+}
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 84322a7c7..c6acffcc9 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -2719,6 +2719,36 @@ void TestBlackbox::overrideProjectProperties()
QCOMPARE(runQbs(params), 0);
}
+void TestBlackbox::pathProbe_data()
+{
+ QTest::addColumn<QString>("projectFile");
+ QTest::addColumn<bool>("successExpected");
+ QTest::newRow("non-existent") << QString("non-existent.qbs") << false;
+ QTest::newRow("non-existent-selector.qbs") << QString("non-existent-selector.qbs") << false;
+ QTest::newRow("single-file") << QString("single-file.qbs") << true;
+ QTest::newRow("single-file-selector") << QString("single-file-selector.qbs") << true;
+ QTest::newRow("single-file-selector-array") << QString("single-file-selector-array.qbs") << true;
+ QTest::newRow("single-file-mult-variants") << QString("single-file-mult-variants.qbs") << true;
+ QTest::newRow("mult-files") << QString("mult-files.qbs") << true;
+ QTest::newRow("mult-files-mult-variants") << QString("mult-files-mult-variants.qbs") << true;
+ QTest::newRow("single-file-suffixes") << QString("single-file-suffixes.qbs") << true;
+ QTest::newRow("mult-files-suffixes") << QString("mult-files-suffixes.qbs") << true;
+ QTest::newRow("mult-files-mult-suffixes") << QString("mult-files-mult-suffixes.qbs") << true;
+ QTest::newRow("name-filter") << QString("name-filter.qbs") << true;
+}
+
+void TestBlackbox::pathProbe()
+{
+ QDir::setCurrent(testDataDir + "/path-probe");
+ QFETCH(QString, projectFile);
+ QFETCH(bool, successExpected);
+ rmDirR(relativeBuildDir());
+
+ QbsRunParameters buildParams("build", QStringList{"-f", projectFile});
+ buildParams.expectFailure = !successExpected;
+ QCOMPARE(runQbs(buildParams) == 0, successExpected);
+}
+
void TestBlackbox::pchChangeTracking()
{
QDir::setCurrent(testDataDir + "/pch-change-tracking");
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index 5b3adcbe2..e8c456b1e 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -205,6 +205,8 @@ private slots:
void outOfDateMarking();
void outputArtifactAutoTagging();
void overrideProjectProperties();
+ void pathProbe_data();
+ void pathProbe();
void pchChangeTracking();
void perGroupDefineInExportItem();
void pkgConfigProbe();