forked from qt-creator/qt-creator
ExtensionSystem: Split update into remove and install
Change-Id: Ib048d5c889bb5ac463309ea15486e3f226d84a2e Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -839,6 +839,8 @@ int main(int argc, char **argv)
|
|||||||
// Make sure we honor the system's proxy settings
|
// Make sure we honor the system's proxy settings
|
||||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||||
|
|
||||||
|
PluginManager::removePluginsAfterRestart();
|
||||||
|
|
||||||
// We need to install plugins before we scan for them.
|
// We need to install plugins before we scan for them.
|
||||||
PluginManager::installPluginsAfterRestart();
|
PluginManager::installPluginsAfterRestart();
|
||||||
|
|
||||||
@@ -847,9 +849,6 @@ int main(int argc, char **argv)
|
|||||||
PluginManager::setPluginPaths(
|
PluginManager::setPluginPaths(
|
||||||
getPluginPaths() + Utils::transform(pluginPaths, &FilePath::fromUserInput));
|
getPluginPaths() + Utils::transform(pluginPaths, &FilePath::fromUserInput));
|
||||||
|
|
||||||
// We need to remove plugins once we have scanned for them.
|
|
||||||
PluginManager::removePluginsAfterRestart();
|
|
||||||
|
|
||||||
QMap<QString, QString> foundAppOptions;
|
QMap<QString, QString> foundAppOptions;
|
||||||
if (pluginArguments.size() > 1) {
|
if (pluginArguments.size() > 1) {
|
||||||
QMap<QString, bool> appOptions;
|
QMap<QString, bool> appOptions;
|
||||||
|
@@ -357,15 +357,15 @@ void PluginManager::installPluginsAfterRestart()
|
|||||||
d->installPluginsAfterRestart();
|
d->installPluginsAfterRestart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginManager::removePluginOnRestart(const QString &id)
|
Result PluginManager::removePluginOnRestart(const QString &id)
|
||||||
{
|
{
|
||||||
d->removePluginOnNextRestart(id);
|
return d->removePluginOnRestart(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginManager::installPluginOnRestart(
|
void PluginManager::installPluginOnRestart(
|
||||||
const Utils::FilePath &source, const Utils::FilePath &destination)
|
const Utils::FilePath &source, const Utils::FilePath &destination)
|
||||||
{
|
{
|
||||||
d->installPluginOnNextRestart(source, destination);
|
d->installPluginOnRestart(source, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -1710,11 +1710,6 @@ PluginSpec *PluginManager::specForPlugin(IPlugin *plugin)
|
|||||||
return findOrDefault(d->pluginSpecs, equal(&PluginSpec::plugin, plugin));
|
return findOrDefault(d->pluginSpecs, equal(&PluginSpec::plugin, plugin));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PluginManager::takePluginIdForRemoval(const QString &id)
|
|
||||||
{
|
|
||||||
return d->m_pluginsToRemove.remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString pluginListString(const QSet<PluginSpec *> &plugins)
|
static QString pluginListString(const QSet<PluginSpec *> &plugins)
|
||||||
{
|
{
|
||||||
QStringList names = Utils::transform<QList>(plugins, &PluginSpec::name);
|
QStringList names = Utils::transform<QList>(plugins, &PluginSpec::name);
|
||||||
@@ -1925,36 +1920,6 @@ static const FilePaths pluginFiles(const FilePaths &pluginPaths)
|
|||||||
return pluginFiles;
|
return pluginFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PluginManagerPrivate::removePlugin(const QString &pluginId)
|
|
||||||
{
|
|
||||||
PluginSpec *existingSpec
|
|
||||||
= Utils::findOrDefault(pluginSpecs, Utils::equal(&PluginSpec::id, pluginId));
|
|
||||||
|
|
||||||
if (existingSpec) {
|
|
||||||
QTC_ASSERT(existingSpec->state() == PluginSpec::State::Resolved, return false);
|
|
||||||
|
|
||||||
const Result removeResult = existingSpec->removePluginFiles();
|
|
||||||
if (!removeResult) {
|
|
||||||
qCWarning(pluginLog) << "Failed to remove plugin files for" << pluginId << ":"
|
|
||||||
<< removeResult.error();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (QList<PluginSpec *> &category : pluginCategories) {
|
|
||||||
category.removeOne(existingSpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pluginSpecs.removeOne(existingSpec)) {
|
|
||||||
delete existingSpec;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is used by other plugin managers like Lua that is not loaded yet.
|
|
||||||
m_pluginsToRemove << pluginId;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginManagerPrivate::addPlugins(const PluginSpecs &specs)
|
void PluginManagerPrivate::addPlugins(const PluginSpecs &specs)
|
||||||
{
|
{
|
||||||
pluginSpecs += specs;
|
pluginSpecs += specs;
|
||||||
@@ -1987,11 +1952,24 @@ void PluginManagerPrivate::addPlugins(const PluginSpecs &specs)
|
|||||||
static const char PLUGINS_TO_INSTALL_KEY[] = "PluginsToInstall";
|
static const char PLUGINS_TO_INSTALL_KEY[] = "PluginsToInstall";
|
||||||
static const char PLUGINS_TO_REMOVE_KEY[] = "PluginsToRemove";
|
static const char PLUGINS_TO_REMOVE_KEY[] = "PluginsToRemove";
|
||||||
|
|
||||||
void PluginManagerPrivate::removePluginOnNextRestart(const QString &pluginId)
|
Result PluginManagerPrivate::removePluginOnRestart(const QString &pluginId)
|
||||||
{
|
{
|
||||||
settings->setValue(
|
const PluginSpec *pluginSpec
|
||||||
PLUGINS_TO_REMOVE_KEY, settings->value(PLUGINS_TO_REMOVE_KEY).toStringList() << pluginId);
|
= findOrDefault(pluginSpecs, Utils::equal(&PluginSpec::id, pluginId));
|
||||||
|
|
||||||
|
if (!pluginSpec)
|
||||||
|
return Result::Error(Tr::tr("Plugin not found."));
|
||||||
|
|
||||||
|
const expected_str<FilePaths> filePaths = pluginSpec->filesToUninstall();
|
||||||
|
if (!filePaths)
|
||||||
|
return Result::Error(filePaths.error());
|
||||||
|
|
||||||
|
const QVariantList list = Utils::transform(*filePaths, &FilePath::toVariant);
|
||||||
|
|
||||||
|
settings->setValue(PLUGINS_TO_REMOVE_KEY, settings->value(PLUGINS_TO_REMOVE_KEY).toList() + list);
|
||||||
|
|
||||||
settings->sync();
|
settings->sync();
|
||||||
|
return Result::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QList<QPair<FilePath, FilePath>> readPluginInstallList(QtcSettings *settings)
|
static QList<QPair<FilePath, FilePath>> readPluginInstallList(QtcSettings *settings)
|
||||||
@@ -2009,7 +1987,7 @@ static QList<QPair<FilePath, FilePath>> readPluginInstallList(QtcSettings *setti
|
|||||||
return installList;
|
return installList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginManagerPrivate::installPluginOnNextRestart(
|
void PluginManagerPrivate::installPluginOnRestart(
|
||||||
const Utils::FilePath &src, const Utils::FilePath &dest)
|
const Utils::FilePath &src, const Utils::FilePath &dest)
|
||||||
{
|
{
|
||||||
const QList<QPair<FilePath, FilePath>> list = readPluginInstallList(settings)
|
const QList<QPair<FilePath, FilePath>> list = readPluginInstallList(settings)
|
||||||
@@ -2028,9 +2006,19 @@ void PluginManagerPrivate::installPluginOnNextRestart(
|
|||||||
|
|
||||||
void PluginManagerPrivate::removePluginsAfterRestart()
|
void PluginManagerPrivate::removePluginsAfterRestart()
|
||||||
{
|
{
|
||||||
const QStringList removeList = settings->value(PLUGINS_TO_REMOVE_KEY).toStringList();
|
const FilePaths removeList
|
||||||
for (const QString &pluginId : removeList)
|
= Utils::transform(settings->value(PLUGINS_TO_REMOVE_KEY).toList(), &FilePath::fromVariant);
|
||||||
removePlugin(pluginId);
|
|
||||||
|
for (const FilePath &path : removeList) {
|
||||||
|
Result r = Result::Error(Tr::tr("It does not exist."));
|
||||||
|
if (path.isFile())
|
||||||
|
r = path.removeFile();
|
||||||
|
else if (path.isDir())
|
||||||
|
r = path.removeRecursively();
|
||||||
|
|
||||||
|
if (!r)
|
||||||
|
qCWarning(pluginLog()) << "Failed to remove" << path << ":" << r.error();
|
||||||
|
}
|
||||||
|
|
||||||
settings->remove(PLUGINS_TO_REMOVE_KEY);
|
settings->remove(PLUGINS_TO_REMOVE_KEY);
|
||||||
}
|
}
|
||||||
|
@@ -80,13 +80,12 @@ public:
|
|||||||
static const QSet<PluginSpec *> pluginsRequiredByPlugin(PluginSpec *spec);
|
static const QSet<PluginSpec *> pluginsRequiredByPlugin(PluginSpec *spec);
|
||||||
static void checkForProblematicPlugins();
|
static void checkForProblematicPlugins();
|
||||||
static PluginSpec *specForPlugin(IPlugin *plugin);
|
static PluginSpec *specForPlugin(IPlugin *plugin);
|
||||||
static bool takePluginIdForRemoval(const QString &id);
|
|
||||||
|
|
||||||
static void addPlugins(const QVector<PluginSpec *> &specs);
|
static void addPlugins(const QVector<PluginSpec *> &specs);
|
||||||
|
|
||||||
static void reInstallPlugins();
|
static void reInstallPlugins();
|
||||||
|
|
||||||
static void removePluginOnRestart(const QString &id);
|
static Utils::Result removePluginOnRestart(const QString &id);
|
||||||
static void installPluginOnRestart(
|
static void installPluginOnRestart(
|
||||||
const Utils::FilePath &source, const Utils::FilePath &destination);
|
const Utils::FilePath &source, const Utils::FilePath &destination);
|
||||||
|
|
||||||
|
@@ -52,8 +52,6 @@ public:
|
|||||||
void loadPluginsAtRuntime(const QSet<PluginSpec *> &plugins);
|
void loadPluginsAtRuntime(const QSet<PluginSpec *> &plugins);
|
||||||
void addPlugins(const QVector<PluginSpec *> &specs);
|
void addPlugins(const QVector<PluginSpec *> &specs);
|
||||||
|
|
||||||
bool removePlugin(const QString &pluginId);
|
|
||||||
|
|
||||||
void shutdown();
|
void shutdown();
|
||||||
void setPluginPaths(const Utils::FilePaths &paths);
|
void setPluginPaths(const Utils::FilePaths &paths);
|
||||||
const QVector<ExtensionSystem::PluginSpec *> loadQueue();
|
const QVector<ExtensionSystem::PluginSpec *> loadQueue();
|
||||||
@@ -77,8 +75,8 @@ public:
|
|||||||
void removePluginsAfterRestart();
|
void removePluginsAfterRestart();
|
||||||
void installPluginsAfterRestart();
|
void installPluginsAfterRestart();
|
||||||
|
|
||||||
void removePluginOnNextRestart(const QString &pluginId);
|
Utils::Result removePluginOnRestart(const QString &pluginId);
|
||||||
void installPluginOnNextRestart(const Utils::FilePath &src, const Utils::FilePath &dest);
|
void installPluginOnRestart(const Utils::FilePath &src, const Utils::FilePath &dest);
|
||||||
|
|
||||||
class TestSpec {
|
class TestSpec {
|
||||||
public:
|
public:
|
||||||
@@ -152,8 +150,6 @@ public:
|
|||||||
|
|
||||||
PluginManager::ProcessData m_creatorProcessData;
|
PluginManager::ProcessData m_creatorProcessData;
|
||||||
|
|
||||||
QSet<QString> m_pluginsToRemove;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PluginManager *q;
|
PluginManager *q;
|
||||||
|
|
||||||
|
@@ -1453,27 +1453,27 @@ QList<PluginSpec *> pluginSpecsFromArchive(const Utils::FilePath &path)
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Result PluginSpec::removePluginFiles() const
|
expected_str<FilePaths> PluginSpec::filesToUninstall() const
|
||||||
{
|
{
|
||||||
if (isSystemPlugin())
|
if (isSystemPlugin())
|
||||||
return Result::Error(Tr::tr("Cannot remove system plugins."));
|
return make_unexpected(Tr::tr("Cannot remove system plugins."));
|
||||||
|
|
||||||
// Try to figure out where we are ...
|
// Try to figure out where we are ...
|
||||||
const Utils::FilePaths pluginPaths = PluginManager::pluginPaths();
|
const FilePaths pluginPaths = PluginManager::pluginPaths();
|
||||||
|
|
||||||
for (const FilePath &pluginPath : pluginPaths) {
|
for (const FilePath &pluginPath : pluginPaths) {
|
||||||
if (location().isChildOf(pluginPath)) {
|
if (location().isChildOf(pluginPath)) {
|
||||||
const FilePath rootFolder = location().relativeChildPath(pluginPath);
|
const FilePath rootFolder = location().relativeChildPath(pluginPath);
|
||||||
if (rootFolder.isEmpty())
|
if (rootFolder.isEmpty())
|
||||||
return Result::Error(Tr::tr("Could not determine root folder."));
|
return make_unexpected(Tr::tr("Could not determine root folder."));
|
||||||
|
|
||||||
const FilePath pathToDelete = pluginPath
|
const FilePath pathToDelete = pluginPath
|
||||||
/ rootFolder.pathComponents().first().toString();
|
/ rootFolder.pathComponents().first().toString();
|
||||||
return pathToDelete.removeRecursively();
|
return FilePaths{pathToDelete};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return filePath().removeFile();
|
return FilePaths{filePath()};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PluginSpec::isSystemPlugin() const
|
bool PluginSpec::isSystemPlugin() const
|
||||||
|
@@ -161,7 +161,7 @@ public:
|
|||||||
|
|
||||||
virtual Utils::FilePath installLocation(bool inUserFolder) const = 0;
|
virtual Utils::FilePath installLocation(bool inUserFolder) const = 0;
|
||||||
|
|
||||||
virtual Utils::Result removePluginFiles() const;
|
virtual Utils::expected_str<Utils::FilePaths> filesToUninstall() const;
|
||||||
virtual bool isSystemPlugin() const;
|
virtual bool isSystemPlugin() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@@ -515,6 +515,14 @@ InstallResult executePluginInstallWizard(const FilePath &archive, bool prepareFo
|
|||||||
/ extensionId(data.pluginSpec.get());
|
/ extensionId(data.pluginSpec.get());
|
||||||
|
|
||||||
if (prepareForUpdate) {
|
if (prepareForUpdate) {
|
||||||
|
const Result result = ExtensionSystem::PluginManager::removePluginOnRestart(
|
||||||
|
data.pluginSpec->id());
|
||||||
|
if (!result) {
|
||||||
|
qWarning() << "Failed to remove plugin" << data.pluginSpec->id() << ":"
|
||||||
|
<< result.error();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (hasLibSuffix(data.sourcePath)) {
|
if (hasLibSuffix(data.sourcePath)) {
|
||||||
ExtensionSystem::PluginManager::installPluginOnRestart(
|
ExtensionSystem::PluginManager::installPluginOnRestart(
|
||||||
data.pluginSpec->filePath(), installPath);
|
data.pluginSpec->filePath(), installPath);
|
||||||
|
@@ -446,19 +446,6 @@ public:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PluginManager::takePluginIdForRemoval((*result)->id())) {
|
|
||||||
auto removeResult = (*result)->removePluginFiles();
|
|
||||||
if (!removeResult) {
|
|
||||||
qWarning() << "Failed to remove plugin files" << script << ":"
|
|
||||||
<< removeResult.error();
|
|
||||||
MessageManager::writeFlashing(
|
|
||||||
Tr::tr("Failed to remove plugin files of %1: %2")
|
|
||||||
.arg((*result)->id())
|
|
||||||
.arg(removeResult.error()));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins.insert(*result);
|
plugins.insert(*result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user