forked from qt-creator/qt-creator
Python: optimize venv and pip checks
Checking for the venv and pip module can take some time. Since this is done now whenever the kits are validated this has performance implications for multiple actions. For example showing the target selector wizard page or opening/switching sessions. Use a cache to reduce the number of python processes started to check the existence of the modules, and if the module can be found store that info in a persistent store to avoid checking it again after a restart. Change-Id: Ib899da0e6b2da28fbee2b5baff7f923e4595260a Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/mimeutils.h>
|
||||
#include <utils/persistentcachestore.h>
|
||||
#include <utils/process.h>
|
||||
|
||||
#include <QReadLocker>
|
||||
@@ -169,8 +170,8 @@ PythonProject *pythonProjectForFile(const FilePath &pythonFile)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void createVenv(const Utils::FilePath &python,
|
||||
const Utils::FilePath &venvPath,
|
||||
void createVenv(const FilePath &python,
|
||||
const FilePath &venvPath,
|
||||
const std::function<void(bool)> &callback)
|
||||
{
|
||||
QTC_ASSERT(python.isExecutableFile(), callback(false); return);
|
||||
@@ -189,25 +190,57 @@ void createVenv(const Utils::FilePath &python,
|
||||
process->start();
|
||||
}
|
||||
|
||||
bool isVenvPython(const Utils::FilePath &python)
|
||||
bool isVenvPython(const FilePath &python)
|
||||
{
|
||||
return python.parentDir().parentDir().contains("pyvenv.cfg");
|
||||
}
|
||||
|
||||
bool venvIsUsable(const Utils::FilePath &python)
|
||||
bool venvIsUsable(const FilePath &python)
|
||||
{
|
||||
Process process;
|
||||
process.setCommand({python, QStringList{"-m", "venv", "-h"}});
|
||||
process.runBlocking();
|
||||
return process.result() == ProcessResult::FinishedWithSuccess;
|
||||
static QHash<FilePath, bool> cache;
|
||||
auto it = cache.find(python);
|
||||
if (it == cache.end()) {
|
||||
auto store = PersistentCacheStore::byKey(keyFromString("pyVenvIsUsable"));
|
||||
if (store && store->value(keyFromString(python.toString())).toBool()) {
|
||||
cache.insert(python, true);
|
||||
return true;
|
||||
}
|
||||
Process process;
|
||||
process.setCommand({python, QStringList{"-m", "venv", "-h"}});
|
||||
process.runBlocking();
|
||||
const bool usable = process.result() == ProcessResult::FinishedWithSuccess;
|
||||
if (usable) {
|
||||
Store newStore = store.value_or(Store{});
|
||||
newStore.insert(keyFromString(python.toString()), true);
|
||||
PersistentCacheStore::write(keyFromString("pyVenvIsUsable"), newStore);
|
||||
}
|
||||
it = cache.insert(python, usable);
|
||||
}
|
||||
return *it;
|
||||
}
|
||||
|
||||
bool pipIsUsable(const Utils::FilePath &python)
|
||||
bool pipIsUsable(const FilePath &python)
|
||||
{
|
||||
Process process;
|
||||
process.setCommand({python, QStringList{"-m", "pip", "-V"}});
|
||||
process.runBlocking();
|
||||
return process.result() == ProcessResult::FinishedWithSuccess;
|
||||
static QHash<FilePath, bool> cache;
|
||||
auto it = cache.find(python);
|
||||
if (it == cache.end()) {
|
||||
auto store = PersistentCacheStore::byKey(keyFromString("pyPipIsUsable"));
|
||||
if (store && store->value(keyFromString(python.toString())).toBool()) {
|
||||
cache.insert(python, true);
|
||||
return true;
|
||||
}
|
||||
Process process;
|
||||
process.setCommand({python, QStringList{"-m", "pip", "-h"}});
|
||||
process.runBlocking();
|
||||
const bool usable = process.result() == ProcessResult::FinishedWithSuccess;
|
||||
if (usable) {
|
||||
Store newStore = store.value_or(Store{});
|
||||
newStore.insert(keyFromString(python.toString()), true);
|
||||
PersistentCacheStore::write(keyFromString("pyPipIsUsable"), newStore);
|
||||
}
|
||||
it = cache.insert(python, usable);
|
||||
}
|
||||
return *it;
|
||||
}
|
||||
|
||||
QString pythonVersion(const FilePath &python)
|
||||
@@ -225,7 +258,7 @@ QString pythonVersion(const FilePath &python)
|
||||
Process p;
|
||||
p.setCommand({python, {"--version"}});
|
||||
p.runBlocking();
|
||||
if (p.result() == Utils::ProcessResult::FinishedWithSuccess) {
|
||||
if (p.result() == ProcessResult::FinishedWithSuccess) {
|
||||
const QString version = p.readAllStandardOutput().trimmed();
|
||||
QWriteLocker locker(&lock);
|
||||
versionCache.insert(python, version);
|
||||
|
||||
Reference in New Issue
Block a user