aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEike Ziller <[email protected]>2024-11-29 10:21:20 +0100
committerEike Ziller <[email protected]>2024-12-10 10:03:24 +0000
commit2a990b84fafa0e3bd6bf15d37108d4777996cfee (patch)
tree17c11b7e938bd8b1e74f0481175add65a9317d35 /src
parent65a3e484a905bf3fbac86784dd20ec421fbb401d (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.in4
-rw-r--r--src/plugins/coreplugin/icore.cpp29
-rw-r--r--src/plugins/coreplugin/icore.h3
-rw-r--r--src/plugins/coreplugin/vcsmanager.cpp73
-rw-r--r--src/plugins/fossil/Fossil.json.in3
-rw-r--r--src/plugins/git/Git.json.in4
-rw-r--r--src/plugins/mercurial/Mercurial.json.in4
-rw-r--r--src/plugins/subversion/Subversion.json.in5
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" : [