diff options
author | Eike Ziller <[email protected]> | 2024-11-29 10:21:20 +0100 |
---|---|---|
committer | Eike Ziller <[email protected]> | 2024-12-10 10:03:24 +0000 |
commit | 2a990b84fafa0e3bd6bf15d37108d4777996cfee (patch) | |
tree | 17c11b7e938bd8b1e74f0481175add65a9317d35 /src | |
parent | 65a3e484a905bf3fbac86784dd20ec421fbb401d (diff) |
VCS: Detect VCS directories even for disabled VCS plugins
Most of the version control support plugins detect that a directory/file
is under version control by looking for certain files in the directory
structure. This search doesn't really need anything specific from the
plugin, except for a list of file names.
Allow version control plugins to specify the list of files to look for in
their plugin meta data as "VcsDetectionFiles". When it is checked if a
directory is under version control, and none is found from the enabled
plugins, use the meta data to find out if any installed but disabled
plugin feels responsible for that directory.
Show a notification if a plugin is found that handles such a detected
version control system, with the option to enable the plugin and restart
QtC if necessary.
Since this adds discoverability of the version control support even when
plugins are disabled, disable the VCS plugins that can use this
mechanism (except for Git).
Change-Id: Ib507572c0065dd889a2f9b780c794f9cd985e265
Reviewed-by: Orgad Shaneh <[email protected]>
Reviewed-by: Marcus Tillmanns <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/bazaar/Bazaar.json.in | 4 | ||||
-rw-r--r-- | src/plugins/coreplugin/icore.cpp | 29 | ||||
-rw-r--r-- | src/plugins/coreplugin/icore.h | 3 | ||||
-rw-r--r-- | src/plugins/coreplugin/vcsmanager.cpp | 73 | ||||
-rw-r--r-- | src/plugins/fossil/Fossil.json.in | 3 | ||||
-rw-r--r-- | src/plugins/git/Git.json.in | 4 | ||||
-rw-r--r-- | src/plugins/mercurial/Mercurial.json.in | 4 | ||||
-rw-r--r-- | src/plugins/subversion/Subversion.json.in | 5 |
8 files changed, 125 insertions, 0 deletions
diff --git a/src/plugins/bazaar/Bazaar.json.in b/src/plugins/bazaar/Bazaar.json.in index e725b785734..8311877c71c 100644 --- a/src/plugins/bazaar/Bazaar.json.in +++ b/src/plugins/bazaar/Bazaar.json.in @@ -4,6 +4,7 @@ "Name" : "Bazaar", "Version" : "${IDE_VERSION}", "CompatVersion" : "${IDE_VERSION_COMPAT}", + "DisabledByDefault" : true, "VendorId" : "huguesdelorme", "Vendor" : "Hugues Delorme", "Copyright" : "(C) 2016 Hugues Delorme, ${IDE_COPYRIGHT}", @@ -23,5 +24,8 @@ ], "Url" : "https://www.qt.io", "DocumentationUrl" : "https://doc.qt.io/qtcreator/creator-vcs-bazaar.html", + "VcsDetectionFiles" : [ + ".bzr/branch-format" + ], ${IDE_PLUGIN_DEPENDENCIES} } diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 6168acfd6c6..55e99c92e1d 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -1127,6 +1127,35 @@ void ICore::restart() } /*! + Asks the user if they want to enable the \a plugins and their dependencies. + If the user agrees, the plugins are enabled. + If all plugins are soft loadable without restart, they get loaded directly. + Otherwise the "Restart Required" dialog is shown. + + Returns whether the user agreed to enabling the plugins. +*/ +bool ICore::enablePlugins(const QSet<ExtensionSystem::PluginSpec *> &plugins) +{ + std::optional<QSet<PluginSpec *>> additionalPlugins + = PluginManager::askForEnablingPlugins(dialogParent(), plugins, /*enable=*/true); + if (!additionalPlugins) // canceled + return false; + const QSet<PluginSpec *> affectedPlugins = plugins + *additionalPlugins; + bool softloadable = true; + for (PluginSpec *spec : affectedPlugins) { + spec->setEnabledBySettings(true); + softloadable = softloadable && spec->isSoftLoadable(); + } + ExtensionSystem::PluginManager::writeSettings(); + if (softloadable) { + PluginManager::loadPluginsAtRuntime(affectedPlugins); + } else { + ICore::askForRestart(Tr::tr("Plugin changes will take effect after restart.")); + } + return true; +} + +/*! \internal */ void ICore::setRelativePathToProjectFunction(const std::function<FilePath(const FilePath &)> &func) diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index 9aa1e93c393..10a90f66464 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -6,6 +6,7 @@ #include "core_global.h" #include "icontext.h" +#include <extensionsystem/pluginspec.h> #include <utils/appmainwindow.h> #include <utils/filepath.h> #include <utils/qtcsettings.h> @@ -116,6 +117,8 @@ public: static void restart(); + static bool enablePlugins(const QSet<ExtensionSystem::PluginSpec *> &plugins); + enum SaveSettingsReason { SettingsDialogDone, ModeChanged, diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp index de146a5656b..14271eab44f 100644 --- a/src/plugins/coreplugin/vcsmanager.cpp +++ b/src/plugins/coreplugin/vcsmanager.cpp @@ -12,12 +12,15 @@ #include "iversioncontrol.h" #include <extensionsystem/pluginmanager.h> +#include <extensionsystem/pluginspec.h> #include <utils/algorithm.h> #include <utils/fileutils.h> #include <utils/infobar.h> #include <utils/qtcassert.h> +#include <QJsonArray> +#include <QLabel> #include <QList> #include <QMap> #include <QMessageBox> @@ -177,6 +180,74 @@ static FilePath fixedDir(const FilePath &directory) return directory; } +static void askForDisabledVcsPlugins(const FilePath &inputDirectory) +{ + using namespace ExtensionSystem; + FilePath toplevel; + + PluginSpec *spec = Utils::findOrDefault( + PluginManager::plugins(), [&toplevel, inputDirectory](PluginSpec *plugin) { + if (plugin->isEffectivelyEnabled()) + return false; + const QJsonObject metaData = plugin->metaData(); + const QJsonArray filesArray = metaData.value("VcsDetectionFiles").toArray(); + if (filesArray.isEmpty()) + return false; + QStringList files; + for (const QJsonValue &v : filesArray) { + const QString str = v.toString(); + if (!str.isEmpty()) + files.append(str); + } + if (files.isEmpty()) + return false; + qCDebug(findRepoLog) << "Checking if plugin" << plugin->displayName() << "can handle" + << inputDirectory.toUserOutput(); + qCDebug(findRepoLog) << "by checking for" << files; + const FilePath dir = VcsManager::findRepositoryForFiles(inputDirectory, files); + if (dir.isEmpty()) + return false; + qCDebug(findRepoLog) << "The plugin" << plugin->displayName() << "can handle" + << inputDirectory.toUserOutput(); + toplevel = dir; + return true; + }); + + if (!spec) + return; + + const Id vcsSuggestion = Id("VcsManager.Suggestion.").withSuffix(spec->id()); + InfoBar *infoBar = ICore::infoBar(); + if (!infoBar->canInfoBeAdded(vcsSuggestion)) + return; + + const QString pluginDisplayName = spec->displayName(); + Utils::InfoBarEntry info( + vcsSuggestion, + Tr::tr("A directory under version control was detected that is supported by the %1 plugin.") + .arg(pluginDisplayName), + Utils::InfoBarEntry::GlobalSuppression::Enabled); + info.addCustomButton(Tr::tr("Enable %1").arg(pluginDisplayName), [vcsSuggestion, spec] { + // TODO In case the plugin is actually loaded during runtime (softloadable), + // we'd need to restructure findVersionControlForDirectory below to take the new plugin + // into account. + // At the moment softloadable VCS plugins are not supported though. + if (ICore::enablePlugins({spec})) + ICore::infoBar()->removeInfo(vcsSuggestion); + }); + + info.setDetailsWidgetCreator([toplevel, pluginDisplayName]() -> QWidget * { + auto label = new QLabel; + label->setWordWrap(true); + label->setOpenExternalLinks(true); + label->setText(Tr::tr("The directory \"%1\" seems to be under version control that can be " + "handled by the disabled %2 plugin.") + .arg(toplevel.toUserOutput(), pluginDisplayName)); + label->setContentsMargins(0, 0, 0, 8); + return label; + }); + ICore::infoBar()->addInfo(info); +}; IVersionControl* VcsManager::findVersionControlForDirectory(const FilePath &inputDirectory, FilePath *topLevelDirectory) @@ -221,6 +292,8 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const FilePath &inpu // report result; if (topLevelDirectory) topLevelDirectory->clear(); + + askForDisabledVcsPlugins(directory); return nullptr; } diff --git a/src/plugins/fossil/Fossil.json.in b/src/plugins/fossil/Fossil.json.in index ccc9856d2bc..6018e41ed4e 100644 --- a/src/plugins/fossil/Fossil.json.in +++ b/src/plugins/fossil/Fossil.json.in @@ -24,6 +24,9 @@ ], "Url" : "https://www.qt.io", "DocumentationUrl" : "https://doc.qt.io/qtcreator/creator-vcs-fossil.html", + "VcsDetectionFiles" : [ + ".fslckout" + ], ${IDE_PLUGIN_DEPENDENCIES}, "JsonWizardPaths" : [":/fossil/wizard"] diff --git a/src/plugins/git/Git.json.in b/src/plugins/git/Git.json.in index 6c6b476b880..d87f9341643 100644 --- a/src/plugins/git/Git.json.in +++ b/src/plugins/git/Git.json.in @@ -30,6 +30,10 @@ "Description" : "Show given commit hash" } ], + "VcsDetectionFiles" : [ + ".git", + ".git/config" + ], ${IDE_PLUGIN_DEPENDENCIES}, "Mimetypes" : [ diff --git a/src/plugins/mercurial/Mercurial.json.in b/src/plugins/mercurial/Mercurial.json.in index d8125d77ba2..835005771ca 100644 --- a/src/plugins/mercurial/Mercurial.json.in +++ b/src/plugins/mercurial/Mercurial.json.in @@ -4,6 +4,7 @@ "Name" : "Mercurial", "Version" : "${IDE_VERSION}", "CompatVersion" : "${IDE_VERSION_COMPAT}", + "DisabledByDefault" : true, "VendorId" : "brianmcgillion", "Vendor" : "Brian McGillion", "Copyright" : "(C) 2016 Brian McGillion, ${IDE_COPYRIGHT}", @@ -23,5 +24,8 @@ ], "Url" : "https://www.qt.io", "DocumentationUrl" : "https://doc.qt.io/qtcreator/creator-vcs-mercurial.html", + "VcsDetectionFiles" : [ + ".hg/requires" + ], ${IDE_PLUGIN_DEPENDENCIES} } diff --git a/src/plugins/subversion/Subversion.json.in b/src/plugins/subversion/Subversion.json.in index 1941eb222c4..81420a0e3ac 100644 --- a/src/plugins/subversion/Subversion.json.in +++ b/src/plugins/subversion/Subversion.json.in @@ -4,6 +4,7 @@ "Name" : "Subversion", "Version" : "${IDE_VERSION}", "CompatVersion" : "${IDE_VERSION_COMPAT}", + "DisabledByDefault" : true, "VendorId" : "theqtcompany", "Vendor" : "The Qt Company Ltd", "Copyright" : "${IDE_COPYRIGHT}", @@ -23,6 +24,10 @@ ], "Url" : "https://www.qt.io", "DocumentationUrl" : "https://doc.qt.io/qtcreator/creator-vcs-subversion.html", + "VcsDetectionFiles" : [ + ".svn/wc.db", + "_svn/wc.db" + ], ${IDE_PLUGIN_DEPENDENCIES}, "Mimetypes" : [ |