diff options
| author | Christian Kandeler <christian.kandeler@digia.com> | 2013-07-15 11:21:25 +0200 |
|---|---|---|
| committer | Christian Kandeler <christian.kandeler@digia.com> | 2013-07-16 10:18:40 +0200 |
| commit | 3315b5a35f86f70d9d3ef32fcc07d90406f5b30a (patch) | |
| tree | b18fe4a2e1ee63563be37416992266c460050315 | |
| parent | 7aff31171eb3e756fc6ac6ff4bb4db6dcc96e42a (diff) | |
| download | qbs-3315b5a35f86f70d9d3ef32fcc07d90406f5b30a.tar.gz | |
Use previous results of calls to "File.exists()" in change tracking.
This is the same kind of "external change" as those coming from the
environment or JavaScript files, and is thus handled the same way.
Change-Id: I0a097d6d5c39ece859e6784f65f77f35a7273d59
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
| -rw-r--r-- | src/lib/buildgraph/buildgraphloader.cpp | 17 | ||||
| -rw-r--r-- | src/lib/buildgraph/buildgraphloader.h | 1 | ||||
| -rw-r--r-- | src/lib/jsextensions/file.cpp | 7 | ||||
| -rw-r--r-- | src/lib/language/language.cpp | 3 | ||||
| -rw-r--r-- | src/lib/language/language.h | 1 | ||||
| -rw-r--r-- | src/lib/language/projectresolver.cpp | 1 | ||||
| -rw-r--r-- | src/lib/language/scriptengine.cpp | 5 | ||||
| -rw-r--r-- | src/lib/language/scriptengine.h | 3 | ||||
| -rw-r--r-- | src/lib/tools/persistence.cpp | 2 | ||||
| -rw-r--r-- | tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs | 6 | ||||
| -rw-r--r-- | tests/auto/blackbox/tst_blackbox.cpp | 27 |
11 files changed, 68 insertions, 5 deletions
diff --git a/src/lib/buildgraph/buildgraphloader.cpp b/src/lib/buildgraph/buildgraphloader.cpp index 4d62e55ae..ab3360574 100644 --- a/src/lib/buildgraph/buildgraphloader.cpp +++ b/src/lib/buildgraph/buildgraphloader.cpp @@ -179,7 +179,8 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters ¶met // anew. bool allProductsPotentiallyChanged = false; if (hasBuildSystemFileChanged(buildSystemFiles, buildGraphTimeStamp) - || hasEnvironmentChanged(restoredProject)) { + || hasEnvironmentChanged(restoredProject) + || hasFileExistsResultChanged(restoredProject)) { reResolvingNecessary = true; allProductsPotentiallyChanged = true; } @@ -285,6 +286,20 @@ bool BuildGraphLoader::hasEnvironmentChanged(const TopLevelProjectConstPtr &rest return false; } +bool BuildGraphLoader::hasFileExistsResultChanged(const TopLevelProjectConstPtr &restoredProject) const +{ + for (QHash<QString, bool>::ConstIterator it = restoredProject->fileExistsResults.constBegin(); + it != restoredProject->fileExistsResults.constEnd(); ++it) { + if (FileInfo(it.key()).exists() != it.value()) { + m_logger.qbsDebug() << "Existence check for file '" << it.key() + << " 'changed, must re-resolve project."; + return true; + } + } + + return false; +} + bool BuildGraphLoader::hasProductFileChanged(const QList<ResolvedProductPtr> &restoredProducts, const FileTime &referenceTime, QSet<QString> &remainingBuildSystemFiles, QList<ResolvedProductPtr> &changedProducts) diff --git a/src/lib/buildgraph/buildgraphloader.h b/src/lib/buildgraph/buildgraphloader.h index 8cbe5e354..86907cddc 100644 --- a/src/lib/buildgraph/buildgraphloader.h +++ b/src/lib/buildgraph/buildgraphloader.h @@ -67,6 +67,7 @@ private: const QString &buildGraphFilePath, const TopLevelProjectPtr &restoredProject); bool hasEnvironmentChanged(const TopLevelProjectConstPtr &restoredProject) const; + bool hasFileExistsResultChanged(const TopLevelProjectConstPtr &restoredProject) const; bool hasProductFileChanged(const QList<ResolvedProductPtr> &restoredProducts, const FileTime &referenceTime, QSet<QString> &remainingBuildSystemFiles, diff --git a/src/lib/jsextensions/file.cpp b/src/lib/jsextensions/file.cpp index 4d7515482..6d84475cd 100644 --- a/src/lib/jsextensions/file.cpp +++ b/src/lib/jsextensions/file.cpp @@ -29,6 +29,7 @@ #include "file.h" +#include <language/scriptengine.h> #include <logging/translator.h> #include <tools/fileinfo.h> @@ -91,7 +92,11 @@ QScriptValue File::js_exists(QScriptContext *context, QScriptEngine *engine) return context->throwError(QScriptContext::SyntaxError, Tr::tr("exist expects 1 argument")); } - return FileInfo::exists(context->argument(0).toString()); + const QString filePath = context->argument(0).toString(); + const bool exists = FileInfo::exists(filePath); + ScriptEngine * const se = static_cast<ScriptEngine *>(engine); + se->addFileExistsResult(filePath, exists); + return exists; } QScriptValue File::js_remove(QScriptContext *context, QScriptEngine *engine) diff --git a/src/lib/language/language.cpp b/src/lib/language/language.cpp index 8711bd0c5..b34ccdabe 100644 --- a/src/lib/language/language.cpp +++ b/src/lib/language/language.cpp @@ -727,6 +727,7 @@ void TopLevelProject::load(PersistentPool &pool) pool.stream() >> m_id; pool.stream() >> platformEnvironment; pool.stream() >> usedEnvironment; + pool.stream() >> fileExistsResults; QHash<QString, QString> envHash; pool.stream() >> envHash; for (QHash<QString, QString>::const_iterator i = envHash.begin(); i != envHash.end(); ++i) @@ -740,7 +741,7 @@ void TopLevelProject::store(PersistentPool &pool) const { ResolvedProject::store(pool); pool.stream() << m_id; - pool.stream() << platformEnvironment << usedEnvironment; + pool.stream() << platformEnvironment << usedEnvironment << fileExistsResults; QHash<QString, QString> envHash; foreach (const QString &key, environment.keys()) envHash.insert(key, environment.value(key)); diff --git a/src/lib/language/language.h b/src/lib/language/language.h index d142ba1bf..efa8e50c3 100644 --- a/src/lib/language/language.h +++ b/src/lib/language/language.h @@ -369,6 +369,7 @@ public: QProcessEnvironment environment; QVariantMap platformEnvironment; QHash<QString, QString> usedEnvironment; // Environment variables requested by the project while resolving. + QHash<QString, bool> fileExistsResults; // Results of calls to "File.exists()". QScopedPointer<ProjectBuildData> buildData; QSet<QString> buildSystemFiles; diff --git a/src/lib/language/projectresolver.cpp b/src/lib/language/projectresolver.cpp index d9fcc4306..8cd61b3d1 100644 --- a/src/lib/language/projectresolver.cpp +++ b/src/lib/language/projectresolver.cpp @@ -163,6 +163,7 @@ void ProjectResolver::resolveTopLevelProject(Item *item, ProjectContext *project projectContext->project = project; resolveProject(item, projectContext); project->usedEnvironment = m_engine->usedEnvironment(); + project->fileExistsResults = m_engine->fileExistsResults(); project->environment = m_environment; project->buildSystemFiles = m_engine->imports(); makeSubProjectNamesUniqe(project); diff --git a/src/lib/language/scriptengine.cpp b/src/lib/language/scriptengine.cpp index 25cde2ec3..f27f0e679 100644 --- a/src/lib/language/scriptengine.cpp +++ b/src/lib/language/scriptengine.cpp @@ -238,6 +238,11 @@ void ScriptEngine::addEnvironmentVariable(const QString &name, const QString &va m_usedEnvironment.insert(name, value); } +void ScriptEngine::addFileExistsResult(const QString &filePath, bool exists) +{ + m_fileExistsResult.insert(filePath, exists); +} + QSet<QString> ScriptEngine::imports() const { return QSet<QString>::fromList(m_jsImportCache.keys()); diff --git a/src/lib/language/scriptengine.h b/src/lib/language/scriptengine.h index afbea5889..7a84defb4 100644 --- a/src/lib/language/scriptengine.h +++ b/src/lib/language/scriptengine.h @@ -77,6 +77,8 @@ public: void setEnvironment(const QProcessEnvironment &env); void addEnvironmentVariable(const QString &name, const QString &value); QHash<QString, QString> usedEnvironment() const { return m_usedEnvironment; } + void addFileExistsResult(const QString &filePath, bool exists); + QHash<QString, bool> fileExistsResults() const { return m_fileExistsResult; } QSet<QString> imports() const; private: @@ -92,6 +94,7 @@ private: QScriptValue m_emptyFunction; QProcessEnvironment m_environment; QHash<QString, QString> m_usedEnvironment; + QHash<QString, bool> m_fileExistsResult; }; } // namespace Internal diff --git a/src/lib/tools/persistence.cpp b/src/lib/tools/persistence.cpp index d891b1d1e..07cf4917e 100644 --- a/src/lib/tools/persistence.cpp +++ b/src/lib/tools/persistence.cpp @@ -40,7 +40,7 @@ namespace qbs { namespace Internal { -static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-43"; +static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-44"; PersistentPool::PersistentPool(const Logger &logger) : m_logger(logger) { diff --git a/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs b/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs index cfd897447..8ed267fa5 100644 --- a/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs +++ b/tests/auto/blackbox/testdata/trackExternalProductChanges/project.qbs @@ -1,6 +1,10 @@ import qbs +import qbs.File import "fileList.js" as FileList CppApplication { - files: ["main.cpp"].concat(FileList.fileList()).concat(qbs.getenv("QBS_TEST_PULL_IN_FILE_VIA_ENV") ? ["environmentChange.cpp"] : []) + property pathList filesFromEnv: qbs.getenv("QBS_TEST_PULL_IN_FILE_VIA_ENV") ? ["environmentChange.cpp"] : [] + property pathList filesFromJs: FileList.fileList() + property pathList filesFromFs: File.exists(path + "/fileExists.cpp") ? ["fileExists.cpp"] : [] + files: ["main.cpp"].concat(filesFromJs).concat(filesFromEnv).concat(filesFromFs) } diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 8d2f6dbdb..cb91da3fd 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -596,6 +596,7 @@ void TestBlackbox::trackExternalProductChanges() QVERIFY(m_qbsStdout.contains("compiling main.cpp")); QVERIFY(!m_qbsStdout.contains("compiling environmentChange.cpp")); QVERIFY(!m_qbsStdout.contains("compiling jsFileChange.cpp")); + QVERIFY(!m_qbsStdout.contains("compiling fileExists.cpp")); QbsRunParameters params; params.environment.insert("QBS_TEST_PULL_IN_FILE_VIA_ENV", "1"); @@ -603,12 +604,14 @@ void TestBlackbox::trackExternalProductChanges() QVERIFY(!m_qbsStdout.contains("compiling main.cpp")); QVERIFY(m_qbsStdout.contains("compiling environmentChange.cpp")); QVERIFY(!m_qbsStdout.contains("compiling jsFileChange.cpp")); + QVERIFY(!m_qbsStdout.contains("compiling fileExists.cpp")); rmDirR(buildDir); QCOMPARE(runQbs(), 0); QVERIFY(m_qbsStdout.contains("compiling main.cpp")); QVERIFY(!m_qbsStdout.contains("compiling environmentChange.cpp")); QVERIFY(!m_qbsStdout.contains("compiling jsFileChange.cpp")); + QVERIFY(!m_qbsStdout.contains("compiling fileExists.cpp")); waitForNewTimestamp(); QFile jsFile("fileList.js"); @@ -622,6 +625,30 @@ void TestBlackbox::trackExternalProductChanges() QVERIFY(!m_qbsStdout.contains("compiling main.cpp")); QVERIFY(!m_qbsStdout.contains("compiling environmentChange.cpp")); QVERIFY(m_qbsStdout.contains("compiling jsFileChange.cpp")); + QVERIFY(!m_qbsStdout.contains("compiling fileExists.cpp")); + + rmDirR(buildDir); + QVERIFY(jsFile.open(QIODevice::ReadWrite)); + jsCode = jsFile.readAll(); + jsCode.replace("['jsFileChange.cpp']", "[]"); + jsFile.resize(0); + jsFile.write(jsCode); + jsFile.close(); + QCOMPARE(runQbs(), 0); + QVERIFY(m_qbsStdout.contains("compiling main.cpp")); + QVERIFY(!m_qbsStdout.contains("compiling environmentChange.cpp")); + QVERIFY(!m_qbsStdout.contains("compiling jsFileChange.cpp")); + QVERIFY(!m_qbsStdout.contains("compiling fileExists.cpp")); + + QFile cppFile("fileExists.cpp"); + QVERIFY(cppFile.open(QIODevice::WriteOnly)); + cppFile.write("void fileExists() { }\n"); + cppFile.close(); + QCOMPARE(runQbs(), 0); + QVERIFY(!m_qbsStdout.contains("compiling main.cpp")); + QVERIFY(!m_qbsStdout.contains("compiling environmentChange.cpp")); + QVERIFY(!m_qbsStdout.contains("compiling jsFileChange.cpp")); + QVERIFY(m_qbsStdout.contains("compiling fileExists.cpp")); } void TestBlackbox::trackRemoveFile() |
