FileUtils: Add some helper to handle ls-style output

Unix-ish device implementations would otherwise repeat that code.

Change-Id: I1265fe1a69e55409ab2875d0b6f6113ec92edd79
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
hjk
2022-01-21 13:11:39 +01:00
parent 4fb3eb8fd5
commit f7a585fad9
4 changed files with 48 additions and 75 deletions

View File

@@ -42,6 +42,7 @@
#ifdef QT_GUI_LIB #ifdef QT_GUI_LIB
#include <QMessageBox> #include <QMessageBox>
#include <QRegularExpression>
#endif #endif
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@@ -493,6 +494,43 @@ FilePaths FileUtils::getOpenFilePaths(QWidget *parent,
options); options);
return transform(result, &FilePath::fromString); return transform(result, &FilePath::fromString);
} }
// Used on 'ls' output on unix-like systems.
void FileUtils::iterateLsOutput(const FilePath &base,
const QStringList &entries,
const FileFilter &filter,
const std::function<bool (const FilePath &)> &callBack)
{
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) {
const QRegularExpressionMatch match = re.match(fileName);
if (match.hasMatch())
return true;
}
return nameRegexps.isEmpty();
};
// FIXME: Handle filters. For now bark on unsupported options.
QTC_CHECK(filter.fileFilters == QDir::NoFilter);
for (const QString &entry : entries) {
if (!nameMatches(entry))
continue;
if (!callBack(base.pathAppended(entry)))
break;
}
}
#endif // QT_WIDGETS_LIB #endif // QT_WIDGETS_LIB
} // namespace Utils } // namespace Utils

View File

@@ -144,6 +144,11 @@ public:
static void setDeviceFileHooks(const DeviceFileHooks &hooks); static void setDeviceFileHooks(const DeviceFileHooks &hooks);
static void iterateLsOutput(const FilePath &base,
const QStringList &entries,
const FileFilter &filter,
const std::function<bool(const FilePath &)> &callBack);
#ifdef QT_WIDGETS_LIB #ifdef QT_WIDGETS_LIB
static void setDialogParentGetter(const std::function<QWidget *()> &getter); static void setDialogParentGetter(const std::function<QWidget *()> &getter);
@@ -173,6 +178,7 @@ public:
QString *selectedFilter = nullptr, QString *selectedFilter = nullptr,
QFileDialog::Options options = {}); QFileDialog::Options options = {});
#endif #endif
}; };
template<typename T> template<typename T>

View File

@@ -1525,41 +1525,6 @@ void DockerDevice::iterateWithFind(const FilePath &filePath,
} }
} }
static void filterEntriesHelper(const FilePath &base,
const std::function<bool(const FilePath &)> &callBack,
const QStringList &entries,
const FileFilter &filter)
{
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) {
const QRegularExpressionMatch match = re.match(fileName);
if (match.hasMatch())
return true;
}
return nameRegexps.isEmpty();
};
// FIXME: Handle filters. For now bark on unsupported options.
QTC_CHECK(filter.fileFilters == QDir::NoFilter);
for (const QString &entry : entries) {
if (!nameMatches(entry))
continue;
if (!callBack(base.pathAppended(entry)))
break;
}
}
void DockerDevice::iterateDirectory(const FilePath &filePath, void DockerDevice::iterateDirectory(const FilePath &filePath,
const std::function<bool(const FilePath &)> &callBack, const std::function<bool(const FilePath &)> &callBack,
const FileFilter &filter) const const FileFilter &filter) const
@@ -1585,9 +1550,8 @@ void DockerDevice::iterateDirectory(const FilePath &filePath,
// if we do not have find - use ls as fallback // if we do not have find - use ls as fallback
const QByteArray output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}}); const QByteArray output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}});
const QString out = QString::fromUtf8(output.data(), output.size()); const QStringList entries = QString::fromUtf8(output).split('\n', Qt::SkipEmptyParts);
const QStringList entries = out.split('\n', Qt::SkipEmptyParts); FileUtils::iterateLsOutput(filePath, entries, filter, callBack);
filterEntriesHelper(filePath, callBack, entries, filter);
} }
QByteArray DockerDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const QByteArray DockerDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const

View File

@@ -718,40 +718,6 @@ bool LinuxDevice::setPermissions(const Utils::FilePath &filePath, QFileDevice::P
return d->runInShell({"chmod", {QString::number(flags, 16), filePath.path()}}); return d->runInShell({"chmod", {QString::number(flags, 16), filePath.path()}});
} }
static void filterEntriesHelper(const FilePath &base,
const std::function<bool(const FilePath &)> &callBack,
const QStringList &entries,
const FileFilter &filter)
{
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) {
const QRegularExpressionMatch match = re.match(fileName);
if (match.hasMatch())
return true;
}
return nameRegexps.isEmpty();
};
// FIXME: Handle filters. For now bark on unsupported options.
QTC_CHECK(filter.fileFilters == QDir::NoFilter);
QTC_CHECK(filter.iteratorFlags == QDirIterator::NoIteratorFlags);
for (const QString &entry : entries) {
if (!nameMatches(entry))
continue;
if (!callBack(base.pathAppended(entry)))
break;
}
}
void LinuxDevice::iterateDirectory(const FilePath &filePath, void LinuxDevice::iterateDirectory(const FilePath &filePath,
const std::function<bool(const FilePath &)> &callBack, const std::function<bool(const FilePath &)> &callBack,
const FileFilter &filter) const const FileFilter &filter) const
@@ -759,9 +725,8 @@ void LinuxDevice::iterateDirectory(const FilePath &filePath,
QTC_ASSERT(handlesFile(filePath), return); QTC_ASSERT(handlesFile(filePath), return);
// if we do not have find - use ls as fallback // if we do not have find - use ls as fallback
const QByteArray output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}}); const QByteArray output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}});
const QString out = QString::fromUtf8(output.data(), output.size()); const QStringList entries = QString::fromUtf8(output).split('\n', Qt::SkipEmptyParts);
const QStringList entries = out.split('\n', Qt::SkipEmptyParts); FileUtils::iterateLsOutput(filePath, entries, filter, callBack);
filterEntriesHelper(filePath, callBack, entries, filter);
} }
QByteArray LinuxDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const QByteArray LinuxDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const