forked from qt-creator/qt-creator
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:
@@ -73,7 +73,7 @@ enum { defaultMaxHangTimerCount = 10 };
|
||||
|
||||
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)
|
||||
class ChannelBuffer
|
||||
@@ -225,8 +225,8 @@ void QtcProcess::start()
|
||||
QTC_CHECK(d->m_writeData.isEmpty()); // FIXME: Use it.
|
||||
|
||||
if (d->m_commandLine.executable().needsDevice()) {
|
||||
QTC_ASSERT(s_remoteRunProcessHook, return);
|
||||
s_remoteRunProcessHook(*this);
|
||||
QTC_ASSERT(s_deviceHooks.startProcessHook, return);
|
||||
s_deviceHooks.startProcessHook(*this);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -336,9 +336,9 @@ void QtcProcess::setDisableUnixTerminal()
|
||||
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)
|
||||
@@ -561,6 +561,16 @@ QString QtcProcess::locateBinary(const QString &path, const QString &binary)
|
||||
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)
|
||||
{
|
||||
const QByteArray path = qgetenv("PATH");
|
||||
|
@@ -41,9 +41,17 @@ namespace Utils {
|
||||
|
||||
class CommandLine;
|
||||
class Environment;
|
||||
class QtcProcess;
|
||||
|
||||
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
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -92,7 +100,7 @@ public:
|
||||
void setStdOutCallback(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);
|
||||
|
||||
@@ -123,6 +131,8 @@ public:
|
||||
static QString locateBinary(const QString &binary);
|
||||
static QString locateBinary(const QString &path, const QString &binary);
|
||||
|
||||
static Environment systemEnvironmentForBinary(const FilePath &filePath);
|
||||
|
||||
private:
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
void setupChildProcess() override;
|
||||
|
@@ -363,59 +363,69 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
|
||||
connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested,
|
||||
this, &DeviceManager::save);
|
||||
|
||||
DeviceFileHooks hooks;
|
||||
DeviceFileHooks deviceHooks;
|
||||
|
||||
hooks.isExecutableFile = [](const FilePath &filePath) {
|
||||
deviceHooks.isExecutableFile = [](const FilePath &filePath) {
|
||||
auto device = DeviceManager::deviceForPath(filePath);
|
||||
QTC_ASSERT(device, return false);
|
||||
return device->isExecutableFile(filePath);
|
||||
};
|
||||
|
||||
hooks.isReadableFile = [](const FilePath &filePath) {
|
||||
deviceHooks.isReadableFile = [](const FilePath &filePath) {
|
||||
auto device = DeviceManager::deviceForPath(filePath);
|
||||
QTC_ASSERT(device, return false);
|
||||
return device->isReadableFile(filePath);
|
||||
};
|
||||
|
||||
hooks.isReadableDir = [](const FilePath &filePath) {
|
||||
deviceHooks.isReadableDir = [](const FilePath &filePath) {
|
||||
auto device = DeviceManager::deviceForPath(filePath);
|
||||
QTC_ASSERT(device, return false);
|
||||
return device->isReadableDirectory(filePath);
|
||||
};
|
||||
|
||||
hooks.isWritableDir = [](const FilePath &filePath) {
|
||||
deviceHooks.isWritableDir = [](const FilePath &filePath) {
|
||||
auto device = DeviceManager::deviceForPath(filePath);
|
||||
QTC_ASSERT(device, return false);
|
||||
return device->isWritableDirectory(filePath);
|
||||
};
|
||||
|
||||
hooks.createDir = [](const FilePath &filePath) {
|
||||
deviceHooks.createDir = [](const FilePath &filePath) {
|
||||
auto device = DeviceManager::deviceForPath(filePath);
|
||||
QTC_ASSERT(device, return false);
|
||||
return device->createDirectory(filePath);
|
||||
};
|
||||
|
||||
hooks.dirEntries = [](const FilePath &filePath,
|
||||
deviceHooks.dirEntries = [](const FilePath &filePath,
|
||||
const QStringList &nameFilters, QDir::Filters filters) {
|
||||
auto device = DeviceManager::deviceForPath(filePath);
|
||||
QTC_ASSERT(device, return FilePaths());
|
||||
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);
|
||||
QTC_ASSERT(device, return QByteArray());
|
||||
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();
|
||||
auto device = DeviceManager::deviceForPath(filePath);
|
||||
QTC_ASSERT(device, return);
|
||||
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()
|
||||
|
Reference in New Issue
Block a user