Utils: Support remote FilePath::{lastModified,{remove,copy}File}

And implement the Docker variant.

Change-Id: Iee7cd0aaaf3d5c7dbb4ff995ac6889f31cb2f505
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2021-06-14 08:33:44 +02:00
parent 4a04e75a4d
commit a5b16f8137
7 changed files with 124 additions and 4 deletions

View File

@@ -1346,10 +1346,31 @@ uint FilePath::hash(uint seed) const
QDateTime FilePath::lastModified() const QDateTime FilePath::lastModified() const
{ {
QTC_CHECK(!needsDevice()); if (needsDevice()) {
QTC_ASSERT(s_deviceHooks.lastModified, return {});
return s_deviceHooks.lastModified(*this);
}
return toFileInfo().lastModified(); return toFileInfo().lastModified();
} }
bool FilePath::removeFile() const
{
if (needsDevice()) {
QTC_ASSERT(s_deviceHooks.removeFile, return false);
return s_deviceHooks.removeFile(*this);
}
return QFile::remove(path());
}
bool FilePath::copyFile(const FilePath &target) const
{
if (needsDevice()) {
QTC_ASSERT(s_deviceHooks.copyFile, return false);
return s_deviceHooks.copyFile(*this, target);
}
return QFile::copy(path(), target.path());
}
QTextStream &operator<<(QTextStream &s, const FilePath &fn) QTextStream &operator<<(QTextStream &s, const FilePath &fn)
{ {
return s << fn.toString(); return s << fn.toString();

View File

@@ -76,9 +76,12 @@ public:
std::function<bool(const FilePath &)> ensureWritableDir; std::function<bool(const FilePath &)> ensureWritableDir;
std::function<bool(const FilePath &)> createDir; std::function<bool(const FilePath &)> createDir;
std::function<bool(const FilePath &)> exists; std::function<bool(const FilePath &)> exists;
std::function<bool(const FilePath &)> removeFile;
std::function<bool(const FilePath &, const FilePath &)> copyFile;
std::function<FilePath(const FilePath &)> searchInPath; std::function<FilePath(const FilePath &)> searchInPath;
std::function<QList<FilePath>(const FilePath &, const QStringList &, QDir::Filters)> dirEntries; std::function<QList<FilePath>(const FilePath &, const QStringList &, QDir::Filters)> dirEntries;
std::function<QByteArray(const FilePath &, int)> fileContents; std::function<QByteArray(const FilePath &, int)> fileContents;
std::function<QDateTime(const FilePath &)> lastModified;
}; };
class QTCREATOR_UTILS_EXPORT FilePath class QTCREATOR_UTILS_EXPORT FilePath
@@ -155,6 +158,9 @@ public:
bool isDir() const; bool isDir() const;
bool isNewerThan(const QDateTime &timeStamp) const; bool isNewerThan(const QDateTime &timeStamp) const;
QDateTime lastModified() const;
bool removeFile() const;
bool copyFile(const FilePath &target) const;
Qt::CaseSensitivity caseSensitivity() const; Qt::CaseSensitivity caseSensitivity() const;
@@ -174,7 +180,6 @@ public:
bool isEmpty() const; bool isEmpty() const;
uint hash(uint seed) const; uint hash(uint seed) const;
QDateTime lastModified() const;
// NOTE: Most FilePath operations on FilePath created from URL currently // NOTE: Most FilePath operations on FilePath created from URL currently
// do not work. Among the working are .toVariant() and .toUrl(). // do not work. Among the working are .toVariant() and .toUrl().

View File

@@ -59,6 +59,7 @@
#include <utils/treemodel.h> #include <utils/treemodel.h>
#include <QApplication> #include <QApplication>
#include <QDateTime>
#include <QDialog> #include <QDialog>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
@@ -788,6 +789,52 @@ bool DockerDevice::exists(const FilePath &filePath) const
return exitCode == 0; return exitCode == 0;
} }
bool DockerDevice::removeFile(const FilePath &filePath) const
{
QTC_ASSERT(handlesFile(filePath), return false);
tryCreateLocalFileAccess();
if (hasLocalFileAccess()) {
const FilePath localAccess = mapToLocalAccess(filePath);
const bool res = localAccess.removeFile();
LOG("Remove? " << filePath.toUserOutput() << localAccess.toUserOutput() << res);
return res;
}
const CommandLine cmd("rm", {filePath.path()});
const int exitCode = d->runSynchronously(cmd);
return exitCode == 0;
}
bool DockerDevice::copyFile(const FilePath &filePath, const FilePath &target) const
{
QTC_ASSERT(handlesFile(filePath), return false);
QTC_ASSERT(handlesFile(target), return false);
tryCreateLocalFileAccess();
if (hasLocalFileAccess()) {
const FilePath localAccess = mapToLocalAccess(filePath);
const FilePath localTarget = mapToLocalAccess(target);
const bool res = localAccess.copyFile(localTarget);
LOG("Copy " << filePath.toUserOutput() << localAccess.toUserOutput() << localTarget << res);
return res;
}
const CommandLine cmd("cp", {filePath.path(), target.path()});
const int exitCode = d->runSynchronously(cmd);
return exitCode == 0;
}
QDateTime DockerDevice::lastModified(const FilePath &filePath) const
{
QTC_ASSERT(handlesFile(filePath), return {});
tryCreateLocalFileAccess();
if (hasLocalFileAccess()) {
const FilePath localAccess = mapToLocalAccess(filePath);
const QDateTime res = localAccess.lastModified();
LOG("Last modified? " << filePath.toUserOutput() << localAccess.toUserOutput() << res);
return res;
}
QTC_CHECK(false);
return {};
}
FilePath DockerDevice::searchInPath(const FilePath &filePath) const FilePath DockerDevice::searchInPath(const FilePath &filePath) const
{ {
const QString path = filePath.path(); const QString path = filePath.path();

View File

@@ -80,11 +80,14 @@ public:
bool isWritableDirectory(const Utils::FilePath &filePath) const override; bool isWritableDirectory(const Utils::FilePath &filePath) const override;
bool createDirectory(const Utils::FilePath &filePath) const override; bool createDirectory(const Utils::FilePath &filePath) const override;
bool exists(const Utils::FilePath &filePath) const override; bool exists(const Utils::FilePath &filePath) const override;
bool removeFile(const Utils::FilePath &filePath) const override;
bool copyFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override;
Utils::FilePath searchInPath(const Utils::FilePath &filePath) const override; Utils::FilePath searchInPath(const Utils::FilePath &filePath) const override;
QList<Utils::FilePath> directoryEntries(const Utils::FilePath &filePath, QList<Utils::FilePath> directoryEntries(const Utils::FilePath &filePath,
const QStringList &nameFilters, const QStringList &nameFilters,
QDir::Filters filters) const override; QDir::Filters filters) const override;
QByteArray fileContents(const Utils::FilePath &filePath, int limit) const override; QByteArray fileContents(const Utils::FilePath &filePath, int limit) const override;
QDateTime lastModified(const Utils::FilePath &filePath) const override;
void runProcess(Utils::QtcProcess &process) const override; void runProcess(Utils::QtcProcess &process) const override;
Utils::Environment systemEnvironment() const override; Utils::Environment systemEnvironment() const override;

View File

@@ -39,6 +39,7 @@
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <QDateTime>
#include <QFileInfo> #include <QFileInfo>
#include <QHash> #include <QHash>
#include <QList> #include <QList>
@@ -416,6 +417,18 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
return device->exists(filePath); return device->exists(filePath);
}; };
deviceHooks.removeFile = [](const FilePath &filePath) {
auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return false);
return device->removeFile(filePath);
};
deviceHooks.copyFile = [](const FilePath &filePath, const FilePath &target) {
auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return false);
return device->copyFile(filePath, target);
};
deviceHooks.searchInPath = [](const FilePath &filePath) { deviceHooks.searchInPath = [](const FilePath &filePath) {
auto device = DeviceManager::deviceForPath(filePath); auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return FilePath{}); QTC_ASSERT(device, return FilePath{});
@@ -435,6 +448,12 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
return device->fileContents(filePath, maxSize); return device->fileContents(filePath, maxSize);
}; };
deviceHooks.lastModified = [](const FilePath &filePath) {
auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return QDateTime());
return device->lastModified(filePath);
};
FilePath::setDeviceFileHooks(deviceHooks); FilePath::setDeviceFileHooks(deviceHooks);
DeviceProcessHooks processHooks; DeviceProcessHooks processHooks;

View File

@@ -43,6 +43,7 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QStandardPaths> #include <QStandardPaths>
#include <QDateTime>
#include <QString> #include <QString>
#include <QUuid> #include <QUuid>
@@ -252,20 +253,35 @@ bool IDevice::ensureWritableDirectory(const FilePath &filePath) const
return createDirectory(filePath); return createDirectory(filePath);
} }
bool IDevice::createDirectory(const Utils::FilePath &filePath) const bool IDevice::createDirectory(const FilePath &filePath) const
{ {
Q_UNUSED(filePath); Q_UNUSED(filePath);
QTC_CHECK(false); QTC_CHECK(false);
return false; return false;
} }
bool IDevice::exists(const Utils::FilePath &filePath) const bool IDevice::exists(const FilePath &filePath) const
{ {
Q_UNUSED(filePath); Q_UNUSED(filePath);
QTC_CHECK(false); QTC_CHECK(false);
return false; return false;
} }
bool IDevice::removeFile(const FilePath &filePath) const
{
Q_UNUSED(filePath);
QTC_CHECK(false);
return false;
}
bool IDevice::copyFile(const FilePath &filePath, const FilePath &target) const
{
Q_UNUSED(filePath);
Q_UNUSED(target);
QTC_CHECK(false);
return false;
}
FilePath IDevice::searchInPath(const FilePath &filePath) const FilePath IDevice::searchInPath(const FilePath &filePath) const
{ {
return Environment::systemEnvironment().searchInPath(filePath.path()); return Environment::systemEnvironment().searchInPath(filePath.path());
@@ -290,6 +306,12 @@ QByteArray IDevice::fileContents(const FilePath &filePath, int limit) const
return {}; return {};
} }
QDateTime IDevice::lastModified(const FilePath &filePath) const
{
Q_UNUSED(filePath);
return {};
}
void IDevice::runProcess(QtcProcess &process) const void IDevice::runProcess(QtcProcess &process) const
{ {
Q_UNUSED(process); Q_UNUSED(process);

View File

@@ -243,11 +243,14 @@ public:
virtual bool ensureWritableDirectory(const Utils::FilePath &filePath) const; virtual bool ensureWritableDirectory(const Utils::FilePath &filePath) const;
virtual bool createDirectory(const Utils::FilePath &filePath) const; virtual bool createDirectory(const Utils::FilePath &filePath) const;
virtual bool exists(const Utils::FilePath &filePath) const; virtual bool exists(const Utils::FilePath &filePath) const;
virtual bool removeFile(const Utils::FilePath &filePath) const;
virtual bool copyFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const;
virtual Utils::FilePath searchInPath(const Utils::FilePath &filePath) const; virtual Utils::FilePath searchInPath(const Utils::FilePath &filePath) const;
virtual QList<Utils::FilePath> directoryEntries(const Utils::FilePath &filePath, virtual QList<Utils::FilePath> directoryEntries(const Utils::FilePath &filePath,
const QStringList &nameFilters, const QStringList &nameFilters,
QDir::Filters filters) const; QDir::Filters filters) const;
virtual QByteArray fileContents(const Utils::FilePath &filePath, int limit) const; virtual QByteArray fileContents(const Utils::FilePath &filePath, int limit) const;
virtual QDateTime lastModified(const Utils::FilePath &filePath) const;
virtual void runProcess(Utils::QtcProcess &process) const; virtual void runProcess(Utils::QtcProcess &process) const;
virtual Utils::Environment systemEnvironment() const; virtual Utils::Environment systemEnvironment() const;