From 18245dcf1083a19e592254fd5e1337fcde1abf4a Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 7 Jun 2021 15:47:06 +0200 Subject: [PATCH] Utils/ProjectExplorer: Add IDevice::searchInPath Change-Id: Ibc7cc7bd6bf3a7776681f7cd2fff051525b19f60 Reviewed-by: David Schulz --- src/libs/utils/fileutils.cpp | 21 +++++++++++++++++++ src/libs/utils/fileutils.h | 3 +++ src/plugins/docker/dockerdevice.cpp | 18 ++++++++++++++++ src/plugins/docker/dockerdevice.h | 1 + .../devicesupport/devicemanager.cpp | 6 ++++++ .../projectexplorer/devicesupport/idevice.cpp | 5 +++++ .../projectexplorer/devicesupport/idevice.h | 1 + 7 files changed, 55 insertions(+) diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index d0ab78eaaba..a08f7ba98d6 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -28,6 +28,7 @@ #include "algorithm.h" #include "commandline.h" +#include "environment.h" #include "qtcassert.h" #include @@ -1277,6 +1278,26 @@ FilePath FilePath::onDevice(const FilePath &deviceTemplate) const return res; } +/*! + Searched a binary corresponding to this object in the PATH of + the device implied by this object's scheme and host. + + Example usage: + \code + binary = FilePath::fromUrl("docker://123/./make); + fullPath = binary.onDeviceSearchInPath(); + assert(fullPath == FilePath::fromUrl("docker://123/usr/bin/make")) + \endcode +*/ +FilePath FilePath::onDeviceSearchInPath() const +{ + if (needsDevice()) { + QTC_ASSERT(s_deviceHooks.searchInPath, return {}); + return s_deviceHooks.searchInPath(*this); + } + return Environment::systemEnvironment().searchInPath(path()); +} + FilePath FilePath::pathAppended(const QString &path) const { FilePath fn = *this; diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index f319d1ac392..3e584a41dd5 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -76,6 +76,7 @@ public: std::function ensureWritableDir; std::function createDir; std::function exists; + std::function searchInPath; std::function(const FilePath &, const QStringList &, QDir::Filters)> dirEntries; std::function fileContents; }; @@ -180,6 +181,8 @@ public: static void setDeviceFileHooks(const DeviceFileHooks &hooks); + FilePath onDeviceSearchInPath() const; + private: friend class ::tst_fileutils; static QString calcRelativePath(const QString &absolutePath, const QString &absoluteAnchorPath); diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index a79dcbf9174..005a772fbf2 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -719,6 +719,24 @@ bool DockerDevice::exists(const FilePath &filePath) const return exitCode == 0; } +FilePath DockerDevice::searchInPath(const FilePath &filePath) const +{ + const QString path = filePath.path(); + + CommandLine dcmd{"docker", {"exec", d->m_container, "which", path}}; + QtcProcess proc; + proc.setCommand(dcmd); + proc.setWorkingDirectory("/tmp"); + proc.start(); + proc.waitForFinished(); + + LOG("Run sync:" << dcmd.toUserOutput() << " result: " << proc.exitCode()); + QTC_ASSERT(proc.exitCode() == 0, return filePath); + + const QString output = proc.stdOut(); + return mapToGlobalPath(FilePath::fromString(output)); +} + QList DockerDevice::directoryEntries(const FilePath &filePath, const QStringList &nameFilters, QDir::Filters filters) const diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index 63b4990f0b3..57f3f366f2a 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -81,6 +81,7 @@ public: bool isWritableDirectory(const Utils::FilePath &filePath) const override; bool createDirectory(const Utils::FilePath &filePath) const override; bool exists(const Utils::FilePath &filePath) const override; + Utils::FilePath searchInPath(const Utils::FilePath &filePath) const override; QList directoryEntries(const Utils::FilePath &filePath, const QStringList &nameFilters, QDir::Filters filters) const override; diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index ded1f27f7d0..cf5f27ece75 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -416,6 +416,12 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_uniqueexists(filePath); }; + deviceHooks.searchInPath = [](const FilePath &filePath) { + auto device = DeviceManager::deviceForPath(filePath); + QTC_ASSERT(device, return FilePath{}); + return device->searchInPath(filePath); + }; + deviceHooks.dirEntries = [](const FilePath &filePath, const QStringList &nameFilters, QDir::Filters filters) { auto device = DeviceManager::deviceForPath(filePath); diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index c9b3338097d..90a144767c1 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -266,6 +266,11 @@ bool IDevice::exists(const Utils::FilePath &filePath) const return false; } +FilePath IDevice::searchInPath(const FilePath &filePath) const +{ + return Environment::systemEnvironment().searchInPath(filePath.path()); +} + QList IDevice::directoryEntries(const FilePath &filePath, const QStringList &nameFilters, QDir::Filters filters) const diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index eb00f21d5e1..0fe627726eb 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -243,6 +243,7 @@ public: virtual bool ensureWritableDirectory(const Utils::FilePath &filePath) const; virtual bool createDirectory(const Utils::FilePath &filePath) const; virtual bool exists(const Utils::FilePath &filePath) const; + virtual Utils::FilePath searchInPath(const Utils::FilePath &filePath) const; virtual QList directoryEntries(const Utils::FilePath &filePath, const QStringList &nameFilters, QDir::Filters filters) const;