From 044eeacde5ee1add8b06a8a53b86fd5c6991d488 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Wed, 4 Mar 2015 09:25:08 +0200 Subject: Load only tested plugins when invoked with -test By default, a clean settings path is used for test environment. All the default plugins are loaded, although they're not needed. This change significantly improves loading time for tests. Change-Id: I24254f3e538e3f0e6d233d0989738dc1ce238209 Reviewed-by: Leena Miettinen Reviewed-by: Eike Ziller --- src/libs/extensionsystem/optionsparser.cpp | 1 + src/libs/extensionsystem/plugindetailsview.cpp | 10 +++++- src/libs/extensionsystem/pluginmanager.cpp | 40 ++++++++++++++++++++++-- src/libs/extensionsystem/pluginmanager_p.h | 1 + src/libs/extensionsystem/pluginspec.cpp | 7 ++++- src/libs/extensionsystem/pluginspec.h | 3 +- src/plugins/cppeditor/cppeditor.qbs | 4 +++ src/plugins/cppeditor/cppeditor_dependencies.pri | 2 ++ src/plugins/cpptools/cpptools.qbs | 5 +++ src/plugins/cpptools/cpptools_dependencies.pri | 3 ++ src/qtcreatorplugin.pri | 4 +++ 11 files changed, 75 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libs/extensionsystem/optionsparser.cpp b/src/libs/extensionsystem/optionsparser.cpp index 9882c3121f..8d50d722e7 100644 --- a/src/libs/extensionsystem/optionsparser.cpp +++ b/src/libs/extensionsystem/optionsparser.cpp @@ -91,6 +91,7 @@ bool OptionsParser::parse() } if (m_isDependencyRefreshNeeded) m_pmPrivate->resolveDependencies(); + m_pmPrivate->enableOnlyTestedSpecs(); return !m_hasError; } diff --git a/src/libs/extensionsystem/plugindetailsview.cpp b/src/libs/extensionsystem/plugindetailsview.cpp index 35e64f4ee6..310ef48b9d 100644 --- a/src/libs/extensionsystem/plugindetailsview.cpp +++ b/src/libs/extensionsystem/plugindetailsview.cpp @@ -98,8 +98,16 @@ void PluginDetailsView::update(PluginSpec *spec) QString depString = dep.name; depString += QLatin1String(" ("); depString += dep.version; - if (dep.type == PluginDependency::Optional) + switch (dep.type) { + case PluginDependency::Required: + break; + case PluginDependency::Optional: depString += QLatin1String(", optional"); + break; + case PluginDependency::Test: + depString += QLatin1String(", test"); + break; + } depString += QLatin1Char(')'); depStrings.append(depString); } diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 5f2785236d..d34db47d25 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -1255,7 +1255,14 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList &queu } // add dependencies - foreach (PluginSpec *depSpec, spec->dependencySpecs()) { + QHashIterator it(spec->dependencySpecs()); + while (it.hasNext()) { + it.next(); + // Skip test dependencies since they are not real dependencies but just force-loaded + // plugins when running tests + if (it.key().type == PluginDependency::Test) + continue; + PluginSpec *depSpec = it.value(); if (!loadQueue(depSpec, queue, circularityCheckQueue)) { spec->d->hasError = true; spec->d->errorString = @@ -1299,7 +1306,7 @@ void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destSt QHashIterator it(spec->dependencySpecs()); while (it.hasNext()) { it.next(); - if (it.key().type == PluginDependency::Optional) + if (it.key().type != PluginDependency::Required) continue; PluginSpec *depSpec = it.value(); if (depSpec->state() != destState) { @@ -1423,6 +1430,35 @@ void PluginManagerPrivate::resolveDependencies() } } +void PluginManagerPrivate::enableOnlyTestedSpecs() +{ + if (testSpecs.isEmpty()) + return; + + QList specsForTests; + foreach (const TestSpec &testSpec, testSpecs) { + QList circularityCheckQueue; + loadQueue(testSpec.pluginSpec, specsForTests, circularityCheckQueue); + // add plugins that must be force loaded when running tests for the plugin + // (aka "test dependencies") + QHashIterator it(testSpec.pluginSpec->dependencySpecs()); + while (it.hasNext()) { + it.next(); + if (it.key().type != PluginDependency::Test) + continue; + PluginSpec *depSpec = it.value(); + circularityCheckQueue.clear(); + loadQueue(depSpec, specsForTests, circularityCheckQueue); + } + } + foreach (PluginSpec *spec, pluginSpecs) + spec->setForceDisabled(true); + foreach (PluginSpec *spec, specsForTests) { + spec->setForceDisabled(false); + spec->setForceEnabled(true); + } +} + // Look in argument descriptions of the specs for the option. PluginSpec *PluginManagerPrivate::pluginForOption(const QString &option, bool *requiresArgument) const { diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h index 0400ceb0fc..f219d5c0da 100644 --- a/src/libs/extensionsystem/pluginmanager_p.h +++ b/src/libs/extensionsystem/pluginmanager_p.h @@ -73,6 +73,7 @@ public: QList loadQueue(); void loadPlugin(PluginSpec *spec, PluginSpec::State destState); void resolveDependencies(); + void enableOnlyTestedSpecs(); void initProfiling(); void profilingSummary() const; void profilingReport(const char *what, const PluginSpec *spec = 0); diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index 9d470cd5b2..858dfd9510 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -86,6 +86,8 @@ Dependency is not necessarily needed. You need to make sure that the plugin is able to load without this dependency installed, so for example you may not link to the dependency's library. + \value Test + Dependency needs to be force-loaded for running tests of the plugin. */ /*! @@ -471,6 +473,7 @@ namespace { const char DEPENDENCY_TYPE[] = "Type"; const char DEPENDENCY_TYPE_SOFT[] = "optional"; const char DEPENDENCY_TYPE_HARD[] = "required"; + const char DEPENDENCY_TYPE_TEST[] = "test"; const char ARGUMENTS[] = "Arguments"; const char ARGUMENT_NAME[] = "Name"; const char ARGUMENT_PARAMETER[] = "Parameter"; @@ -763,6 +766,8 @@ bool PluginSpecPrivate::readMetaData(const QJsonObject &metaData) dep.type = PluginDependency::Required; } else if (typeValue.toLower() == QLatin1String(DEPENDENCY_TYPE_SOFT)) { dep.type = PluginDependency::Optional; + } else if (typeValue.toLower() == QLatin1String(DEPENDENCY_TYPE_TEST)) { + dep.type = PluginDependency::Test; } else { return reportError(tr("Dependency: \"%1\" must be \"%2\" or \"%3\" (is \"%4\")") .arg(QLatin1String(DEPENDENCY_TYPE), @@ -917,7 +922,7 @@ void PluginSpecPrivate::disableIndirectlyIfDependencyDisabled() QHashIterator it(dependencySpecs); while (it.hasNext()) { it.next(); - if (it.key().type == PluginDependency::Optional) + if (it.key().type != PluginDependency::Required) continue; PluginSpec *dependencySpec = it.value(); if (!dependencySpec->isEffectivelyEnabled()) { diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h index 9272403e9a..56860135a9 100644 --- a/src/libs/extensionsystem/pluginspec.h +++ b/src/libs/extensionsystem/pluginspec.h @@ -55,7 +55,8 @@ struct EXTENSIONSYSTEM_EXPORT PluginDependency { enum Type { Required, - Optional + Optional, + Test }; PluginDependency() : type(Required) {} diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index cb1248508e..243fb63774 100644 --- a/src/plugins/cppeditor/cppeditor.qbs +++ b/src/plugins/cppeditor/cppeditor.qbs @@ -16,6 +16,10 @@ QtcPlugin { Depends { name: "app_version_header" } + pluginTestDepends: [ + "QmakeProjectManager", + ] + files: [ "cppautocompleter.cpp", "cppautocompleter.h", "cppcanonicalsymbol.cpp", "cppcanonicalsymbol.h", diff --git a/src/plugins/cppeditor/cppeditor_dependencies.pri b/src/plugins/cppeditor/cppeditor_dependencies.pri index 2b90476fc3..751d75224a 100644 --- a/src/plugins/cppeditor/cppeditor_dependencies.pri +++ b/src/plugins/cppeditor/cppeditor_dependencies.pri @@ -9,3 +9,5 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ cpptools \ projectexplorer +QTC_TEST_DEPENDS += \ + qmakeprojectmanager diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 9d8e6c7d85..72b68b9a9a 100644 --- a/src/plugins/cpptools/cpptools.qbs +++ b/src/plugins/cpptools/cpptools.qbs @@ -14,6 +14,11 @@ QtcPlugin { Depends { name: "ProjectExplorer" } Depends { name: "app_version_header" } + pluginTestDepends: [ + "CppEditor", + "QmakeProjectManager", + ] + cpp.defines: base Properties { condition: qbs.toolchain.contains("msvc") diff --git a/src/plugins/cpptools/cpptools_dependencies.pri b/src/plugins/cpptools/cpptools_dependencies.pri index 705d6334f3..27d0f90d68 100644 --- a/src/plugins/cpptools/cpptools_dependencies.pri +++ b/src/plugins/cpptools/cpptools_dependencies.pri @@ -8,3 +8,6 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ projectexplorer \ texteditor +QTC_TEST_DEPENDS += \ + cppeditor \ + qmakeprojectmanager diff --git a/src/qtcreatorplugin.pri b/src/qtcreatorplugin.pri index 5381b6de83..0f57dfc88a 100644 --- a/src/qtcreatorplugin.pri +++ b/src/qtcreatorplugin.pri @@ -10,6 +10,7 @@ exists($$depfile) { TARGET = $$QTC_PLUGIN_NAME plugin_deps = $$QTC_PLUGIN_DEPENDS +plugin_test_deps = $$QTC_TEST_DEPENDS plugin_recmds = $$QTC_PLUGIN_RECOMMENDS include(../qtcreator.pri) @@ -36,6 +37,9 @@ for(dep, plugin_deps) { for(dep, plugin_recmds) { dependencyList += " { \"Name\" : \"$$dependencyName($$dep)\", \"Version\" : \"$$QTCREATOR_VERSION\", \"Type\" : \"optional\" }" } +for(dep, plugin_test_deps) { + dependencyList += " { \"Name\" : \"$$dependencyName($$dep)\", \"Version\" : \"$$QTCREATOR_VERSION\", \"Type\" : \"test\" }" +} dependencyList = $$join(dependencyList, ",$$escape_expand(\\n)") dependencyList = "\"Dependencies\" : [$$escape_expand(\\n)$$dependencyList$$escape_expand(\\n) ]" -- cgit v1.2.1