Replace IPathMatcher stuff with Filter

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
TheKodeToad 2025-08-04 14:28:45 +01:00
parent d41db5253e
commit d7eddd3773
No known key found for this signature in database
GPG key ID: 5E39D70B4C93C38E
22 changed files with 66 additions and 183 deletions

View file

@ -46,8 +46,6 @@
#include "DataMigrationTask.h" #include "DataMigrationTask.h"
#include "java/JavaInstallList.h" #include "java/JavaInstallList.h"
#include "net/PasteUpload.h" #include "net/PasteUpload.h"
#include "pathmatcher/MultiMatcher.h"
#include "pathmatcher/SimplePrefixMatcher.h"
#include "tasks/Task.h" #include "tasks/Task.h"
#include "tools/GenericProfiler.h" #include "tools/GenericProfiler.h"
#include "ui/InstanceWindow.h" #include "ui/InstanceWindow.h"
@ -1985,22 +1983,23 @@ bool Application::handleDataMigration(const QString& currentData,
if (!currentExists) { if (!currentExists) {
// Migrate! // Migrate!
auto matcher = std::make_shared<MultiMatcher>(); using namespace Filters;
matcher->add(std::make_shared<SimplePrefixMatcher>(configFile));
matcher->add(std::make_shared<SimplePrefixMatcher>( QList<Filter> filters;
BuildConfig.LAUNCHER_CONFIGFILE)); // it's possible that we already used that directory before filters.append(equals(configFile));
matcher->add(std::make_shared<SimplePrefixMatcher>("logs/")); filters.append(equals(BuildConfig.LAUNCHER_CONFIGFILE)); // it's possible that we already used that directory before
matcher->add(std::make_shared<SimplePrefixMatcher>("accounts.json")); filters.append(startsWith("logs/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("accounts/")); filters.append(equals("accounts.json"));
matcher->add(std::make_shared<SimplePrefixMatcher>("assets/")); filters.append(startsWith("accounts/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("icons/")); filters.append(startsWith("assets/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("instances/")); filters.append(startsWith("icons/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("libraries/")); filters.append(startsWith("instances/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("mods/")); filters.append(startsWith("libraries/"));
matcher->add(std::make_shared<SimplePrefixMatcher>("themes/")); filters.append(startsWith("mods/"));
filters.append(startsWith("themes/"));
ProgressDialog diag; ProgressDialog diag;
DataMigrationTask task(oldData, currentData, matcher); DataMigrationTask task(oldData, currentData, any(std::move(filters)));
if (diag.execWithTask(&task)) { if (diag.execWithTask(&task)) {
qDebug() << "<> Migration succeeded"; qDebug() << "<> Migration succeeded";
setDoNotMigrate(); setDoNotMigrate();

View file

@ -52,7 +52,6 @@
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include "MessageLevel.h" #include "MessageLevel.h"
#include "minecraft/auth/MinecraftAccount.h" #include "minecraft/auth/MinecraftAccount.h"
#include "pathmatcher/IPathMatcher.h"
#include "settings/INIFile.h" #include "settings/INIFile.h"
#include "net/Mode.h" #include "net/Mode.h"

View file

@ -107,15 +107,6 @@ if (UNIX AND NOT CYGWIN AND NOT APPLE)
) )
endif() endif()
set(PATHMATCHER_SOURCES
# Path matchers
pathmatcher/FSTreeMatcher.h
pathmatcher/IPathMatcher.h
pathmatcher/MultiMatcher.h
pathmatcher/RegexpMatcher.h
pathmatcher/SimplePrefixMatcher.h
)
set(NET_SOURCES set(NET_SOURCES
# network stuffs # network stuffs
net/ByteArraySink.h net/ByteArraySink.h
@ -759,7 +750,6 @@ endif()
set(LOGIC_SOURCES set(LOGIC_SOURCES
${CORE_SOURCES} ${CORE_SOURCES}
${PATHMATCHER_SOURCES}
${NET_SOURCES} ${NET_SOURCES}
${LAUNCH_SOURCES} ${LAUNCH_SOURCES}
${UPDATE_SOURCES} ${UPDATE_SOURCES}

View file

@ -12,7 +12,7 @@
#include <QtConcurrent> #include <QtConcurrent>
DataMigrationTask::DataMigrationTask(const QString& sourcePath, const QString& targetPath, const IPathMatcher::Ptr pathMatcher) DataMigrationTask::DataMigrationTask(const QString& sourcePath, const QString& targetPath, Filter pathMatcher)
: Task(), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath) : Task(), m_sourcePath(sourcePath), m_targetPath(targetPath), m_pathMatcher(pathMatcher), m_copy(sourcePath, targetPath)
{ {
m_copy.matcher(m_pathMatcher).whitelist(true); m_copy.matcher(m_pathMatcher).whitelist(true);

View file

@ -5,7 +5,7 @@
#pragma once #pragma once
#include "FileSystem.h" #include "FileSystem.h"
#include "pathmatcher/IPathMatcher.h" #include "Filter.h"
#include "tasks/Task.h" #include "tasks/Task.h"
#include <QFuture> #include <QFuture>
@ -18,7 +18,7 @@
class DataMigrationTask : public Task { class DataMigrationTask : public Task {
Q_OBJECT Q_OBJECT
public: public:
explicit DataMigrationTask(const QString& sourcePath, const QString& targetPath, IPathMatcher::Ptr pathmatcher); explicit DataMigrationTask(const QString& sourcePath, const QString& targetPath, Filter pathmatcher);
~DataMigrationTask() override = default; ~DataMigrationTask() override = default;
protected: protected:
@ -33,7 +33,7 @@ class DataMigrationTask : public Task {
private: private:
const QString& m_sourcePath; const QString& m_sourcePath;
const QString& m_targetPath; const QString& m_targetPath;
const IPathMatcher::Ptr m_pathMatcher; const Filter m_pathMatcher;
FS::copy m_copy; FS::copy m_copy;
int m_toCopy = 0; int m_toCopy = 0;

View file

@ -331,7 +331,7 @@ bool copy::operator()(const QString& offset, bool dryRun)
// Function that'll do the actual copying // Function that'll do the actual copying
auto copy_file = [this, dryRun, src, dst, opt, &err](QString src_path, QString relative_dst_path) { auto copy_file = [this, dryRun, src, dst, opt, &err](QString src_path, QString relative_dst_path) {
if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist)) if (m_matcher && (m_matcher(relative_dst_path) != m_whitelist))
return; return;
auto dst_path = PathCombine(dst, relative_dst_path); auto dst_path = PathCombine(dst, relative_dst_path);
@ -418,7 +418,7 @@ void create_link::make_link_list(const QString& offset)
// Function that'll do the actual linking // Function that'll do the actual linking
auto link_file = [this, dst](QString src_path, QString relative_dst_path) { auto link_file = [this, dst](QString src_path, QString relative_dst_path) {
if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist)) { if (m_matcher && (m_matcher(relative_dst_path) != m_whitelist)) {
qDebug() << "path" << relative_dst_path << "in black list or not in whitelist"; qDebug() << "path" << relative_dst_path << "in black list or not in whitelist";
return; return;
} }
@ -1277,7 +1277,7 @@ bool clone::operator()(const QString& offset, bool dryRun)
// Function that'll do the actual cloneing // Function that'll do the actual cloneing
auto cloneFile = [this, dryRun, dst, &err](QString src_path, QString relative_dst_path) { auto cloneFile = [this, dryRun, dst, &err](QString src_path, QString relative_dst_path) {
if (m_matcher && (m_matcher->matches(relative_dst_path) != m_whitelist)) if (m_matcher && (m_matcher(relative_dst_path) != m_whitelist))
return; return;
auto dst_path = PathCombine(dst, relative_dst_path); auto dst_path = PathCombine(dst, relative_dst_path);

View file

@ -38,7 +38,7 @@
#pragma once #pragma once
#include "Exception.h" #include "Exception.h"
#include "pathmatcher/IPathMatcher.h" #include "Filter.h"
#include <system_error> #include <system_error>
@ -115,9 +115,9 @@ class copy : public QObject {
m_followSymlinks = follow; m_followSymlinks = follow;
return *this; return *this;
} }
copy& matcher(IPathMatcher::Ptr filter) copy& matcher(Filter filter)
{ {
m_matcher = filter; m_matcher = std::move(filter);
return *this; return *this;
} }
copy& whitelist(bool whitelist) copy& whitelist(bool whitelist)
@ -147,7 +147,7 @@ class copy : public QObject {
private: private:
bool m_followSymlinks = true; bool m_followSymlinks = true;
IPathMatcher::Ptr m_matcher = nullptr; Filter m_matcher = nullptr;
bool m_whitelist = false; bool m_whitelist = false;
bool m_overwrite = false; bool m_overwrite = false;
QDir m_src; QDir m_src;
@ -209,9 +209,9 @@ class create_link : public QObject {
m_useHardLinks = useHard; m_useHardLinks = useHard;
return *this; return *this;
} }
create_link& matcher(IPathMatcher::Ptr filter) create_link& matcher(Filter filter)
{ {
m_matcher = filter; m_matcher = std::move(filter);
return *this; return *this;
} }
create_link& whitelist(bool whitelist) create_link& whitelist(bool whitelist)
@ -260,7 +260,7 @@ class create_link : public QObject {
private: private:
bool m_useHardLinks = false; bool m_useHardLinks = false;
IPathMatcher::Ptr m_matcher = nullptr; Filter m_matcher = nullptr;
bool m_whitelist = false; bool m_whitelist = false;
bool m_recursive = true; bool m_recursive = true;
@ -492,9 +492,9 @@ class clone : public QObject {
m_src.setPath(src); m_src.setPath(src);
m_dst.setPath(dst); m_dst.setPath(dst);
} }
clone& matcher(IPathMatcher::Ptr filter) clone& matcher(Filter filter)
{ {
m_matcher = filter; m_matcher = std::move(filter);
return *this; return *this;
} }
clone& whitelist(bool whitelist) clone& whitelist(bool whitelist)
@ -518,7 +518,7 @@ class clone : public QObject {
bool operator()(const QString& offset, bool dryRun = false); bool operator()(const QString& offset, bool dryRun = false);
private: private:
IPathMatcher::Ptr m_matcher = nullptr; Filter m_matcher = nullptr;
bool m_whitelist = false; bool m_whitelist = false;
QDir m_src; QDir m_src;
QDir m_dst; QDir m_dst;

View file

@ -11,9 +11,15 @@ inline Filter inverse(Filter filter)
return [filter = std::move(filter)](const QString& src) { return !filter(src); }; return [filter = std::move(filter)](const QString& src) { return !filter(src); };
} }
inline Filter contains(QString pattern) inline Filter any(QList<Filter> filters)
{ {
return [pattern = std::move(pattern)](const QString& src) { return src.contains(pattern); }; return [filters = std::move(filters)](const QString& src) {
for (auto& filter : filters)
if (filter(src))
return true;
return false;
};
} }
inline Filter equals(QString pattern) inline Filter equals(QString pattern)
@ -31,6 +37,16 @@ inline Filter equalsOrEmpty(QString pattern)
return [pattern = std::move(pattern)](const QString& src) { return src.isEmpty() || src == pattern; }; return [pattern = std::move(pattern)](const QString& src) { return src.isEmpty() || src == pattern; };
} }
inline Filter contains(QString pattern)
{
return [pattern = std::move(pattern)](const QString& src) { return src.contains(pattern); };
}
inline Filter startsWith(QString pattern)
{
return [pattern = std::move(pattern)](const QString& src) { return src.startsWith(pattern); };
}
inline Filter regexp(QRegularExpression pattern) inline Filter regexp(QRegularExpression pattern)
{ {
return [pattern = std::move(pattern)](const QString& src) { return pattern.match(src).hasMatch(); }; return [pattern = std::move(pattern)](const QString& src) { return pattern.match(src).hasMatch(); };

View file

@ -3,8 +3,8 @@
#include <QtConcurrentRun> #include <QtConcurrentRun>
#include <memory> #include <memory>
#include "FileSystem.h" #include "FileSystem.h"
#include "Filter.h"
#include "NullInstance.h" #include "NullInstance.h"
#include "pathmatcher/RegexpMatcher.h"
#include "settings/INISettingsObject.h" #include "settings/INISettingsObject.h"
#include "tasks/Task.h" #include "tasks/Task.h"
@ -30,9 +30,8 @@ InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, const InstanceCopyP
if (!filters.isEmpty()) { if (!filters.isEmpty()) {
// Set regex filter: // Set regex filter:
// FIXME: get this from the original instance type... // FIXME: get this from the original instance type...
auto matcherReal = new RegexpMatcher(filters); QRegularExpression regexp(filters, QRegularExpression::CaseInsensitiveOption);
matcherReal->caseSensitive(false); m_matcher = Filters::regexp(regexp);
m_matcher.reset(matcherReal);
} }
} }

View file

@ -5,6 +5,7 @@
#include <QUrl> #include <QUrl>
#include "BaseInstance.h" #include "BaseInstance.h"
#include "BaseVersion.h" #include "BaseVersion.h"
#include "Filter.h"
#include "InstanceCopyPrefs.h" #include "InstanceCopyPrefs.h"
#include "InstanceTask.h" #include "InstanceTask.h"
#include "net/NetJob.h" #include "net/NetJob.h"
@ -28,7 +29,7 @@ class InstanceCopyTask : public InstanceTask {
InstancePtr m_origInstance; InstancePtr m_origInstance;
QFuture<bool> m_copyFuture; QFuture<bool> m_copyFuture;
QFutureWatcher<bool> m_copyFutureWatcher; QFutureWatcher<bool> m_copyFutureWatcher;
IPathMatcher::Ptr m_matcher; Filter m_matcher;
bool m_keepPlaytime; bool m_keepPlaytime;
bool m_useLinks = false; bool m_useLinks = false;
bool m_useHardLinks = false; bool m_useHardLinks = false;

View file

@ -78,7 +78,7 @@ QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir& directory)
} }
for (const QString& file : directory.entryList(QDir::Files | QDir::Hidden)) { for (const QString& file : directory.entryList(QDir::Files | QDir::Hidden)) {
auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file)); auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file));
if (m_matcher->matches(relPath)) { if (m_matcher(relPath)) {
ret.append(relPath); ret.append(relPath);
} }
} }

View file

@ -2,7 +2,7 @@
#include <QDir> #include <QDir>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
#include "pathmatcher/IPathMatcher.h" #include "Filter.h"
class RecursiveFileSystemWatcher : public QObject { class RecursiveFileSystemWatcher : public QObject {
Q_OBJECT Q_OBJECT
@ -16,7 +16,7 @@ class RecursiveFileSystemWatcher : public QObject {
void setWatchFiles(bool watchFiles); void setWatchFiles(bool watchFiles);
bool watchFiles() const { return m_watchFiles; } bool watchFiles() const { return m_watchFiles; }
void setMatcher(IPathMatcher::Ptr matcher) { m_matcher = matcher; } void setMatcher(Filter matcher) { m_matcher = std::move(matcher); }
QStringList files() const { return m_files; } QStringList files() const { return m_files; }
@ -32,7 +32,7 @@ class RecursiveFileSystemWatcher : public QObject {
QDir m_root; QDir m_root;
bool m_watchFiles = false; bool m_watchFiles = false;
bool m_isEnabled = false; bool m_isEnabled = false;
IPathMatcher::Ptr m_matcher; Filter m_matcher;
QFileSystemWatcher* m_watcher; QFileSystemWatcher* m_watcher;

View file

@ -53,7 +53,6 @@
#include "FileSystem.h" #include "FileSystem.h"
#include "MMCTime.h" #include "MMCTime.h"
#include "java/JavaVersion.h" #include "java/JavaVersion.h"
#include "pathmatcher/MultiMatcher.h"
#include "launch/LaunchTask.h" #include "launch/LaunchTask.h"
#include "launch/TaskStepWrapper.h" #include "launch/TaskStepWrapper.h"

View file

@ -1,14 +0,0 @@
#pragma once
#include <SeparatorPrefixTree.h>
#include "IPathMatcher.h"
class FSTreeMatcher : public IPathMatcher {
public:
virtual ~FSTreeMatcher() {};
FSTreeMatcher(SeparatorPrefixTree<'/'>& tree) : m_fsTree(tree) {}
bool matches(const QString& string) const override { return m_fsTree.covers(string); }
SeparatorPrefixTree<'/'>& m_fsTree;
};

View file

@ -1,12 +0,0 @@
#pragma once
#include <QString>
#include <memory>
class IPathMatcher {
public:
using Ptr = std::shared_ptr<IPathMatcher>;
public:
virtual ~IPathMatcher() {}
virtual bool matches(const QString& string) const = 0;
};

View file

@ -1,27 +0,0 @@
#pragma once
#include <SeparatorPrefixTree.h>
#include "IPathMatcher.h"
class MultiMatcher : public IPathMatcher {
public:
virtual ~MultiMatcher() {};
MultiMatcher() {}
MultiMatcher& add(Ptr add)
{
m_matchers.append(add);
return *this;
}
virtual bool matches(const QString& string) const override
{
for (auto iter : m_matchers) {
if (iter->matches(string)) {
return true;
}
}
return false;
}
QList<Ptr> m_matchers;
};

View file

@ -1,40 +0,0 @@
#pragma once
#include <QRegularExpression>
#include "IPathMatcher.h"
class RegexpMatcher : public IPathMatcher {
public:
virtual ~RegexpMatcher() {}
RegexpMatcher(const QString& regexp)
{
m_regexp.setPattern(regexp);
m_onlyFilenamePart = !regexp.contains('/');
}
RegexpMatcher(const QRegularExpression& regex) : m_regexp(regex) { m_onlyFilenamePart = !regex.pattern().contains('/'); }
RegexpMatcher& caseSensitive(bool cs = true)
{
if (cs) {
m_regexp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
} else {
m_regexp.setPatternOptions(QRegularExpression::NoPatternOption);
}
return *this;
}
virtual bool matches(const QString& string) const override
{
if (m_onlyFilenamePart) {
auto slash = string.lastIndexOf('/');
if (slash != -1) {
auto part = string.mid(slash + 1);
return m_regexp.match(part).hasMatch();
}
}
return m_regexp.match(string).hasMatch();
}
QRegularExpression m_regexp;
bool m_onlyFilenamePart = false;
};

View file

@ -1,24 +0,0 @@
// SPDX-FileCopyrightText: 2022 Sefa Eyeoglu <contact@scrumplex.net>
//
// SPDX-License-Identifier: GPL-3.0-only
#include "IPathMatcher.h"
class SimplePrefixMatcher : public IPathMatcher {
public:
virtual ~SimplePrefixMatcher() {};
SimplePrefixMatcher(const QString& prefix)
{
m_prefix = prefix;
m_isPrefix = prefix.endsWith('/');
}
virtual bool matches(const QString& string) const override
{
if (m_isPrefix)
return string.startsWith(m_prefix);
return string == m_prefix;
}
QString m_prefix;
bool m_isPrefix = false;
};

View file

@ -38,7 +38,6 @@
#include <QWidget> #include <QWidget>
#include <Application.h> #include <Application.h>
#include <pathmatcher/IPathMatcher.h>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
#include "LogPage.h" #include "LogPage.h"
#include "ui/pages/BasePage.h" #include "ui/pages/BasePage.h"

View file

@ -12,8 +12,6 @@
#include <filesystem> #include <filesystem>
namespace fs = std::filesystem; namespace fs = std::filesystem;
#include <pathmatcher/RegexpMatcher.h>
class LinkTask : public Task { class LinkTask : public Task {
Q_OBJECT Q_OBJECT
@ -27,7 +25,7 @@ class LinkTask : public Task {
~LinkTask() { delete m_lnk; } ~LinkTask() { delete m_lnk; }
void matcher(IPathMatcher::Ptr filter) { m_lnk->matcher(filter); } void matcher(Filter filter) { m_lnk->matcher(filter); }
void linkRecursively(bool recursive) void linkRecursively(bool recursive)
{ {
@ -190,7 +188,7 @@ class FileSystemTest : public QObject {
qDebug() << tempDir.path(); qDebug() << tempDir.path();
qDebug() << target_dir.path(); qDebug() << target_dir.path();
FS::copy c(folder, target_dir.path()); FS::copy c(folder, target_dir.path());
RegexpMatcher::Ptr re = std::make_shared<RegexpMatcher>("[.]?mcmeta"); auto re = Filters::regexp(QRegularExpression("/[.]?mcmeta$"));
c.matcher(re); c.matcher(re);
c(); c();
@ -223,7 +221,7 @@ class FileSystemTest : public QObject {
qDebug() << tempDir.path(); qDebug() << tempDir.path();
qDebug() << target_dir.path(); qDebug() << target_dir.path();
FS::copy c(folder, target_dir.path()); FS::copy c(folder, target_dir.path());
RegexpMatcher::Ptr re = std::make_shared<RegexpMatcher>("[.]?mcmeta"); auto re = Filters::regexp(QRegularExpression("/[.]?mcmeta$"));
c.matcher(re); c.matcher(re);
c.whitelist(true); c.whitelist(true);
c(); c();
@ -415,7 +413,7 @@ class FileSystemTest : public QObject {
qDebug() << target_dir.path(); qDebug() << target_dir.path();
LinkTask lnk_tsk(folder, target_dir.path()); LinkTask lnk_tsk(folder, target_dir.path());
RegexpMatcher::Ptr re = std::make_shared<RegexpMatcher>("[.]?mcmeta"); auto re = Filters::regexp(QRegularExpression("/[.]?mcmeta$"));
lnk_tsk.matcher(re); lnk_tsk.matcher(re);
lnk_tsk.linkRecursively(true); lnk_tsk.linkRecursively(true);
connect(&lnk_tsk, &Task::finished, connect(&lnk_tsk, &Task::finished,
@ -461,7 +459,7 @@ class FileSystemTest : public QObject {
qDebug() << target_dir.path(); qDebug() << target_dir.path();
LinkTask lnk_tsk(folder, target_dir.path()); LinkTask lnk_tsk(folder, target_dir.path());
RegexpMatcher::Ptr re = std::make_shared<RegexpMatcher>("[.]?mcmeta"); auto re = Filters::regexp(QRegularExpression("/[.]?mcmeta$"));
lnk_tsk.matcher(re); lnk_tsk.matcher(re);
lnk_tsk.linkRecursively(true); lnk_tsk.linkRecursively(true);
lnk_tsk.whitelist(true); lnk_tsk.whitelist(true);