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. Pick-to: 6.2 Change-Id: I12efeae321da60b1b5ffe5c6d950ba486887ceb1 Reviewed-by: Craig Scott <craig.scott@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
parent
b395e5c5c3
commit
70ecbb690c
|
@ -0,0 +1,3 @@
|
|||
import QtQml
|
||||
|
||||
QtObject {}
|
|
@ -0,0 +1,3 @@
|
|||
module Module
|
||||
|
||||
A 1.0 A.qml
|
|
@ -0,0 +1,3 @@
|
|||
import QtQml
|
||||
|
||||
QtObject {}
|
|
@ -0,0 +1,3 @@
|
|||
import Module
|
||||
|
||||
A {}
|
|
@ -57,5 +57,9 @@
|
|||
"name": "Imports",
|
||||
"relativePath": "Imports",
|
||||
"type": "module"
|
||||
},
|
||||
{
|
||||
"name": "Module",
|
||||
"type": "module"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -253,6 +253,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
|
||||
|
@ -267,8 +268,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)
|
||||
|
@ -276,8 +284,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -293,7 +307,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.
|
||||
|
|
Loading…
Reference in New Issue