Utils: Use a structure to specify several QtcProcess device hooks

... and add a QtcProcess::systemEnvironmentForBinary(filePath)
redirecting to IDevice::systemEnvironment() of the device implicitly
given by filePath. A device implied by e.g. a qmake binary or a compiler
binary is a common scenario.

Change-Id: Ieb2c724ae66f1a1752132e4e4648a604390ca369
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2021-05-26 17:40:57 +02:00
parent 125cdcc3a0
commit 6de05306d6
3 changed files with 47 additions and 17 deletions

View File

@@ -73,7 +73,7 @@ enum { defaultMaxHangTimerCount = 10 };
static Q_LOGGING_CATEGORY(processLog, "qtc.utils.synchronousprocess", QtWarningMsg); static Q_LOGGING_CATEGORY(processLog, "qtc.utils.synchronousprocess", QtWarningMsg);
static std::function<void(QtcProcess &)> s_remoteRunProcessHook; static DeviceProcessHooks s_deviceHooks;
// Data for one channel buffer (stderr/stdout) // Data for one channel buffer (stderr/stdout)
class ChannelBuffer class ChannelBuffer
@@ -225,8 +225,8 @@ void QtcProcess::start()
QTC_CHECK(d->m_writeData.isEmpty()); // FIXME: Use it. QTC_CHECK(d->m_writeData.isEmpty()); // FIXME: Use it.
if (d->m_commandLine.executable().needsDevice()) { if (d->m_commandLine.executable().needsDevice()) {
QTC_ASSERT(s_remoteRunProcessHook, return); QTC_ASSERT(s_deviceHooks.startProcessHook, return);
s_remoteRunProcessHook(*this); s_deviceHooks.startProcessHook(*this);
return; return;
} }
@@ -336,9 +336,9 @@ void QtcProcess::setDisableUnixTerminal()
d->m_disableUnixTerminal = true; d->m_disableUnixTerminal = true;
} }
void QtcProcess::setRemoteStartProcessHook(const std::function<void(QtcProcess &)> &hook) void QtcProcess::setRemoteProcessHooks(const DeviceProcessHooks &hooks)
{ {
s_remoteRunProcessHook = hook; s_deviceHooks = hooks;
} }
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -561,6 +561,16 @@ QString QtcProcess::locateBinary(const QString &path, const QString &binary)
return QString(); return QString();
} }
Environment QtcProcess::systemEnvironmentForBinary(const FilePath &filePath)
{
if (filePath.needsDevice()) {
QTC_ASSERT(s_deviceHooks.systemEnvironmentForBinary, return {});
return s_deviceHooks.systemEnvironmentForBinary(filePath);
}
return Environment::systemEnvironment();
}
QString QtcProcess::locateBinary(const QString &binary) QString QtcProcess::locateBinary(const QString &binary)
{ {
const QByteArray path = qgetenv("PATH"); const QByteArray path = qgetenv("PATH");

View File

@@ -41,9 +41,17 @@ namespace Utils {
class CommandLine; class CommandLine;
class Environment; class Environment;
class QtcProcess;
namespace Internal { class QtcProcessPrivate; } namespace Internal { class QtcProcessPrivate; }
class DeviceProcessHooks
{
public:
std::function<void(QtcProcess &)> startProcessHook;
std::function<Environment(const FilePath &)> systemEnvironmentForBinary;
};
class QTCREATOR_UTILS_EXPORT QtcProcess : public QProcess class QTCREATOR_UTILS_EXPORT QtcProcess : public QProcess
{ {
Q_OBJECT Q_OBJECT
@@ -92,7 +100,7 @@ public:
void setStdOutCallback(const std::function<void(const QString &)> &callback); void setStdOutCallback(const std::function<void(const QString &)> &callback);
void setStdErrCallback(const std::function<void(const QString &)> &callback); void setStdErrCallback(const std::function<void(const QString &)> &callback);
static void setRemoteStartProcessHook(const std::function<void (QtcProcess &)> &hook); static void setRemoteProcessHooks(const DeviceProcessHooks &hooks);
void setOpenMode(OpenMode mode); void setOpenMode(OpenMode mode);
@@ -123,6 +131,8 @@ public:
static QString locateBinary(const QString &binary); static QString locateBinary(const QString &binary);
static QString locateBinary(const QString &path, const QString &binary); static QString locateBinary(const QString &path, const QString &binary);
static Environment systemEnvironmentForBinary(const FilePath &filePath);
private: private:
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
void setupChildProcess() override; void setupChildProcess() override;

View File

@@ -363,59 +363,69 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested,
this, &DeviceManager::save); this, &DeviceManager::save);
DeviceFileHooks hooks; DeviceFileHooks deviceHooks;
hooks.isExecutableFile = [](const FilePath &filePath) { deviceHooks.isExecutableFile = [](const FilePath &filePath) {
auto device = DeviceManager::deviceForPath(filePath); auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return false); QTC_ASSERT(device, return false);
return device->isExecutableFile(filePath); return device->isExecutableFile(filePath);
}; };
hooks.isReadableFile = [](const FilePath &filePath) { deviceHooks.isReadableFile = [](const FilePath &filePath) {
auto device = DeviceManager::deviceForPath(filePath); auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return false); QTC_ASSERT(device, return false);
return device->isReadableFile(filePath); return device->isReadableFile(filePath);
}; };
hooks.isReadableDir = [](const FilePath &filePath) { deviceHooks.isReadableDir = [](const FilePath &filePath) {
auto device = DeviceManager::deviceForPath(filePath); auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return false); QTC_ASSERT(device, return false);
return device->isReadableDirectory(filePath); return device->isReadableDirectory(filePath);
}; };
hooks.isWritableDir = [](const FilePath &filePath) { deviceHooks.isWritableDir = [](const FilePath &filePath) {
auto device = DeviceManager::deviceForPath(filePath); auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return false); QTC_ASSERT(device, return false);
return device->isWritableDirectory(filePath); return device->isWritableDirectory(filePath);
}; };
hooks.createDir = [](const FilePath &filePath) { deviceHooks.createDir = [](const FilePath &filePath) {
auto device = DeviceManager::deviceForPath(filePath); auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return false); QTC_ASSERT(device, return false);
return device->createDirectory(filePath); return device->createDirectory(filePath);
}; };
hooks.dirEntries = [](const FilePath &filePath, deviceHooks.dirEntries = [](const FilePath &filePath,
const QStringList &nameFilters, QDir::Filters filters) { const QStringList &nameFilters, QDir::Filters filters) {
auto device = DeviceManager::deviceForPath(filePath); auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return FilePaths()); QTC_ASSERT(device, return FilePaths());
return device->directoryEntries(filePath, nameFilters, filters); return device->directoryEntries(filePath, nameFilters, filters);
}; };
hooks.fileContents = [](const FilePath &filePath, int maxSize) { deviceHooks.fileContents = [](const FilePath &filePath, int maxSize) {
auto device = DeviceManager::deviceForPath(filePath); auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return QByteArray()); QTC_ASSERT(device, return QByteArray());
return device->fileContents(filePath, maxSize); return device->fileContents(filePath, maxSize);
}; };
FilePath::setDeviceFileHooks(hooks); FilePath::setDeviceFileHooks(deviceHooks);
QtcProcess::setRemoteStartProcessHook([](QtcProcess &process) { DeviceProcessHooks processHooks;
processHooks.startProcessHook = [](QtcProcess &process) {
FilePath filePath = process.commandLine().executable(); FilePath filePath = process.commandLine().executable();
auto device = DeviceManager::deviceForPath(filePath); auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return); QTC_ASSERT(device, return);
device->runProcess(process); device->runProcess(process);
}); };
processHooks.systemEnvironmentForBinary = [](const FilePath &filePath) {
auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return Environment());
return device->systemEnvironment();
};
QtcProcess::setRemoteProcessHooks(processHooks);
} }
DeviceManager::~DeviceManager() DeviceManager::~DeviceManager()