diff options
author | Christian Kandeler <christian.kandeler@digia.com> | 2012-11-13 18:03:28 +0100 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@digia.com> | 2012-11-15 09:46:24 +0100 |
commit | 7137d6c3ae2b953ae42ffb06f22a7ce5327917b8 (patch) | |
tree | 27f9ddc896a0fdb500a3358a8c2acfc6eb292b12 | |
parent | 0060eed9f8bfbd34c8d0a1e20d16ef380f99bc6e (diff) |
Implement "dry run" functionality.
Change-Id: Iae59f773c11ba6d7be748c95807727464906bcaa
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
-rw-r--r-- | src/lib/buildgraph/abstractcommandexecutor.cpp | 1 | ||||
-rw-r--r-- | src/lib/buildgraph/abstractcommandexecutor.h | 3 | ||||
-rw-r--r-- | src/lib/buildgraph/artifactcleaner.cpp | 2 | ||||
-rw-r--r-- | src/lib/buildgraph/artifactcleaner.h | 2 | ||||
-rw-r--r-- | src/lib/buildgraph/executor.cpp | 14 | ||||
-rw-r--r-- | src/lib/buildgraph/jscommandexecutor.cpp | 4 | ||||
-rw-r--r-- | src/lib/buildgraph/processcommandexecutor.cpp | 4 | ||||
-rw-r--r-- | src/lib/language/qbsengine.cpp | 60 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackbox.cpp | 25 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackbox.h | 3 |
10 files changed, 85 insertions, 33 deletions
diff --git a/src/lib/buildgraph/abstractcommandexecutor.cpp b/src/lib/buildgraph/abstractcommandexecutor.cpp index 20ac60ffd..49cc68110 100644 --- a/src/lib/buildgraph/abstractcommandexecutor.cpp +++ b/src/lib/buildgraph/abstractcommandexecutor.cpp @@ -41,6 +41,7 @@ AbstractCommandExecutor::AbstractCommandExecutor(QObject *parent) , m_command(0) , m_transformer(0) , m_mainThreadScriptEngine(0) + , m_dryRun(false) { } diff --git a/src/lib/buildgraph/abstractcommandexecutor.h b/src/lib/buildgraph/abstractcommandexecutor.h index 4d8a259f0..b9c4b34bc 100644 --- a/src/lib/buildgraph/abstractcommandexecutor.h +++ b/src/lib/buildgraph/abstractcommandexecutor.h @@ -63,6 +63,7 @@ protected: const AbstractCommand *command() const { return m_command; } Transformer *transformer() const { return m_transformer; } QScriptEngine *scriptEngine() const { return m_mainThreadScriptEngine; } + bool dryRun() const { return m_dryRun; } private: virtual void doStart() = 0; @@ -72,7 +73,7 @@ private: const AbstractCommand *m_command; Transformer *m_transformer; QScriptEngine *m_mainThreadScriptEngine; - bool m_dryRun; // TODO: Use + bool m_dryRun; }; } // namespace Internal diff --git a/src/lib/buildgraph/artifactcleaner.cpp b/src/lib/buildgraph/artifactcleaner.cpp index d19fb7c37..755aaed2c 100644 --- a/src/lib/buildgraph/artifactcleaner.cpp +++ b/src/lib/buildgraph/artifactcleaner.cpp @@ -120,7 +120,7 @@ private: QSet<QString> m_directories; }; -void ArtifactCleaner::cleanup(const QList<BuildProduct::ConstPtr> &products, bool removeAll, +void ArtifactCleaner::cleanup(const QList<BuildProduct::Ptr> &products, bool removeAll, const BuildOptions &buildOptions) { TimedActivityLogger logger(QLatin1String("Cleaning up")); diff --git a/src/lib/buildgraph/artifactcleaner.h b/src/lib/buildgraph/artifactcleaner.h index 02bee6dbf..3c9fcaa39 100644 --- a/src/lib/buildgraph/artifactcleaner.h +++ b/src/lib/buildgraph/artifactcleaner.h @@ -42,7 +42,7 @@ class Artifact; class ArtifactCleaner { public: - void cleanup(const QList<BuildProduct::ConstPtr> &products, bool removeAll, + void cleanup(const QList<BuildProduct::Ptr> &products, bool removeAll, const BuildOptions &buildOptions); }; diff --git a/src/lib/buildgraph/executor.cpp b/src/lib/buildgraph/executor.cpp index 54b55b50f..e3864e29f 100644 --- a/src/lib/buildgraph/executor.cpp +++ b/src/lib/buildgraph/executor.cpp @@ -397,12 +397,14 @@ void Executor::buildArtifact(Artifact *artifact) } // create the output directories - ArtifactList::const_iterator it = artifact->transformer->outputs.begin(); - for (; it != artifact->transformer->outputs.end(); ++it) { - Artifact *output = *it; - QDir outDir = QFileInfo(output->filePath()).absoluteDir(); - if (!outDir.exists()) - outDir.mkpath("."); + if (!m_buildOptions.dryRun) { + ArtifactList::const_iterator it = artifact->transformer->outputs.begin(); + for (; it != artifact->transformer->outputs.end(); ++it) { + Artifact *output = *it; + QDir outDir = QFileInfo(output->filePath()).absoluteDir(); + if (!outDir.exists()) + outDir.mkpath("."); + } } // scan all input artifacts diff --git a/src/lib/buildgraph/jscommandexecutor.cpp b/src/lib/buildgraph/jscommandexecutor.cpp index 042f3c01d..4b668b2ea 100644 --- a/src/lib/buildgraph/jscommandexecutor.cpp +++ b/src/lib/buildgraph/jscommandexecutor.cpp @@ -149,6 +149,10 @@ void JsCommandExecutor::waitForFinished() void JsCommandExecutor::doStart() { + if (dryRun()) { + emit finished(); + return; + } QFuture<JSRunner::result_type> future = QtConcurrent::run(JSRunner(jsCommand()), transformer()); if (!m_jsFutureWatcher) { m_jsFutureWatcher = new JavaScriptCommandFutureWatcher(this); diff --git a/src/lib/buildgraph/processcommandexecutor.cpp b/src/lib/buildgraph/processcommandexecutor.cpp index 3b37b53ce..1dffb3d08 100644 --- a/src/lib/buildgraph/processcommandexecutor.cpp +++ b/src/lib/buildgraph/processcommandexecutor.cpp @@ -102,6 +102,10 @@ void ProcessCommandExecutor::doStart() if (!cmd->isSilent()) qbsInfo() << DontPrintLogLevel << LogOutputStdOut << m_commandLine; qbsDebug() << "[EXEC] " << m_commandLine; + if (dryRun()) { + emit finished(); + return; + } // Automatically use response files, if the command line gets to long. if (!cmd->responseFileUsagePrefix().isEmpty()) { diff --git a/src/lib/language/qbsengine.cpp b/src/lib/language/qbsengine.cpp index 7d7f590e3..06fbc0a28 100644 --- a/src/lib/language/qbsengine.cpp +++ b/src/lib/language/qbsengine.cpp @@ -67,6 +67,11 @@ public: const BuildOptions &buildOptions); void buildProducts(const QList<ResolvedProduct::ConstPtr> &products, const BuildOptions &buildOptions, bool needsDepencencyResolving); + void cleanBuildProducts(const QList<BuildProduct::Ptr> &buildProducts, + const BuildOptions &buildOptions, QbsEngine::CleanType cleanType); + + void storeBuildGraphs(const QList<BuildProduct::Ptr> &buildProducts, + const BuildOptions &buildOptions); ScriptEngine engine; ProgressObserver *observer; @@ -207,32 +212,19 @@ void QbsEngine::buildProducts(const QList<Product> &products, const BuildOptions d->buildProducts(resolvedProducts, buildOptions, true); } -static void cleanBuildProducts(const QList<BuildProduct::ConstPtr> &buildProducts, - const BuildOptions &buildOptions, QbsEngine::CleanType cleanType) -{ - ArtifactCleaner cleaner; - cleaner.cleanup(buildProducts, cleanType == QbsEngine::CleanupAll, buildOptions); - - QSet<BuildProject *> buildProjects; - foreach (const BuildProduct::ConstPtr &bProduct, buildProducts) - buildProjects += bProduct->project; - foreach (BuildProject *bProject, buildProjects) - bProject->store(); -} - void QbsEngine::cleanProjects(const QList<Project::Id> &projectIds, const BuildOptions &buildOptions, CleanType cleanType) { - QList<BuildProduct::ConstPtr> products; + QList<BuildProduct::Ptr> products; foreach (const Project::Id id, projectIds) { const ResolvedProject::ConstPtr rProject = d->publicObjectsMap.project(id); if (!rProject) throw Error(Tr::tr("Cleaning up failed: Project not found.")); const BuildProject::ConstPtr bProject = d->setupBuildProject(rProject); - foreach (const BuildProduct::ConstPtr &product, bProject->buildProducts()) + foreach (const BuildProduct::Ptr &product, bProject->buildProducts()) products << product; } - cleanBuildProducts(products, buildOptions, cleanType); + d->cleanBuildProducts(products, buildOptions, cleanType); } void QbsEngine::cleanProjects(const QList<Project> &projects, const BuildOptions &buildOptions, @@ -244,21 +236,21 @@ void QbsEngine::cleanProjects(const QList<Project> &projects, const BuildOptions void QbsEngine::cleanProducts(const QList<Product> &products, const BuildOptions &buildOptions, QbsEngine::CleanType cleanType) { - QList<BuildProduct::ConstPtr> buildProducts; + QList<BuildProduct::Ptr> buildProducts; foreach (const Product &product, products) { const ResolvedProduct::ConstPtr rProduct = d->publicObjectsMap.product(product.id()); if (!rProduct) throw Error(Tr::tr("Cleaning up failed: Product not found.")); const ResolvedProject::ConstPtr rProject = rProduct->project.toStrongRef(); const BuildProject::ConstPtr bProject = d->setupBuildProject(rProject); - foreach (const BuildProduct::ConstPtr &bProduct, bProject->buildProducts()) { + foreach (const BuildProduct::Ptr &bProduct, bProject->buildProducts()) { if (bProduct->rProduct == rProduct) { buildProducts << bProduct; break; } } } - cleanBuildProducts(buildProducts, buildOptions, cleanType); + d->cleanBuildProducts(buildProducts, buildOptions, cleanType); } Project QbsEngine::retrieveProject(Project::Id projectId) const @@ -409,10 +401,7 @@ void QbsEngine::QbsEnginePrivate::buildProducts(const QList<BuildProduct::Ptr> & executor.build(buildProducts); execLoop.exec(); buildLogger.finishActivity(); - if (executor.state() != Executor::ExecutorError) { - foreach (const BuildProject::ConstPtr &buildProject, buildProjects) - buildProject->store(); - } + storeBuildGraphs(buildProducts, buildOptions); if (executor.buildResult() != Executor::SuccessfulBuild) throw Error(Tr::tr("Build failed.")); } @@ -449,6 +438,31 @@ void QbsEngine::QbsEnginePrivate::buildProducts(const QList<ResolvedProduct::Con buildProducts(productsToBuild, buildOptions); } +void QbsEngine::QbsEnginePrivate::cleanBuildProducts(const QList<BuildProduct::Ptr> &buildProducts, + const BuildOptions &buildOptions, QbsEngine::CleanType cleanType) +{ + try { + ArtifactCleaner cleaner; + cleaner.cleanup(buildProducts, cleanType == QbsEngine::CleanupAll, buildOptions); + } catch (const Error &error) { + storeBuildGraphs(buildProducts, buildOptions); + throw; + } + storeBuildGraphs(buildProducts, buildOptions); +} + +void QbsEngine::QbsEnginePrivate::storeBuildGraphs(const QList<BuildProduct::Ptr> &buildProducts, + const BuildOptions &buildOptions) +{ + if (buildOptions.dryRun) + return; + QSet<BuildProject *> buildProjects; + foreach (const BuildProduct::ConstPtr &bProduct, buildProducts) + buildProjects += bProduct->project; + foreach (const BuildProject * const bProject, buildProjects) + bProject->store(); +} + QVariantMap QbsEngine::QbsEnginePrivate::createBuildConfiguration(const QVariantMap &userBuildConfig) { QHash<QString, Platform::Ptr > platforms = Platform::platforms(); diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 96981481a..a4038db60 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -45,7 +45,8 @@ TestBlackbox::TestBlackbox() testSourceDir(QDir::cleanPath(SRCDIR "/testdata")), qbsExecutableFilePath(initQbsExecutableFilePath()), buildProfile(QLatin1String("qbs_autotests")), - buildDir(buildProfile + QLatin1String("-debug")) + buildDir(buildProfile + QLatin1String("-debug")), + buildGraphPath(buildDir + QLatin1Char('/') + buildDir + QLatin1String(".bg")) { } @@ -187,9 +188,31 @@ void TestBlackbox::build_project() QCOMPARE(runQbs(), 0); QVERIFY2(QFile::exists(productFileName), qPrintable(productFileName)); + QVERIFY(QFile::exists(buildGraphPath)); QVERIFY2(QFile::remove(productFileName), qPrintable(productFileName)); QCOMPARE(runQbs(), 0); QVERIFY2(QFile::exists(productFileName), qPrintable(productFileName)); + QVERIFY(QFile::exists(buildGraphPath)); +} + +void TestBlackbox::build_project_dry_run_data() +{ + build_project_data(); +} + +void TestBlackbox::build_project_dry_run() +{ + QFETCH(QString, projectSubDir); + QFETCH(QString, productFileName); + if (!projectSubDir.startsWith('/')) + projectSubDir.prepend('/'); + QVERIFY2(QFile::exists(testDataDir + projectSubDir), qPrintable(testDataDir + projectSubDir)); + QDir::setCurrent(testDataDir + projectSubDir); + + QCOMPARE(runQbs(QStringList() << "-n"), 0); + const QStringList &buildDirContents + = QDir(buildDir).entryList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs); + QVERIFY2(buildDirContents.isEmpty(), qPrintable(buildDirContents.join(" "))); } void TestBlackbox::track_qrc() diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index a2450caf3..5b91dcd62 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -44,6 +44,7 @@ class TestBlackbox : public QObject const QString qbsExecutableFilePath; const QString buildProfile; const QString buildDir; + const QString buildGraphPath; public: TestBlackbox(); @@ -61,6 +62,8 @@ public slots: private slots: void build_project_data(); void build_project(); + void build_project_dry_run_data(); + void build_project_dry_run(); void track_qrc(); void track_qobject_change(); void trackAddFile(); |