aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2021-11-02 14:20:46 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-11-04 15:16:34 +0000
commit6403ba67249a414b026950dde2a903fe11d0c5d3 (patch)
tree4d5036783899341b6471566faf740de35a2808e7
parentd121e220f0e7f2be9e2a3d7af04fc36326484d0d (diff)
qmlimportscanner: Prefer directories with qmldir
With the new CMake module API, we often have both the source and the binary dir as an import path, with the qmldir only being available in the binary directory. For deployment to work correctly, we need to pick up the qmldir. Thus, when finding a module both with and without a qmldir in different paths, prefer the version with the qmldir. Change-Id: I12efeae321da60b1b5ffe5c6d950ba486887ceb1 Reviewed-by: Craig Scott <craig.scott@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> (cherry picked from commit 70ecbb690c8caadd18d8932245d6c8332678cf9a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--tests/auto/qml/qmlimportscanner/data/With/Module/A.qml3
-rw-r--r--tests/auto/qml/qmlimportscanner/data/With/Module/qmldir3
-rw-r--r--tests/auto/qml/qmlimportscanner/data/WithOut/Module/A.qml3
-rw-r--r--tests/auto/qml/qmlimportscanner/data/qmldirpref.qml3
-rw-r--r--tests/auto/qml/qmlimportscanner/data/rootPath.json4
-rw-r--r--tests/auto/qml/qmlimportscanner/tst_qmlimportscanner.cpp26
-rw-r--r--tools/qmlimportscanner/main.cpp24
7 files changed, 61 insertions, 5 deletions
diff --git a/tests/auto/qml/qmlimportscanner/data/With/Module/A.qml b/tests/auto/qml/qmlimportscanner/data/With/Module/A.qml
new file mode 100644
index 0000000000..8fc36a40da
--- /dev/null
+++ b/tests/auto/qml/qmlimportscanner/data/With/Module/A.qml
@@ -0,0 +1,3 @@
+import QtQml
+
+QtObject {}
diff --git a/tests/auto/qml/qmlimportscanner/data/With/Module/qmldir b/tests/auto/qml/qmlimportscanner/data/With/Module/qmldir
new file mode 100644
index 0000000000..2338864432
--- /dev/null
+++ b/tests/auto/qml/qmlimportscanner/data/With/Module/qmldir
@@ -0,0 +1,3 @@
+module Module
+
+A 1.0 A.qml
diff --git a/tests/auto/qml/qmlimportscanner/data/WithOut/Module/A.qml b/tests/auto/qml/qmlimportscanner/data/WithOut/Module/A.qml
new file mode 100644
index 0000000000..8fc36a40da
--- /dev/null
+++ b/tests/auto/qml/qmlimportscanner/data/WithOut/Module/A.qml
@@ -0,0 +1,3 @@
+import QtQml
+
+QtObject {}
diff --git a/tests/auto/qml/qmlimportscanner/data/qmldirpref.qml b/tests/auto/qml/qmlimportscanner/data/qmldirpref.qml
new file mode 100644
index 0000000000..d1b1e80329
--- /dev/null
+++ b/tests/auto/qml/qmlimportscanner/data/qmldirpref.qml
@@ -0,0 +1,3 @@
+import Module
+
+A {}
diff --git a/tests/auto/qml/qmlimportscanner/data/rootPath.json b/tests/auto/qml/qmlimportscanner/data/rootPath.json
index 12850aa8bb..fe42646665 100644
--- a/tests/auto/qml/qmlimportscanner/data/rootPath.json
+++ b/tests/auto/qml/qmlimportscanner/data/rootPath.json
@@ -57,5 +57,9 @@
"name": "Imports",
"relativePath": "Imports",
"type": "module"
+ },
+ {
+ "name": "Module",
+ "type": "module"
}
]
diff --git a/tests/auto/qml/qmlimportscanner/tst_qmlimportscanner.cpp b/tests/auto/qml/qmlimportscanner/tst_qmlimportscanner.cpp
index 88a8163961..2d339cc33d 100644
--- a/tests/auto/qml/qmlimportscanner/tst_qmlimportscanner.cpp
+++ b/tests/auto/qml/qmlimportscanner/tst_qmlimportscanner.cpp
@@ -46,6 +46,7 @@ private Q_SLOTS:
void rootPath();
void modules_data();
void modules();
+ void qmldirPreference();
private:
void runQmlimportscanner(const QString &mode, const QString &fileToScan,
@@ -123,6 +124,31 @@ void TestQmlimportscanner::modules()
runQmlimportscanner("-qmlFiles", qmlFile.fileName(), testFile(name + ".json"));
}
+void TestQmlimportscanner::qmldirPreference()
+{
+ // ###
+ QStringList with {u"-importPath"_qs, testFile("With")};
+ QStringList withOut {u"-importPath"_qs, testFile("WithOut")};
+ QStringList genericArgs {u"-qmlFiles"_qs, testFile("qmldirpref.qml"), u"-importPath"_qs,
+ QLibraryInfo::path(QLibraryInfo::QmlImportsPath)};
+
+
+ // found path should not depend on order of importPath arguments
+ QStringList argcombis[2] { genericArgs + with + withOut, genericArgs + withOut + with };
+ for (const auto &allArgs: argcombis) {
+ QProcess process;
+ process.start(m_qmlimportscannerPath, allArgs);
+ QVERIFY(process.waitForFinished());
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ QCOMPARE(process.exitCode(), 0);
+ QVERIFY(process.readAllStandardError().isEmpty());
+ auto output = process.readAllStandardOutput();
+ // check that the "With" path is used, and the "WithOut" path is ignored
+ QVERIFY(output.contains("With/Module"));
+ QVERIFY(!output.contains("WithOut/Module"));
+ }
+}
+
void TestQmlimportscanner::runQmlimportscanner(const QString &mode, const QString &pathToScan,
const QString &resultFile)
{
diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp
index ab26abae46..e9b4577318 100644
--- a/tools/qmlimportscanner/main.cpp
+++ b/tools/qmlimportscanner/main.cpp
@@ -257,6 +257,7 @@ QPair<QString, QString> resolveImportPath(const QString &uri, const QString &ver
const QStringList parts = uri.split(dot, Qt::SkipEmptyParts);
QString ver = version;
+ QPair<QString, QString> candidate;
while (true) {
for (const QString &qmlImportPath : qAsConst(g_qmlImportPaths)) {
// Search for the most specific version first, and search
@@ -271,8 +272,15 @@ QPair<QString, QString> resolveImportPath(const QString &uri, const QString &ver
if (relativePath.endsWith(slash))
relativePath.chop(1);
const QString candidatePath = QDir::cleanPath(qmlImportPath + slash + relativePath);
- if (QDir(candidatePath).exists())
- return qMakePair(candidatePath, relativePath); // import found
+ const QDir candidateDir(candidatePath);
+ if (candidateDir.exists()) {
+ const auto newCandidate = qMakePair(candidatePath, relativePath); // import found
+ if (candidateDir.exists(u"qmldir"_qs)) // if it has a qmldir, we are fine
+ return newCandidate;
+ else if (candidate.first.isEmpty())
+ candidate = newCandidate;
+ // otherwise we keep looking if we can find the module again (with a qmldir this time)
+ }
} else {
for (int index = parts.count() - 1; index >= 0; --index) {
QString relativePath = parts.mid(0, index + 1).join(slash)
@@ -280,8 +288,14 @@ QPair<QString, QString> resolveImportPath(const QString &uri, const QString &ver
if (relativePath.endsWith(slash))
relativePath.chop(1);
const QString candidatePath = QDir::cleanPath(qmlImportPath + slash + relativePath);
- if (QDir(candidatePath).exists())
- return qMakePair(candidatePath, relativePath); // import found
+ const QDir candidateDir(candidatePath);
+ if (candidateDir.exists()) {
+ const auto newCandidate = qMakePair(candidatePath, relativePath); // import found
+ if (candidateDir.exists(u"qmldir"_qs))
+ return newCandidate;
+ else if (candidate.first.isEmpty())
+ candidate = newCandidate;
+ }
}
}
}
@@ -297,7 +311,7 @@ QPair<QString, QString> resolveImportPath(const QString &uri, const QString &ver
ver = ver.mid(0, lastDot);
}
- return QPair<QString, QString>(); // not found
+ return candidate;
}
// Find absolute file system paths and plugins for a list of modules.