Utils: Wrap various file system iteration flags and filters

... into a single class.

This makes passing them around as a whole easier, and opens a path
to have "generic" filters in form of a lambda or such.

Change-Id: Ibf644b2fedcf0f1a35258030710afff8f5873f88
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
hjk
2022-01-21 12:22:54 +01:00
parent c6fdb66b2b
commit 1fc83d2a56
35 changed files with 121 additions and 143 deletions

View File

@@ -1455,17 +1455,20 @@ bool DockerDevice::setPermissions(const FilePath &filePath, QFileDevice::Permiss
void DockerDevice::iterateWithFind(const FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters) const
const FileFilter &filter) const
{
QTC_ASSERT(callBack, return);
QTC_CHECK(filePath.isAbsolutePath());
QStringList arguments{filePath.path(), "-maxdepth", "1"};
QStringList arguments{filePath.path()};
const QDir::Filters filters = filter.fileFilters;
if (filters & QDir::NoSymLinks)
arguments.prepend("-H");
else
arguments.prepend("-L");
if (!filter.iteratorFlags.testFlag(QDirIterator::Subdirectories))
arguments.append({"-maxdepth", "1"});
QStringList filterOptions;
if (filters & QDir::Dirs)
@@ -1493,12 +1496,12 @@ void DockerDevice::iterateWithFind(const FilePath &filePath,
const QString nameOption = (filters & QDir::CaseSensitive) ? QString{"-name"}
: QString{"-iname"};
QStringList criticalWildcards;
if (!nameFilters.isEmpty()) {
if (!filter.nameFilters.isEmpty()) {
const QRegularExpression oneChar("\\[.*?\\]");
for (int i = 0, len = nameFilters.size(); i < len; ++i) {
for (int i = 0, len = filter.nameFilters.size(); i < len; ++i) {
if (i > 0)
filterOptions << "-o";
QString current = nameFilters.at(i);
QString current = filter.nameFilters.at(i);
if (current.indexOf(oneChar) != -1)
criticalWildcards.append(current);
current.replace(oneChar, "?"); // BAD! but still better than nothing
@@ -1537,15 +1540,17 @@ void DockerDevice::iterateWithFind(const FilePath &filePath,
static void filterEntriesHelper(const FilePath &base,
const std::function<bool(const FilePath &)> &callBack,
const QStringList &entries,
const QStringList &nameFilters,
QDir::Filters filters)
const FileFilter &filter)
{
const QList<QRegularExpression> nameRegexps = transform(nameFilters, [](const QString &filter) {
QRegularExpression re;
re.setPattern(QRegularExpression::wildcardToRegularExpression(filter));
QTC_CHECK(re.isValid());
return re;
});
QTC_CHECK(filter.iteratorFlags != QDirIterator::NoIteratorFlags); // FIXME: Not supported yet below.
const QList<QRegularExpression> nameRegexps =
transform(filter.nameFilters, [](const QString &filter) {
QRegularExpression re;
re.setPattern(QRegularExpression::wildcardToRegularExpression(filter));
QTC_CHECK(re.isValid());
return re;
});
const auto nameMatches = [&nameRegexps](const QString &fileName) {
for (const QRegularExpression &re : nameRegexps) {
@@ -1557,7 +1562,7 @@ static void filterEntriesHelper(const FilePath &base,
};
// FIXME: Handle filters. For now bark on unsupported options.
QTC_CHECK(filters == QDir::NoFilter);
QTC_CHECK(filter.fileFilters == QDir::NoFilter);
for (const QString &entry : entries) {
if (!nameMatches(entry))
@@ -1569,12 +1574,8 @@ static void filterEntriesHelper(const FilePath &base,
void DockerDevice::iterateDirectory(const FilePath &filePath,
const std::function<bool(const FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags) const
const FileFilter &filter) const
{
Q_UNUSED(flags) // FIXME: Use it.
QTC_ASSERT(handlesFile(filePath), return);
updateContainerAccess();
if (hasLocalFileAccess()) {
@@ -1582,12 +1583,12 @@ void DockerDevice::iterateDirectory(const FilePath &filePath,
local.iterateDirectory([&callBack, this](const FilePath &entry) {
return callBack(mapFromLocalAccess(entry));
},
nameFilters, filters);
filter);
return;
}
if (d->m_useFind) {
iterateWithFind(filePath, callBack, nameFilters, filters);
iterateWithFind(filePath, callBack, filter);
// d->m_useFind will be set to false if 'find' is not found. In this
// case fall back to 'ls' below.
if (d->m_useFind)
@@ -1597,7 +1598,7 @@ void DockerDevice::iterateDirectory(const FilePath &filePath,
// if we do not have find - use ls as fallback
const QString output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}});
const QStringList entries = output.split('\n', Qt::SkipEmptyParts);
filterEntriesHelper(filePath, callBack, entries, nameFilters, filters);
filterEntriesHelper(filePath, callBack, entries, filter);
}
QByteArray DockerDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const

View File

@@ -96,9 +96,7 @@ public:
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
void iterateDirectory(const Utils::FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags) const override;
const Utils::FileFilter &filter) const override;
QByteArray fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const override;
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
QDateTime lastModified(const Utils::FilePath &filePath) const override;
@@ -127,8 +125,7 @@ protected:
private:
void iterateWithFind(const Utils::FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters) const;
const Utils::FileFilter &filter) const;
void aboutToBeRemoved() const final;