From 8d500f3807592837a938a40de338a3639614e0c0 Mon Sep 17 00:00:00 2001 From: reddevillg Date: Thu, 22 Jan 2026 15:19:21 +0800 Subject: [PATCH] refactor: Part of Remove Qt dependencies from utils Move Qt/DBus related utilities from utils to common. Note: This commit changes the namespace `linglong::utils::dbus` to `linglong::common::dbus` and `linglong::utils::serialize` (partially) to `linglong::common::serialize`. Signed-off-by: reddevillg --- apps/ll-package-manager/src/main.cpp | 4 +- libs/linglong/CMakeLists.txt | 9 ++ .../src/linglong/builder/source_fetcher.cpp | 1 + libs/linglong/src/linglong/cli/cli.cpp | 34 +++---- libs/linglong/src/linglong/cli/cli.h | 3 +- .../common}/dbus/properties_forwarder.cpp | 20 ++-- .../common}/dbus/properties_forwarder.h | 6 +- .../src/linglong/common}/dbus/register.cpp | 2 +- .../src/linglong/common}/dbus/register.h | 24 +++-- .../src/linglong/common/formatter.cpp | 43 ++++++++ libs/linglong/src/linglong/common/formatter.h | 46 +++++++++ .../src/linglong/common}/gkeyfile_wrapper.h | 14 +-- .../src/linglong/common/serialize/json.cpp | 57 +++++++++++ .../src/linglong/common/serialize/json.h | 76 ++++++++++++++ .../src/linglong/package/layer_file.cpp | 1 + .../package_manager/package_manager.cpp | 49 +++++----- .../linglong/package_manager/package_task.cpp | 6 +- .../linglong/package_manager/package_task.h | 4 +- .../src/linglong/repo/ostree_repo.cpp | 27 ++--- libs/linglong/tests/ll-tests/CMakeLists.txt | 2 +- .../gkeyfile_wrapper_test.cpp | 80 +++++++-------- libs/utils/CMakeLists.txt | 7 -- libs/utils/src/linglong/utils/dbus/log.cpp | 9 -- libs/utils/src/linglong/utils/dbus/log.h | 11 --- .../src/linglong/utils/log/formatter.cpp | 25 +---- libs/utils/src/linglong/utils/log/formatter.h | 30 +----- .../src/linglong/utils/serialize/json.cpp | 52 ---------- .../utils/src/linglong/utils/serialize/json.h | 98 ------------------- 28 files changed, 377 insertions(+), 363 deletions(-) rename libs/{utils/src/linglong/utils => linglong/src/linglong/common}/dbus/properties_forwarder.cpp (84%) rename libs/{utils/src/linglong/utils => linglong/src/linglong/common}/dbus/properties_forwarder.h (86%) rename libs/{utils/src/linglong/utils => linglong/src/linglong/common}/dbus/register.cpp (75%) rename libs/{utils/src/linglong/utils => linglong/src/linglong/common}/dbus/register.h (70%) create mode 100644 libs/linglong/src/linglong/common/formatter.cpp create mode 100644 libs/linglong/src/linglong/common/formatter.h rename libs/{utils/src/linglong/utils => linglong/src/linglong/common}/gkeyfile_wrapper.h (92%) create mode 100644 libs/linglong/src/linglong/common/serialize/json.cpp create mode 100644 libs/linglong/src/linglong/common/serialize/json.h rename libs/linglong/tests/ll-tests/src/linglong/{utils => common}/gkeyfile_wrapper_test.cpp (69%) delete mode 100644 libs/utils/src/linglong/utils/dbus/log.cpp delete mode 100644 libs/utils/src/linglong/utils/dbus/log.h diff --git a/apps/ll-package-manager/src/main.cpp b/apps/ll-package-manager/src/main.cpp index cd5ddd6d2..e478e2db6 100644 --- a/apps/ll-package-manager/src/main.cpp +++ b/apps/ll-package-manager/src/main.cpp @@ -6,11 +6,11 @@ #include "configure.h" #include "linglong/adaptors/package_manager/package_manager1.h" +#include "linglong/common/dbus/register.h" #include "linglong/package_manager/package_manager.h" #include "linglong/repo/config.h" #include "linglong/repo/migrate.h" #include "linglong/repo/ostree_repo.h" -#include "linglong/utils/dbus/register.h" #include "linglong/utils/global/initialize.h" #include "ocppi/cli/CLI.hpp" #include "ocppi/cli/crun/Crun.hpp" @@ -19,8 +19,8 @@ #include +using namespace linglong::common::dbus; using namespace linglong::utils::global; -using namespace linglong::utils::dbus; namespace { void withDBusDaemon(ocppi::cli::CLI &cli) diff --git a/libs/linglong/CMakeLists.txt b/libs/linglong/CMakeLists.txt index ae1c5f1ba..416bf8dc7 100644 --- a/libs/linglong/CMakeLists.txt +++ b/libs/linglong/CMakeLists.txt @@ -35,6 +35,15 @@ pfl_add_library( src/linglong/cli/printer.h src/linglong/cli/terminal_notifier.cpp src/linglong/cli/terminal_notifier.h + src/linglong/common/dbus/properties_forwarder.cpp + src/linglong/common/dbus/properties_forwarder.h + src/linglong/common/dbus/register.cpp + src/linglong/common/dbus/register.h + src/linglong/common/formatter.cpp + src/linglong/common/formatter.h + src/linglong/common/gkeyfile_wrapper.h + src/linglong/common/serialize/json.cpp + src/linglong/common/serialize/json.h src/linglong/extension/extension.cpp src/linglong/extension/extension.h src/linglong/package/architecture.cpp diff --git a/libs/linglong/src/linglong/builder/source_fetcher.cpp b/libs/linglong/src/linglong/builder/source_fetcher.cpp index 924cbcca5..23b7f8921 100644 --- a/libs/linglong/src/linglong/builder/source_fetcher.cpp +++ b/libs/linglong/src/linglong/builder/source_fetcher.cpp @@ -7,6 +7,7 @@ #include "source_fetcher.h" #include "configure.h" +#include "linglong/common/formatter.h" #include "linglong/utils/error/error.h" #include "linglong/utils/global/initialize.h" #include "linglong/utils/log/log.h" diff --git a/libs/linglong/src/linglong/cli/cli.cpp b/libs/linglong/src/linglong/cli/cli.cpp index c131cef11..466fcb472 100644 --- a/libs/linglong/src/linglong/cli/cli.cpp +++ b/libs/linglong/src/linglong/cli/cli.cpp @@ -298,7 +298,7 @@ void Cli::interaction(const QDBusObjectPath &object_path, } auto messageType = static_cast(messageID); - auto msg = utils::serialize::fromQVariantMap< + auto msg = common::serialize::fromQVariantMap< api::types::v1::PackageManager1RequestInteractionAdditionalMessage>(additionalMessage); std::vector actions{ "yes", "Yes", "no", "No" }; @@ -348,7 +348,7 @@ void Cli::interaction(const QDBusObjectPath &object_path, auto reply = api::types::v1::InteractionReply{ .action = action }; QDBusPendingReply dbusReply = - this->pkgMan.ReplyInteraction(object_path, utils::serialize::toQVariantMap(reply)); + this->pkgMan.ReplyInteraction(object_path, common::serialize::toQVariantMap(reply)); dbusReply.waitForFinished(); if (dbusReply.isError()) { this->printer.printErr( @@ -964,7 +964,7 @@ int Cli::installFromFile(const QFileInfo &fileInfo, auto pendingReply = this->pkgMan.InstallFromFile(dbusFileDescriptor, fileInfo.suffix(), - utils::serialize::toQVariantMap(commonOptions)); + common::serialize::toQVariantMap(commonOptions)); res = waitTaskCreated(pendingReply, TaskType::InstallFromFile); if (!res) { this->handleCommonError(res.error()); @@ -1030,7 +1030,7 @@ int Cli::install(const InstallOptions &options) LogD("install module: {}", common::strings::join(*params.package.modules)); - auto pendingReply = this->pkgMan.Install(utils::serialize::toQVariantMap(params)); + auto pendingReply = this->pkgMan.Install(common::serialize::toQVariantMap(params)); auto res = waitTaskCreated(pendingReply, TaskType::Install); if (!res) { handleInstallError(res.error(), params); @@ -1094,7 +1094,7 @@ int Cli::upgrade(const UpgradeOptions &options) params.packages.emplace_back(std::move(package)); } - auto pendingReply = this->pkgMan.Update(utils::serialize::toQVariantMap(params)); + auto pendingReply = this->pkgMan.Update(common::serialize::toQVariantMap(params)); auto res = waitTaskCreated(pendingReply, TaskType::Upgrade); if (!res) { handleUpgradeError(res.error()); @@ -1155,7 +1155,7 @@ int Cli::search(const SearchOptions &options) return; } auto result = - utils::serialize::fromQVariantMap(data); + common::serialize::fromQVariantMap(data); if (!result) { this->printer.printErr(result.error()); loop.exit(-1); @@ -1222,7 +1222,7 @@ int Cli::search(const SearchOptions &options) loop.exit(0); }); - auto pendingReply = this->pkgMan.Search(utils::serialize::toQVariantMap(params)); + auto pendingReply = this->pkgMan.Search(common::serialize::toQVariantMap(params)); auto result = waitDBusReply(pendingReply); if (!result) { this->printer.printErr(result.error()); @@ -1254,7 +1254,7 @@ int Cli::prune() return; } auto ret = - utils::serialize::fromQVariantMap( + common::serialize::fromQVariantMap( data); if (!ret) { this->printer.printErr(ret.error()); @@ -1315,7 +1315,7 @@ int Cli::uninstall(const UninstallOptions &options) params.package.packageManager1PackageModule = options.module; } - auto pendingReply = this->pkgMan.Uninstall(utils::serialize::toQVariantMap(params)); + auto pendingReply = this->pkgMan.Uninstall(common::serialize::toQVariantMap(params)); auto res = waitTaskCreated(pendingReply, TaskType::Uninstall); if (!res) { this->handleUninstallError(res.error()); @@ -1399,7 +1399,7 @@ int Cli::repo(CLI::App *app, const RepoOptions &options) return -1; } - auto cfg = utils::serialize::fromQVariantMap(propCfg); + auto cfg = common::serialize::fromQVariantMap(propCfg); if (!cfg) { qCritical() << cfg.error(); qCritical() << "linglong bug detected."; @@ -1462,7 +1462,7 @@ int Cli::repo(CLI::App *app, const RepoOptions &options) .priority = 0, .url = url, }); - return this->setRepoConfig(utils::serialize::toQVariantMap(cfgRef)); + return this->setRepoConfig(common::serialize::toQVariantMap(cfgRef)); } auto existingRepo = @@ -1496,7 +1496,7 @@ int Cli::repo(CLI::App *app, const RepoOptions &options) } } - return this->setRepoConfig(utils::serialize::toQVariantMap(cfgRef)); + return this->setRepoConfig(common::serialize::toQVariantMap(cfgRef)); } if (argsParsed("update")) { @@ -1506,17 +1506,17 @@ int Cli::repo(CLI::App *app, const RepoOptions &options) } existingRepo->url = url; - return this->setRepoConfig(utils::serialize::toQVariantMap(cfgRef)); + return this->setRepoConfig(common::serialize::toQVariantMap(cfgRef)); } if (argsParsed("enable-mirror")) { existingRepo->mirrorEnabled = true; - return this->setRepoConfig(utils::serialize::toQVariantMap(cfgRef)); + return this->setRepoConfig(common::serialize::toQVariantMap(cfgRef)); } if (argsParsed("disable-mirror")) { existingRepo->mirrorEnabled = false; - return this->setRepoConfig(utils::serialize::toQVariantMap(cfgRef)); + return this->setRepoConfig(common::serialize::toQVariantMap(cfgRef)); } if (argsParsed("set-default")) { @@ -1530,7 +1530,7 @@ int Cli::repo(CLI::App *app, const RepoOptions &options) break; } } - return this->setRepoConfig(utils::serialize::toQVariantMap(cfgRef)); + return this->setRepoConfig(common::serialize::toQVariantMap(cfgRef)); } return 0; @@ -1538,7 +1538,7 @@ int Cli::repo(CLI::App *app, const RepoOptions &options) if (argsParsed("set-priority")) { existingRepo->priority = options.repoPriority; - return this->setRepoConfig(utils::serialize::toQVariantMap(cfgRef)); + return this->setRepoConfig(common::serialize::toQVariantMap(cfgRef)); } this->printer.printErr(LINGLONG_ERRV("unknown operation")); diff --git a/libs/linglong/src/linglong/cli/cli.h b/libs/linglong/src/linglong/cli/cli.h index d8a10ba63..5df01d403 100644 --- a/libs/linglong/src/linglong/cli/cli.h +++ b/libs/linglong/src/linglong/cli/cli.h @@ -13,6 +13,7 @@ #include "linglong/api/types/v1/RepositoryCacheLayersItem.hpp" #include "linglong/cli/interactive_notifier.h" #include "linglong/cli/printer.h" +#include "linglong/common/serialize/json.h" #include "linglong/repo/ostree_repo.h" #include "linglong/runtime/container_builder.h" #include "linglong/utils/error/error.h" @@ -238,7 +239,7 @@ class Cli : public QObject return LINGLONG_ERR(reply.error().message(), reply.error().type()); } - auto result = utils::serialize::fromQVariantMap(reply.value()); + auto result = common::serialize::fromQVariantMap(reply.value()); if (!result) { LogF("bug detected: {}", result.error()); std::abort(); diff --git a/libs/utils/src/linglong/utils/dbus/properties_forwarder.cpp b/libs/linglong/src/linglong/common/dbus/properties_forwarder.cpp similarity index 84% rename from libs/utils/src/linglong/utils/dbus/properties_forwarder.cpp rename to libs/linglong/src/linglong/common/dbus/properties_forwarder.cpp index 4afd81333..1a4d25a13 100644 --- a/libs/utils/src/linglong/utils/dbus/properties_forwarder.cpp +++ b/libs/linglong/src/linglong/common/dbus/properties_forwarder.cpp @@ -4,14 +4,16 @@ #include "properties_forwarder.h" +#include "linglong/utils/log/log.h" + #include #include -#include #include +#include #include -namespace linglong::utils::dbus { +namespace linglong::common::dbus { PropertiesForwarder::PropertiesForwarder(QDBusConnection connection, QString path, @@ -23,12 +25,14 @@ PropertiesForwarder::PropertiesForwarder(QDBusConnection connection, , connection(std::move(connection)) { if (parent == nullptr) { - qFatal("parent is nullptr"); + LogE("parent is nullptr"); + std::abort(); } const auto *mo = parent->metaObject(); if (mo == nullptr) { - qFatal("couldn't find metaObject of parent."); + LogE("couldn't find metaObject of parent."); + std::abort(); } for (auto i = mo->propertyOffset(); i < mo->propertyCount(); ++i) { @@ -43,7 +47,7 @@ PropertiesForwarder::PropertiesForwarder(QDBusConnection connection, } } -error::Result PropertiesForwarder::forward() noexcept +utils::error::Result PropertiesForwarder::forward() noexcept { LINGLONG_TRACE("forward propertiesChanged") auto msg = QDBusMessage::createSignal(this->path, @@ -66,7 +70,7 @@ void PropertiesForwarder::PropertyChanged() const auto *mo = sender->metaObject(); if (mo == nullptr) { - qCritical() << __PRETTY_FUNCTION__ << "relay propertiesChanged failed."; + LogE("relay propertiesChanged failed."); return; } @@ -87,7 +91,7 @@ void PropertiesForwarder::PropertyChanged() } if (propName.isEmpty()) { - qCritical() << "can't find corresponding property:" << signature; + LogE("can't find corresponding property: {}", signature.toStdString()); return; } @@ -100,4 +104,4 @@ void PropertiesForwarder::PropertyChanged() propCache.insert(propName, prop.read(sender)); } -} // namespace linglong::utils::dbus +} // namespace linglong::common::dbus diff --git a/libs/utils/src/linglong/utils/dbus/properties_forwarder.h b/libs/linglong/src/linglong/common/dbus/properties_forwarder.h similarity index 86% rename from libs/utils/src/linglong/utils/dbus/properties_forwarder.h rename to libs/linglong/src/linglong/common/dbus/properties_forwarder.h index 9275d394e..ba1b513ae 100644 --- a/libs/utils/src/linglong/utils/dbus/properties_forwarder.h +++ b/libs/linglong/src/linglong/common/dbus/properties_forwarder.h @@ -10,7 +10,7 @@ #include #include -namespace linglong::utils::dbus { +namespace linglong::common::dbus { class PropertiesForwarder : public QObject { @@ -23,7 +23,7 @@ class PropertiesForwarder : public QObject PropertiesForwarder(PropertiesForwarder &&) = delete; PropertiesForwarder &operator=(PropertiesForwarder &&) = delete; - error::Result forward() noexcept; + utils::error::Result forward() noexcept; public Q_SLOTS: void PropertyChanged(); @@ -35,4 +35,4 @@ public Q_SLOTS: QVariantMap propCache; }; -} // namespace linglong::utils::dbus +} // namespace linglong::common::dbus diff --git a/libs/utils/src/linglong/utils/dbus/register.cpp b/libs/linglong/src/linglong/common/dbus/register.cpp similarity index 75% rename from libs/utils/src/linglong/utils/dbus/register.cpp rename to libs/linglong/src/linglong/common/dbus/register.cpp index 785a99884..6ebe1f349 100644 --- a/libs/utils/src/linglong/utils/dbus/register.cpp +++ b/libs/linglong/src/linglong/common/dbus/register.cpp @@ -4,4 +4,4 @@ * SPDX-License-Identifier: LGPL-3.0-or-later */ -#include "linglong/utils/dbus/register.h" +#include "linglong/common/dbus/register.h" diff --git a/libs/utils/src/linglong/utils/dbus/register.h b/libs/linglong/src/linglong/common/dbus/register.h similarity index 70% rename from libs/utils/src/linglong/utils/dbus/register.h rename to libs/linglong/src/linglong/common/dbus/register.h index bbc02f97b..adbb00fd1 100644 --- a/libs/utils/src/linglong/utils/dbus/register.h +++ b/libs/linglong/src/linglong/common/dbus/register.h @@ -6,22 +6,22 @@ #pragma once -#include "linglong/utils/dbus/log.h" +#include "linglong/common/formatter.h" #include "linglong/utils/error/error.h" -#include "tl/expected.hpp" +#include "linglong/utils/log/log.h" #include #include -namespace linglong::utils::dbus { +namespace linglong::common::dbus { [[nodiscard]] inline auto registerDBusObject(QDBusConnection conn, const QString &path, - QObject *obj) -> tl::expected + QObject *obj) -> utils::error::Result { LINGLONG_TRACE("register D-Bus object"); if (conn.registerObject(path, obj)) { - qCDebug(linglong_utils_dbus) << "register object to dbus on" << path; + LogD("register object to dbus on {}", path); return LINGLONG_OK; } @@ -31,20 +31,19 @@ namespace linglong::utils::dbus { inline void unregisterDBusObject(QDBusConnection conn, const QString &path) { conn.unregisterObject(path); - qCDebug(linglong_utils_dbus) << "unregister object to dbus on" << path; + LogD("unregister object to dbus on {}", path); } [[nodiscard]] inline auto registerDBusService(QDBusConnection conn, const QString &serviceName) - -> error::Result + -> utils::error::Result { LINGLONG_TRACE("register D-Bus service"); if (conn.registerService(serviceName)) { - qCDebug(linglong_utils_dbus) << "register dbus name" << serviceName; + LogD("register dbus name {}", serviceName); return LINGLONG_OK; } - error::Error err; // FIXME: use real ERROR CODE defined in API. if (conn.lastError().isValid()) { return LINGLONG_ERR(conn.lastError().name() + ": " + conn.lastError().message()); @@ -54,17 +53,16 @@ inline void unregisterDBusObject(QDBusConnection conn, const QString &path) } [[nodiscard]] inline auto unregisterDBusService(QDBusConnection conn, const QString &serviceName) - -> tl::expected + -> utils::error::Result { LINGLONG_TRACE("unregister D-Bus service"); if (conn.unregisterService(serviceName)) { - qCDebug(linglong_utils_dbus) << "unregister dbus name" << serviceName; + LogD("unregister dbus name {}", serviceName); return LINGLONG_OK; } // FIXME: use real ERROR CODE defined in API. - error::Error err; if (conn.lastError().isValid()) { return LINGLONG_ERR(conn.lastError().name() + ": " + conn.lastError().message()); } @@ -72,4 +70,4 @@ inline void unregisterDBusObject(QDBusConnection conn, const QString &path) return LINGLONG_ERR("unknown"); } -} // namespace linglong::utils::dbus +} // namespace linglong::common::dbus diff --git a/libs/linglong/src/linglong/common/formatter.cpp b/libs/linglong/src/linglong/common/formatter.cpp new file mode 100644 index 000000000..830d630bd --- /dev/null +++ b/libs/linglong/src/linglong/common/formatter.cpp @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include "formatter.h" + +#if FMT_VERSION >= 70000 +auto fmt::formatter::format(const QString &qstr, fmt::format_context &ctx) const + -> fmt::format_context::iterator +#else +auto fmt::formatter::format(const QString &qstr, fmt::format_context &ctx) + -> fmt::format_context::iterator +#endif +{ + return formatter::format(qstr.toStdString(), ctx); +} + +#if FMT_VERSION >= 70000 +auto fmt::formatter::format(const QStringList &qstrList, + fmt::format_context &ctx) const + -> fmt::format_context::iterator +#else +auto fmt::formatter::format(const QStringList &qstrList, fmt::format_context &ctx) + -> fmt::format_context::iterator +#endif +{ + return formatter::format(qstrList.join(" ").toStdString(), ctx); +} + +#if FMT_VERSION >= 70000 +auto fmt::formatter::format(const GError &error, fmt::format_context &ctx) const + -> fmt::format_context::iterator +#else +auto fmt::formatter::format(const GError &error, fmt::format_context &ctx) + -> fmt::format_context::iterator +#endif +{ + return formatter::format( + fmt::format("[code {}]:\n{}", error.code, error.message), + ctx); +} diff --git a/libs/linglong/src/linglong/common/formatter.h b/libs/linglong/src/linglong/common/formatter.h new file mode 100644 index 000000000..c91cd38d9 --- /dev/null +++ b/libs/linglong/src/linglong/common/formatter.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +#pragma once + +#include +#include + +#include +#include + +template <> +struct fmt::formatter : fmt::formatter +{ +#if FMT_VERSION >= 70000 + auto format(const QString &qstr, fmt::format_context &ctx) const + -> fmt::format_context::iterator; +#else + auto format(const QString &qstr, fmt::format_context &ctx) -> fmt::format_context::iterator; +#endif +}; + +template <> +struct fmt::formatter : fmt::formatter +{ +#if FMT_VERSION >= 70000 + auto format(const QStringList &qstrList, fmt::format_context &ctx) const + -> fmt::format_context::iterator; +#else + auto format(const QStringList &qstrList, fmt::format_context &ctx) + -> fmt::format_context::iterator; +#endif +}; + +template <> +struct fmt::formatter : fmt::formatter +{ +#if FMT_VERSION >= 70000 + auto format(const GError &error, fmt::format_context &ctx) const + -> fmt::format_context::iterator; +#else + auto format(const GError &error, fmt::format_context &ctx) -> fmt::format_context::iterator; +#endif +}; diff --git a/libs/utils/src/linglong/utils/gkeyfile_wrapper.h b/libs/linglong/src/linglong/common/gkeyfile_wrapper.h similarity index 92% rename from libs/utils/src/linglong/utils/gkeyfile_wrapper.h rename to libs/linglong/src/linglong/common/gkeyfile_wrapper.h index c9d64aed7..3a8eea1bd 100644 --- a/libs/utils/src/linglong/utils/gkeyfile_wrapper.h +++ b/libs/linglong/src/linglong/common/gkeyfile_wrapper.h @@ -15,7 +15,7 @@ #include #include -namespace linglong::utils { +namespace linglong::common { class GKeyFileWrapper final { @@ -32,7 +32,7 @@ class GKeyFileWrapper final auto operator=(const GKeyFileWrapper &) -> GKeyFileWrapper & = delete; ~GKeyFileWrapper() = default; - static auto New(const QString &filePath) -> error::Result + static auto New(const QString &filePath) -> utils::error::Result { LINGLONG_TRACE(fmt::format("create GKeyFileWrapper for {}", filePath.toStdString())); @@ -63,7 +63,7 @@ class GKeyFileWrapper final } template - auto getValue(const QString &key, const GroupName &group) const -> error::Result + auto getValue(const QString &key, const GroupName &group) const -> utils::error::Result { LINGLONG_TRACE(fmt::format("get {} from {}", key.toStdString(), group.toStdString())); @@ -94,7 +94,7 @@ class GKeyFileWrapper final return result; } - auto getkeys(const QString &group) -> error::Result + auto getkeys(const QString &group) -> utils::error::Result { LINGLONG_TRACE("get keys from " + group.toStdString()); @@ -117,7 +117,7 @@ class GKeyFileWrapper final return result; } - auto saveToFile(const QString &filepath) -> error::Result + auto saveToFile(const QString &filepath) -> utils::error::Result { LINGLONG_TRACE(fmt::format("save to {}", filepath.toStdString())); @@ -131,7 +131,7 @@ class GKeyFileWrapper final return LINGLONG_OK; } - auto hasKey(const QString &key, const GroupName &group) -> error::Result + auto hasKey(const QString &key, const GroupName &group) -> utils::error::Result { LINGLONG_TRACE( fmt::format("check {} is in {} or not", key.toStdString(), group.toStdString())); @@ -157,4 +157,4 @@ class GKeyFileWrapper final std::unique_ptr gKeyFile; }; -} // namespace linglong::utils +} // namespace linglong::common diff --git a/libs/linglong/src/linglong/common/serialize/json.cpp b/libs/linglong/src/linglong/common/serialize/json.cpp new file mode 100644 index 000000000..d5bef57e4 --- /dev/null +++ b/libs/linglong/src/linglong/common/serialize/json.cpp @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include "json.h" + +#include + +namespace linglong::common::serialize { +namespace { +QVariant decodeQDBusArgument(const QVariant &v) +{ + if (!v.canConvert()) { + return v; + } + + const QDBusArgument &complexType = v.value(); + switch (complexType.currentType()) { + case QDBusArgument::MapType: { + QVariantMap list; + complexType >> list; + + for (auto iter = list.begin(); iter != list.end(); iter++) { + iter.value() = decodeQDBusArgument(iter.value()); + } + + return list; + } + case QDBusArgument::ArrayType: { + QVariantList list; + complexType >> list; + + for (auto &item : list) { + item = decodeQDBusArgument(item); + } + + return list; + } + default: + Q_ASSERT(false); + return QVariant{}; + } +} + +} // namespace + +QJsonObject QJsonObjectfromVariantMap(const QVariantMap &map) noexcept +{ + QVariantMap newMap; + for (auto it = map.constBegin(); it != map.constEnd(); it++) { + newMap.insert(it.key(), decodeQDBusArgument(it.value())); + } + return QJsonObject::fromVariantMap(newMap); +} +} // namespace linglong::common::serialize diff --git a/libs/linglong/src/linglong/common/serialize/json.h b/libs/linglong/src/linglong/common/serialize/json.h new file mode 100644 index 000000000..bc250f018 --- /dev/null +++ b/libs/linglong/src/linglong/common/serialize/json.h @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#pragma once + +#include "linglong/common/formatter.h" +#include "linglong/utils/error/error.h" +#include "linglong/utils/serialize/json.h" + +#include +#include + +#include +#include +#include +#include +#include + +namespace linglong::common::serialize { + +QJsonObject QJsonObjectfromVariantMap(const QVariantMap &vmap) noexcept; + +template +QJsonDocument toQJsonDocument(const T &x) noexcept +{ + nlohmann::json json = x; + return QJsonDocument::fromJson(json.dump().data()); +} + +template +QVariantMap toQVariantMap(const T &x) noexcept +{ + QJsonDocument doc = toQJsonDocument(x); + Q_ASSERT(doc.isObject()); + return doc.object().toVariantMap(); +} + +template +utils::error::Result fromQJsonDocument(const QJsonDocument &doc) noexcept +{ + return utils::serialize::LoadJSON(doc.toJson(QJsonDocument::Compact).toStdString()); +} + +template +utils::error::Result fromQJsonObject(const QJsonObject &obj) noexcept +{ + return fromQJsonDocument(QJsonDocument(obj)); +} + +template +utils::error::Result fromQVariantMap(const QVariantMap &vmap) +{ + return fromQJsonObject(QJsonObjectfromVariantMap(vmap)); +} + +template +utils::error::Result LoadJSONFile(GFile *file) noexcept +{ + g_autofree char *path = g_file_get_path(file); + LINGLONG_TRACE(fmt::format("load json from {}", path)); + + g_autoptr(GError) gErr = nullptr; + g_autofree gchar *content = nullptr; + gsize length; + + if (!g_file_load_contents(file, nullptr, &content, &length, nullptr, &gErr)) { + return LINGLONG_ERR(fmt::format("g_file_load_contents {}", *gErr)); + } + + return utils::serialize::LoadJSON(content); +} + +} // namespace linglong::common::serialize diff --git a/libs/linglong/src/linglong/package/layer_file.cpp b/libs/linglong/src/linglong/package/layer_file.cpp index dc689b96a..0d4c424fe 100644 --- a/libs/linglong/src/linglong/package/layer_file.cpp +++ b/libs/linglong/src/linglong/package/layer_file.cpp @@ -9,6 +9,7 @@ #include "linglong/api/types/v1/Generators.hpp" // IWYU pragma: keep #include "linglong/api/types/v1/LayerInfo.hpp" #include "linglong/common/error.h" +#include "linglong/common/formatter.h" #include "linglong/utils/error/error.h" #include "linglong/utils/log/formatter.h" // IWYU pragma: keep #include "linglong/utils/serialize/json.h" diff --git a/libs/linglong/src/linglong/package_manager/package_manager.cpp b/libs/linglong/src/linglong/package_manager/package_manager.cpp index 247b2303d..a07b51035 100644 --- a/libs/linglong/src/linglong/package_manager/package_manager.cpp +++ b/libs/linglong/src/linglong/package_manager/package_manager.cpp @@ -14,6 +14,7 @@ #include "linglong/api/types/v1/Repo.hpp" #include "linglong/api/types/v1/State.hpp" #include "linglong/common/error.h" +#include "linglong/common/serialize/json.h" #include "linglong/common/strings.h" #include "linglong/extension/extension.h" #include "linglong/package/layer_file.h" @@ -59,7 +60,7 @@ QVariantMap toDBusReply(const utils::error::Result &x, std::string type = "di { Q_ASSERT(!x.has_value()); - return utils::serialize::toQVariantMap( + return common::serialize::toQVariantMap( api::types::v1::CommonResult{ .code = x.error().code(), // NOLINT .message = x.error().message(), // NOLINT .type = std::move(type) }); @@ -69,7 +70,7 @@ QVariantMap toDBusReply(utils::error::ErrorCode code, const std::string &message, const std::string &type = "display") noexcept { - return utils::serialize::toQVariantMap( + return common::serialize::toQVariantMap( api::types::v1::CommonResult{ .code = static_cast(code), // NOLINT .message = message, // NOLINT .type = type }); @@ -229,7 +230,7 @@ PackageManager::getAllRunningContainers() noexcept auto content = utils::serialize::LoadJSONFile( - QString::fromStdString(process_entry.path().string())); + process_entry.path()); if (!content) { return LINGLONG_ERR(QStringLiteral("failed to load info from %1: %2") .arg(process_entry.path().c_str()) @@ -430,13 +431,13 @@ void PackageManager::deferredUninstall() noexcept auto PackageManager::getConfiguration() const noexcept -> QVariantMap { - return utils::serialize::toQVariantMap(this->repo.getConfig()); + return common::serialize::toQVariantMap(this->repo.getConfig()); } void PackageManager::setConfiguration(const QVariantMap ¶meters) noexcept { LogI("set configuration for package manager"); - auto cfg = utils::serialize::fromQVariantMap(parameters); + auto cfg = common::serialize::fromQVariantMap(parameters); if (!cfg) { sendErrorReply(QDBusError::InvalidArgs, QString::fromStdString(cfg.error().message())); return; @@ -575,7 +576,7 @@ QVariantMap PackageManager::installFromLayer(const QDBusUnixFileDescriptor &fd, && !options.skipInteraction) { Q_EMIT RequestInteraction(QDBusObjectPath(taskRef.taskObjectPath().c_str()), static_cast(msgType), - utils::serialize::toQVariantMap(additionalMessage)); + common::serialize::toQVariantMap(additionalMessage)); QEventLoop loop; auto conn = connect( this, @@ -583,7 +584,7 @@ QVariantMap PackageManager::installFromLayer(const QDBusUnixFileDescriptor &fd, [&taskRef, &loop](const QVariantMap &reply) { // handle reply auto interactionReply = - utils::serialize::fromQVariantMap(reply); + common::serialize::fromQVariantMap(reply); if (interactionReply->action != "yes") { taskRef.updateState(linglong::api::types::v1::State::Canceled, "canceled"); } @@ -686,7 +687,7 @@ QVariantMap PackageManager::installFromLayer(const QDBusUnixFileDescriptor &fd, auto &taskRef = taskRet->get(); Q_EMIT TaskAdded(QDBusObjectPath{ taskRef.taskObjectPath().c_str() }); taskRef.updateState(linglong::api::types::v1::State::Queued, "queued to install from layer"); - return utils::serialize::toQVariantMap(api::types::v1::PackageManager1PackageTaskResult{ + return common::serialize::toQVariantMap(api::types::v1::PackageManager1PackageTaskResult{ .taskObjectPath = taskRef.taskObjectPath(), .code = 0, .message = (realFile + " is now installing").toStdString(), @@ -727,7 +728,7 @@ auto PackageManager::InstallFromFile(const QDBusUnixFileDescriptor &fd, return toDBusReply(utils::error::ErrorCode::Failed, "invalid file descriptor"); } - auto opts = utils::serialize::fromQVariantMap(options); + auto opts = common::serialize::fromQVariantMap(options); if (!opts) { return toDBusReply(opts); } @@ -750,7 +751,7 @@ auto PackageManager::InstallFromFile(const QDBusUnixFileDescriptor &fd, auto PackageManager::Install(const QVariantMap ¶meters) noexcept -> QVariantMap { auto paras = - utils::serialize::fromQVariantMap( + common::serialize::fromQVariantMap( parameters); if (!paras) { return toDBusReply(utils::error::ErrorCode::AppInstallFailed, paras.error().message()); @@ -796,7 +797,7 @@ auto PackageManager::Install(const QVariantMap ¶meters) noexcept -> QVariant auto PackageManager::Uninstall(const QVariantMap ¶meters) noexcept -> QVariantMap { auto paras = - utils::serialize::fromQVariantMap( + common::serialize::fromQVariantMap( parameters); if (!paras) { return toDBusReply(utils::error::ErrorCode::AppUninstallFailed, paras.error().message()); @@ -897,7 +898,7 @@ auto PackageManager::Uninstall(const QVariantMap ¶meters) noexcept -> QVaria auto &taskRef = taskRet->get(); Q_EMIT TaskAdded(QDBusObjectPath{ taskRef.taskObjectPath().c_str() }); taskRef.updateState(linglong::api::types::v1::State::Queued, "queued to uninstall"); - return utils::serialize::toQVariantMap(api::types::v1::PackageManager1PackageTaskResult{ + return common::serialize::toQVariantMap(api::types::v1::PackageManager1PackageTaskResult{ .taskObjectPath = taskRef.taskObjectPath(), .code = 0, .message = refSpec + " is now uninstalling", @@ -949,8 +950,9 @@ utils::error::Result PackageManager::Uninstall(PackageTask &taskContext, auto PackageManager::Update(const QVariantMap ¶meters) noexcept -> QVariantMap { - auto paras = utils::serialize::fromQVariantMap( - parameters); + auto paras = + common::serialize::fromQVariantMap( + parameters); if (!paras) { return toDBusReply(utils::error::ErrorCode::AppUpgradeFailed, paras.error().message()); } @@ -1079,8 +1081,9 @@ utils::error::Result PackageManager::uninstallRef( auto PackageManager::Search(const QVariantMap ¶meters) noexcept -> QVariantMap { - auto paras = utils::serialize::fromQVariantMap( - parameters); + auto paras = + common::serialize::fromQVariantMap( + parameters); if (!paras) { return toDBusReply(paras); } @@ -1110,7 +1113,7 @@ auto PackageManager::Search(const QVariantMap ¶meters) noexcept -> QVariantM Q_EMIT this->SearchFinished( QString::fromStdString(task.taskID()), - utils::serialize::toQVariantMap(api::types::v1::PackageManager1SearchResult{ + common::serialize::toQVariantMap(api::types::v1::PackageManager1SearchResult{ .packages = std::move(pkgs), .code = 0, .message = "", @@ -1124,7 +1127,7 @@ auto PackageManager::Search(const QVariantMap ¶meters) noexcept -> QVariantM auto &taskRef = task->get(); taskRef.updateState(linglong::api::types::v1::State::Queued, fmt::format("search {}", paras->id)); - auto result = utils::serialize::toQVariantMap(api::types::v1::PackageManager1JobInfo{ + auto result = common::serialize::toQVariantMap(api::types::v1::PackageManager1JobInfo{ .id = taskRef.taskID(), .code = 0, .message = "", @@ -1214,7 +1217,7 @@ auto PackageManager::Prune() noexcept -> QVariantMap .message = "", }; Q_EMIT PruneFinished(QString::fromStdString(task.taskID()), - utils::serialize::toQVariantMap(result)); + common::serialize::toQVariantMap(result)); task.updateState(linglong::api::types::v1::State::Succeed, "prune"); }); if (!task) { @@ -1223,7 +1226,7 @@ auto PackageManager::Prune() noexcept -> QVariantMap auto &taskRef = task->get(); taskRef.updateState(linglong::api::types::v1::State::Queued, "prune"); - auto result = utils::serialize::toQVariantMap(api::types::v1::PackageManager1JobInfo{ + auto result = common::serialize::toQVariantMap(api::types::v1::PackageManager1JobInfo{ .id = taskRef.taskID(), .code = 0, .message = "", @@ -1459,12 +1462,12 @@ bool PackageManager::waitConfirm( { Q_EMIT RequestInteraction(QDBusObjectPath(taskRef.taskObjectPath().c_str()), static_cast(msgType), - utils::serialize::toQVariantMap(additionalMessage)); + common::serialize::toQVariantMap(additionalMessage)); QEventLoop loop; auto conn = connect(this, &PackageManager::ReplyReceived, [&taskRef, &loop](const QVariantMap &reply) { auto interactionReply = - utils::serialize::fromQVariantMap(reply); + common::serialize::fromQVariantMap(reply); if (interactionReply->action != "yes") { taskRef.updateState(linglong::api::types::v1::State::Canceled, "canceled"); } @@ -1507,7 +1510,7 @@ QVariantMap PackageManager::runActionOnTaskQueue(std::shared_ptr action) auto &taskRef = taskRet->get(); Q_EMIT TaskAdded(QDBusObjectPath{ taskRef.taskObjectPath().c_str() }); taskRef.updateState(linglong::api::types::v1::State::Queued, action->getTaskName()); - return utils::serialize::toQVariantMap(api::types::v1::PackageManager1PackageTaskResult{ + return common::serialize::toQVariantMap(api::types::v1::PackageManager1PackageTaskResult{ .taskObjectPath = taskRef.taskObjectPath(), .code = 0, .message = action->getTaskName() + " is queued", diff --git a/libs/linglong/src/linglong/package_manager/package_task.cpp b/libs/linglong/src/linglong/package_manager/package_task.cpp index d844aa35b..c28ff7ce8 100644 --- a/libs/linglong/src/linglong/package_manager/package_task.cpp +++ b/libs/linglong/src/linglong/package_manager/package_task.cpp @@ -5,8 +5,8 @@ #include "package_task.h" #include "linglong/adaptors/task/task1.h" +#include "linglong/common/dbus/register.h" #include "linglong/package_manager/package_manager.h" -#include "linglong/utils/dbus/register.h" #include "linglong/utils/error/error.h" #include "linglong/utils/global/initialize.h" #include "linglong/utils/log/formatter.h" // IWYU pragma: keep @@ -96,14 +96,14 @@ utils::error::Result PackageTask::exposeOnDBus(const QDBusConnection &conn return LINGLONG_ERR("internal adaptor error"); } auto ret = - linglong::utils::dbus::registerDBusObject(connection, taskObjectPath().c_str(), this); + linglong::common::dbus::registerDBusObject(connection, taskObjectPath().c_str(), this); if (!ret) { return LINGLONG_ERR(ret); } const auto *interface = mo->classInfo(interfaceIndex).value(); m_forwarder = - new utils::dbus::PropertiesForwarder(connection, taskObjectPath().c_str(), interface, this); + new common::dbus::PropertiesForwarder(connection, taskObjectPath().c_str(), interface, this); QObject::connect(this, &PackageTask::changePropertiesDone, m_forwarder, [this]() { auto ret = m_forwarder->forward(); diff --git a/libs/linglong/src/linglong/package_manager/package_task.h b/libs/linglong/src/linglong/package_manager/package_task.h index ac75e887e..05926cf0e 100644 --- a/libs/linglong/src/linglong/package_manager/package_task.h +++ b/libs/linglong/src/linglong/package_manager/package_task.h @@ -5,8 +5,8 @@ #pragma once #include "linglong/api/types/v1/State.hpp" +#include "linglong/common/dbus/properties_forwarder.h" #include "linglong/package_manager/task.h" -#include "linglong/utils/dbus/properties_forwarder.h" #include "linglong/utils/error/error.h" #include "linglong/utils/log/log.h" @@ -87,7 +87,7 @@ public Q_SLOTS: private: friend class PackageTaskQueue; GCancellable *m_cancelFlag{ nullptr }; - utils::dbus::PropertiesForwarder *m_forwarder{ nullptr }; + common::dbus::PropertiesForwarder *m_forwarder{ nullptr }; }; // PackageTaskQueue is used to manage tasks and run them in a separated thread diff --git a/libs/linglong/src/linglong/repo/ostree_repo.cpp b/libs/linglong/src/linglong/repo/ostree_repo.cpp index 7f60f36e6..0283dbd1b 100644 --- a/libs/linglong/src/linglong/repo/ostree_repo.cpp +++ b/libs/linglong/src/linglong/repo/ostree_repo.cpp @@ -13,6 +13,8 @@ #include "linglong/api/types/v1/Repo.hpp" #include "linglong/api/types/v1/RepositoryCacheLayersItem.hpp" #include "linglong/api/types/v1/RepositoryCacheMergedItem.hpp" +#include "linglong/common/formatter.h" +#include "linglong/common/gkeyfile_wrapper.h" #include "linglong/common/strings.h" #include "linglong/package/fuzzy_reference.h" #include "linglong/package/layer_dir.h" @@ -24,7 +26,6 @@ #include "linglong/utils/error/error.h" #include "linglong/utils/file.h" #include "linglong/utils/finally/finally.h" -#include "linglong/utils/gkeyfile_wrapper.h" #include "linglong/utils/log/log.h" #include "linglong/utils/serialize/json.h" #include "linglong/utils/serialize/packageinfo_handler.h" @@ -2727,7 +2728,7 @@ utils::error::Result desktopFileRewrite(const QString &filePath, const QSt { LINGLONG_TRACE(fmt::format("rewrite desktop file {}", filePath.toStdString())); - auto file = utils::GKeyFileWrapper::New(filePath); + auto file = common::GKeyFileWrapper::New(filePath); if (!file) { return LINGLONG_ERR(file); } @@ -2762,8 +2763,8 @@ utils::error::Result desktopFileRewrite(const QString &filePath, const QSt file->setValue("Exec", buildDesktopExec(rawExec, id), group); } - file->setValue("TryExec", LINGLONG_CLIENT_PATH, utils::GKeyFileWrapper::DesktopEntry); - file->setValue("X-linglong", id, utils::GKeyFileWrapper::DesktopEntry); + file->setValue("TryExec", LINGLONG_CLIENT_PATH, common::GKeyFileWrapper::DesktopEntry); + file->setValue("X-linglong", id, common::GKeyFileWrapper::DesktopEntry); // save file auto ret = file->saveToFile(filePath); @@ -2778,12 +2779,12 @@ utils::error::Result dbusServiceRewrite(const QString &filePath, const QSt { LINGLONG_TRACE(fmt::format("rewrite dbus service file {}", filePath.toStdString())); - auto file = utils::GKeyFileWrapper::New(filePath); + auto file = common::GKeyFileWrapper::New(filePath); if (!file) { return LINGLONG_ERR(file); } - auto hasExecRet = file->hasKey("Exec", utils::GKeyFileWrapper::DBusService); + auto hasExecRet = file->hasKey("Exec", common::GKeyFileWrapper::DBusService); if (!hasExecRet) { return LINGLONG_ERR(hasExecRet); } @@ -2793,7 +2794,7 @@ utils::error::Result dbusServiceRewrite(const QString &filePath, const QSt return LINGLONG_OK; } - auto originExec = file->getValue("Exec", utils::GKeyFileWrapper::DBusService); + auto originExec = file->getValue("Exec", common::GKeyFileWrapper::DBusService); if (!originExec) { return LINGLONG_ERR(originExec); } @@ -2805,7 +2806,7 @@ utils::error::Result dbusServiceRewrite(const QString &filePath, const QSt } auto newExec = QString("%1 run %2 -- %3").arg(LINGLONG_CLIENT_PATH, id, rawExec); - file->setValue("Exec", newExec, utils::GKeyFileWrapper::DBusService); + file->setValue("Exec", newExec, common::GKeyFileWrapper::DBusService); auto ret = file->saveToFile(filePath); if (!ret) { @@ -2823,12 +2824,12 @@ utils::error::Result systemdServiceRewrite(const QString &filePath, const // NOTE: The key is allowed to be repeated in the service group QStringList execKeys{ "ExecStart", "ExecStartPost", "ExecCondition", "ExecStop", "ExecStopPost", "ExecReload" }; - auto file = utils::GKeyFileWrapper::New(filePath); + auto file = common::GKeyFileWrapper::New(filePath); if (!file) { return LINGLONG_ERR(file); } - auto keysRet = file->getkeys(utils::GKeyFileWrapper::SystemdService); + auto keysRet = file->getkeys(common::GKeyFileWrapper::SystemdService); if (!keysRet) { return LINGLONG_ERR(keysRet); } @@ -2839,7 +2840,7 @@ utils::error::Result systemdServiceRewrite(const QString &filePath, const continue; } - auto originExec = file->getValue(key, utils::GKeyFileWrapper::SystemdService); + auto originExec = file->getValue(key, common::GKeyFileWrapper::SystemdService); if (!originExec) { return LINGLONG_ERR(originExec); } @@ -2851,7 +2852,7 @@ utils::error::Result systemdServiceRewrite(const QString &filePath, const } auto newExec = QString("%1 run %2 -- %3").arg(LINGLONG_CLIENT_PATH, id, rawExec); - file->setValue(key, newExec, utils::GKeyFileWrapper::SystemdService); + file->setValue(key, newExec, common::GKeyFileWrapper::SystemdService); } auto ret = file->saveToFile(filePath); @@ -2866,7 +2867,7 @@ utils::error::Result contextMenuRewrite(const QString &filePath, const QSt { LINGLONG_TRACE(fmt::format("rewrite context menu{}", filePath.toStdString())); - auto file = utils::GKeyFileWrapper::New(filePath); + auto file = common::GKeyFileWrapper::New(filePath); if (!file) { return LINGLONG_ERR(file); } diff --git a/libs/linglong/tests/ll-tests/CMakeLists.txt b/libs/linglong/tests/ll-tests/CMakeLists.txt index 93ab7b36b..a9adcb5a7 100644 --- a/libs/linglong/tests/ll-tests/CMakeLists.txt +++ b/libs/linglong/tests/ll-tests/CMakeLists.txt @@ -17,6 +17,7 @@ pfl_add_executable( src/linglong/builder/linglong_builder_test.cpp src/linglong/builder/source_fetcher_test.cpp src/linglong/cli/cli_test.cpp + src/linglong/common/gkeyfile_wrapper_test.cpp src/linglong/common/strings_test.cpp src/linglong/common/socket_test.cpp src/linglong/common/xdg_test.cpp @@ -52,7 +53,6 @@ pfl_add_executable( src/linglong/utils/error/error_test.cpp src/linglong/utils/file_test.cpp src/linglong/utils/filelock_test.cpp - src/linglong/utils/gkeyfile_wrapper_test.cpp src/linglong/utils/log.cpp src/linglong/utils/namespce.cpp src/linglong/utils/packageinfo_handler_test.cpp diff --git a/libs/linglong/tests/ll-tests/src/linglong/utils/gkeyfile_wrapper_test.cpp b/libs/linglong/tests/ll-tests/src/linglong/common/gkeyfile_wrapper_test.cpp similarity index 69% rename from libs/linglong/tests/ll-tests/src/linglong/utils/gkeyfile_wrapper_test.cpp rename to libs/linglong/tests/ll-tests/src/linglong/common/gkeyfile_wrapper_test.cpp index 3f57be66f..d403e355c 100644 --- a/libs/linglong/tests/ll-tests/src/linglong/utils/gkeyfile_wrapper_test.cpp +++ b/libs/linglong/tests/ll-tests/src/linglong/common/gkeyfile_wrapper_test.cpp @@ -4,8 +4,8 @@ #include +#include "linglong/common/gkeyfile_wrapper.h" #include "linglong/utils/error/error.h" -#include "linglong/utils/gkeyfile_wrapper.h" #include #include @@ -48,7 +48,7 @@ class GKeyFileWrapperTest : public ::testing::Test TEST_F(GKeyFileWrapperTest, NewWithNonExistentFile) { - auto result = linglong::utils::GKeyFileWrapper::New("/nonexistent/file.ini"); + auto result = linglong::common::GKeyFileWrapper::New("/nonexistent/file.ini"); EXPECT_FALSE(result.has_value()); EXPECT_TRUE(result.error().message().find("no such file") != std::string::npos); } @@ -63,7 +63,7 @@ Icon=test-icon createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); EXPECT_TRUE(result.has_value()); } @@ -76,7 +76,7 @@ Name=Test Application createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); EXPECT_FALSE(result.has_value()); } @@ -88,23 +88,23 @@ Name=Test Application createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); ASSERT_TRUE(result.has_value()); auto &wrapper = *result; // 设置新值 - wrapper.setValue("Exec", "/usr/bin/new-app", linglong::utils::GKeyFileWrapper::DesktopEntry); + wrapper.setValue("Exec", "/usr/bin/new-app", linglong::common::GKeyFileWrapper::DesktopEntry); // 获取值 auto execValue = - wrapper.getValue("Exec", linglong::utils::GKeyFileWrapper::DesktopEntry); + wrapper.getValue("Exec", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(execValue.has_value()); EXPECT_EQ(*execValue, "/usr/bin/new-app"); // 获取已存在的值 auto nameValue = - wrapper.getValue("Name", linglong::utils::GKeyFileWrapper::DesktopEntry); + wrapper.getValue("Name", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(nameValue.has_value()); EXPECT_EQ(*nameValue, "Test Application"); } @@ -117,14 +117,14 @@ Name=Test Application createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); ASSERT_TRUE(result.has_value()); auto &wrapper = *result; // 获取不存在的键 auto nonExistentValue = - wrapper.getValue("NonExistentKey", linglong::utils::GKeyFileWrapper::DesktopEntry); + wrapper.getValue("NonExistentKey", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_FALSE(nonExistentValue.has_value()); } @@ -136,7 +136,7 @@ Name=Test Application createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); ASSERT_TRUE(result.has_value()); auto &wrapper = *result; @@ -160,7 +160,7 @@ ExecStart=/usr/bin/test-service createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); ASSERT_TRUE(result.has_value()); auto &wrapper = *result; @@ -182,12 +182,12 @@ Icon=test-icon createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); ASSERT_TRUE(result.has_value()); auto &wrapper = *result; - auto keys = wrapper.getkeys(linglong::utils::GKeyFileWrapper::DesktopEntry); + auto keys = wrapper.getkeys(linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(keys.has_value()); EXPECT_EQ(keys->size(), 3); EXPECT_TRUE(keys->contains("Name")); @@ -203,7 +203,7 @@ Name=Test Application createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); ASSERT_TRUE(result.has_value()); auto &wrapper = *result; @@ -220,7 +220,7 @@ Name=Test Application createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); ASSERT_TRUE(result.has_value()); auto &wrapper = *result; @@ -228,8 +228,8 @@ Name=Test Application // 修改内容 wrapper.setValue("Exec", "/usr/bin/modified-app", - linglong::utils::GKeyFileWrapper::DesktopEntry); - wrapper.setValue("Icon", "modified-icon", linglong::utils::GKeyFileWrapper::DesktopEntry); + linglong::common::GKeyFileWrapper::DesktopEntry); + wrapper.setValue("Icon", "modified-icon", linglong::common::GKeyFileWrapper::DesktopEntry); // 保存到新文件 QString newFilePath = tempFilePath + ".new"; @@ -237,16 +237,16 @@ Name=Test Application EXPECT_TRUE(saveResult.has_value()); // 验证新文件内容 - auto newWrapper = linglong::utils::GKeyFileWrapper::New(newFilePath); + auto newWrapper = linglong::common::GKeyFileWrapper::New(newFilePath); EXPECT_TRUE(newWrapper.has_value()); auto execValue = - newWrapper->getValue("Exec", linglong::utils::GKeyFileWrapper::DesktopEntry); + newWrapper->getValue("Exec", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(execValue.has_value()); EXPECT_EQ(*execValue, "/usr/bin/modified-app"); auto iconValue = - newWrapper->getValue("Icon", linglong::utils::GKeyFileWrapper::DesktopEntry); + newWrapper->getValue("Icon", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(iconValue.has_value()); EXPECT_EQ(*iconValue, "modified-icon"); @@ -263,23 +263,23 @@ Exec=/usr/bin/test-app createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); ASSERT_TRUE(result.has_value()); auto &wrapper = *result; // 测试存在的键 - auto hasName = wrapper.hasKey("Name", linglong::utils::GKeyFileWrapper::DesktopEntry); + auto hasName = wrapper.hasKey("Name", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(hasName.has_value()); EXPECT_TRUE(*hasName); - auto hasExec = wrapper.hasKey("Exec", linglong::utils::GKeyFileWrapper::DesktopEntry); + auto hasExec = wrapper.hasKey("Exec", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(hasExec.has_value()); EXPECT_TRUE(*hasExec); // 测试不存在的键 auto hasNonExistent = - wrapper.hasKey("NonExistentKey", linglong::utils::GKeyFileWrapper::DesktopEntry); + wrapper.hasKey("NonExistentKey", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(hasNonExistent.has_value()); EXPECT_FALSE(*hasNonExistent); } @@ -292,7 +292,7 @@ Name=Test Application createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); ASSERT_TRUE(result.has_value()); auto &wrapper = *result; @@ -304,10 +304,10 @@ Name=Test Application TEST_F(GKeyFileWrapperTest, Constants) { // 测试常量定义 - EXPECT_EQ(linglong::utils::GKeyFileWrapper::DesktopEntry, "Desktop Entry"); - EXPECT_EQ(linglong::utils::GKeyFileWrapper::DBusService, "D-BUS Service"); - EXPECT_EQ(linglong::utils::GKeyFileWrapper::SystemdService, "Service"); - EXPECT_EQ(linglong::utils::GKeyFileWrapper::ContextMenu, "Menu Entry"); + EXPECT_EQ(linglong::common::GKeyFileWrapper::DesktopEntry, "Desktop Entry"); + EXPECT_EQ(linglong::common::GKeyFileWrapper::DBusService, "D-BUS Service"); + EXPECT_EQ(linglong::common::GKeyFileWrapper::SystemdService, "Service"); + EXPECT_EQ(linglong::common::GKeyFileWrapper::ContextMenu, "Menu Entry"); } TEST_F(GKeyFileWrapperTest, EmptyFile) @@ -315,7 +315,7 @@ TEST_F(GKeyFileWrapperTest, EmptyFile) // 创建空文件 createTestFile(""); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); EXPECT_TRUE(result.has_value()); auto &wrapper = *result; @@ -333,41 +333,41 @@ Name=Original Name createTestFile(content); - auto result = linglong::utils::GKeyFileWrapper::New(tempFilePath); + auto result = linglong::common::GKeyFileWrapper::New(tempFilePath); ASSERT_TRUE(result.has_value()); auto &wrapper = *result; // 执行多个操作 - wrapper.setValue("Name", "Updated Name", linglong::utils::GKeyFileWrapper::DesktopEntry); + wrapper.setValue("Name", "Updated Name", linglong::common::GKeyFileWrapper::DesktopEntry); wrapper.setValue("Exec", "/usr/bin/updated-app", - linglong::utils::GKeyFileWrapper::DesktopEntry); - wrapper.setValue("Icon", "updated-icon", linglong::utils::GKeyFileWrapper::DesktopEntry); + linglong::common::GKeyFileWrapper::DesktopEntry); + wrapper.setValue("Icon", "updated-icon", linglong::common::GKeyFileWrapper::DesktopEntry); // 验证所有更改 auto nameValue = - wrapper.getValue("Name", linglong::utils::GKeyFileWrapper::DesktopEntry); + wrapper.getValue("Name", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(nameValue.has_value()); EXPECT_EQ(*nameValue, "Updated Name"); auto execValue = - wrapper.getValue("Exec", linglong::utils::GKeyFileWrapper::DesktopEntry); + wrapper.getValue("Exec", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(execValue.has_value()); EXPECT_EQ(*execValue, "/usr/bin/updated-app"); auto iconValue = - wrapper.getValue("Icon", linglong::utils::GKeyFileWrapper::DesktopEntry); + wrapper.getValue("Icon", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(iconValue.has_value()); EXPECT_EQ(*iconValue, "updated-icon"); // 验证键的存在 - auto hasAllKeys = wrapper.hasKey("Name", linglong::utils::GKeyFileWrapper::DesktopEntry); + auto hasAllKeys = wrapper.hasKey("Name", linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(hasAllKeys.has_value()); EXPECT_TRUE(*hasAllKeys); // 验证组中的键数量 - auto keys = wrapper.getkeys(linglong::utils::GKeyFileWrapper::DesktopEntry); + auto keys = wrapper.getkeys(linglong::common::GKeyFileWrapper::DesktopEntry); EXPECT_TRUE(keys.has_value()); EXPECT_EQ(keys->size(), 3); } diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt index d1f8610ad..31cf82a8f 100644 --- a/libs/utils/CMakeLists.txt +++ b/libs/utils/CMakeLists.txt @@ -14,12 +14,6 @@ pfl_add_library( src/linglong/utils/cmd.h src/linglong/utils/env.cpp src/linglong/utils/env.h - src/linglong/utils/dbus/log.cpp - src/linglong/utils/dbus/log.h - src/linglong/utils/dbus/properties_forwarder.cpp - src/linglong/utils/dbus/properties_forwarder.h - src/linglong/utils/dbus/register.cpp - src/linglong/utils/dbus/register.h src/linglong/utils/error/details/error_impl.cpp src/linglong/utils/error/details/error_impl.h src/linglong/utils/error/error.cpp @@ -31,7 +25,6 @@ pfl_add_library( src/linglong/utils/finally/finally.cpp src/linglong/utils/finally/finally.h src/linglong/utils/gettext.h - src/linglong/utils/gkeyfile_wrapper.h src/linglong/utils/global/initialize.cpp src/linglong/utils/global/initialize.h src/linglong/utils/hooks.cpp diff --git a/libs/utils/src/linglong/utils/dbus/log.cpp b/libs/utils/src/linglong/utils/dbus/log.cpp deleted file mode 100644 index c9eb856ed..000000000 --- a/libs/utils/src/linglong/utils/dbus/log.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ - -#include "linglong/utils/dbus/log.h" - -Q_LOGGING_CATEGORY(linglong_utils_dbus, "linglong::utils::dbus") // NOLINT diff --git a/libs/utils/src/linglong/utils/dbus/log.h b/libs/utils/src/linglong/utils/dbus/log.h deleted file mode 100644 index d1c12e30e..000000000 --- a/libs/utils/src/linglong/utils/dbus/log.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ - -#pragma once - -#include "QLoggingCategory" - -Q_DECLARE_LOGGING_CATEGORY(linglong_utils_dbus); // NOLINT diff --git a/libs/utils/src/linglong/utils/log/formatter.cpp b/libs/utils/src/linglong/utils/log/formatter.cpp index a141e5129..677b5c1b5 100644 --- a/libs/utils/src/linglong/utils/log/formatter.cpp +++ b/libs/utils/src/linglong/utils/log/formatter.cpp @@ -6,29 +6,6 @@ #include "formatter.h" -#if FMT_VERSION >= 70000 -auto fmt::formatter::format(const QString &qstr, fmt::format_context &ctx) const - -> fmt::format_context::iterator -#else -auto fmt::formatter::format(const QString &qstr, fmt::format_context &ctx) - -> fmt::format_context::iterator -#endif -{ - return formatter::format(qstr.toStdString(), ctx); -} - -#if FMT_VERSION >= 70000 -auto fmt::formatter::format(const QStringList &qstrList, - fmt::format_context &ctx) const - -> fmt::format_context::iterator -#else -auto fmt::formatter::format(const QStringList &qstrList, fmt::format_context &ctx) - -> fmt::format_context::iterator -#endif -{ - return formatter::format(qstrList.join(" ").toStdString(), ctx); -} - #if FMT_VERSION >= 70000 auto fmt::formatter::format( const linglong::utils::error::Error &error, fmt::format_context &ctx) const @@ -54,5 +31,5 @@ auto fmt::formatter::format(const std::filesystem::path & -> fmt::format_context::iterator #endif { - return formatter::format(path.string(), ctx); + return formatter::format(path.string(), ctx); } diff --git a/libs/utils/src/linglong/utils/log/formatter.h b/libs/utils/src/linglong/utils/log/formatter.h index 371016c56..5bb2de632 100644 --- a/libs/utils/src/linglong/utils/log/formatter.h +++ b/libs/utils/src/linglong/utils/log/formatter.h @@ -9,37 +9,11 @@ #include -#include -#include - #include #include template <> -struct fmt::formatter : fmt::formatter -{ -#if FMT_VERSION >= 70000 - auto format(const QString &qstr, fmt::format_context &ctx) const - -> fmt::format_context::iterator; -#else - auto format(const QString &qstr, fmt::format_context &ctx) -> fmt::format_context::iterator; -#endif -}; - -template <> -struct fmt::formatter : fmt::formatter -{ -#if FMT_VERSION >= 70000 - auto format(const QStringList &qstrList, fmt::format_context &ctx) const - -> fmt::format_context::iterator; -#else - auto format(const QStringList &qstrList, fmt::format_context &ctx) - -> fmt::format_context::iterator; -#endif -}; - -template <> -struct fmt::formatter : fmt::formatter +struct fmt::formatter : fmt::formatter { #if FMT_VERSION >= 70000 auto format(const linglong::utils::error::Error &error, fmt::format_context &ctx) const @@ -51,7 +25,7 @@ struct fmt::formatter : fmt::formatter }; template <> -struct fmt::formatter : fmt::formatter +struct fmt::formatter : fmt::formatter { #if FMT_VERSION >= 70000 auto format(const std::filesystem::path &path, fmt::format_context &ctx) const diff --git a/libs/utils/src/linglong/utils/serialize/json.cpp b/libs/utils/src/linglong/utils/serialize/json.cpp index fe7ee6e1e..724eea42b 100644 --- a/libs/utils/src/linglong/utils/serialize/json.cpp +++ b/libs/utils/src/linglong/utils/serialize/json.cpp @@ -5,55 +5,3 @@ */ #include "linglong/utils/serialize/json.h" - -#include -#include -#include - -namespace linglong::utils::serialize { -namespace { -QVariant decodeQDBusArgument(const QVariant &v) -{ - if (!v.canConvert()) { - return v; - } - - const QDBusArgument &complexType = v.value(); - switch (complexType.currentType()) { - case QDBusArgument::MapType: { - QVariantMap list; - complexType >> list; - - for (auto iter = list.begin(); iter != list.end(); iter++) { - iter.value() = decodeQDBusArgument(iter.value()); - } - - return list; - } - case QDBusArgument::ArrayType: { - QVariantList list; - complexType >> list; - - for (auto &item : list) { - item = decodeQDBusArgument(item); - } - - return list; - } - default: - Q_ASSERT(false); - return QVariant{}; - } -} - -} // namespace - -QJsonObject QJsonObjectfromVariantMap(const QVariantMap &map) noexcept -{ - QVariantMap newMap; - for (auto it = map.constBegin(); it != map.constEnd(); it++) { - newMap.insert(it.key(), decodeQDBusArgument(it.value())); - } - return QJsonObject::fromVariantMap(newMap); -} -} // namespace linglong::utils::serialize diff --git a/libs/utils/src/linglong/utils/serialize/json.h b/libs/utils/src/linglong/utils/serialize/json.h index a44287557..f9f7bb43a 100644 --- a/libs/utils/src/linglong/utils/serialize/json.h +++ b/libs/utils/src/linglong/utils/serialize/json.h @@ -12,35 +12,12 @@ #include "nlohmann/json.hpp" #include -#include - -#include -#include -#include -#include #include #include namespace linglong::utils::serialize { -QJsonObject QJsonObjectfromVariantMap(const QVariantMap &vmap) noexcept; - -template -QJsonDocument toQJsonDocument(const T &x) noexcept -{ - nlohmann::json json = x; - return QJsonDocument::fromJson(json.dump().data()); -} - -template -QVariantMap toQVariantMap(const T &x) noexcept -{ - QJsonDocument doc = toQJsonDocument(x); - Q_ASSERT(doc.isObject()); - return doc.object().toVariantMap(); -} - template error::Result LoadJSON(const Source &content) noexcept { @@ -58,23 +35,6 @@ error::Result LoadJSON(const Source &content) noexcept } } -template -error::Result LoadJSONFile(GFile *file) noexcept -{ - g_autofree char *path = g_file_get_path(file); - LINGLONG_TRACE(fmt::format("load json from {}", path)); - - g_autoptr(GError) gErr = nullptr; - g_autofree gchar *content = nullptr; - gsize length; - - if (!g_file_load_contents(file, nullptr, &content, &length, nullptr, &gErr)) { - return LINGLONG_ERR("g_file_load_contents", gErr); - } - - return LoadJSON(content); -} - template error::Result LoadJSONFile(const std::filesystem::path &filePath) noexcept { @@ -87,62 +47,4 @@ error::Result LoadJSONFile(const std::filesystem::path &filePath) noexcept return LoadJSON(file); } -template -error::Result LoadJSONFile(QFile &file) noexcept -{ - LINGLONG_TRACE("load json from file" + QFileInfo(file).absoluteFilePath().toStdString()); - - if (!file.open(QFile::ReadOnly)) { - return LINGLONG_ERR("open", file); - } - - Q_ASSERT(file.error() == QFile::NoError); - - auto content = file.readAll(); - if (file.error() != QFile::NoError) { - return LINGLONG_ERR("read all", file); - } - - return LoadJSON(content.data()); -} - -template -error::Result LoadJSONFile(const QString &filename) noexcept -{ - std::filesystem::path file{ filename.toStdString() }; - return LoadJSONFile(file); -} - -template -error::Result fromQJsonDocument(const QJsonDocument &doc) noexcept -{ - return LoadJSON(doc.toJson(QJsonDocument::Compact).toStdString()); -} - -template -error::Result fromQJsonObject(const QJsonObject &obj) noexcept -{ - return fromQJsonDocument(QJsonDocument(obj)); -} - -template -error::Result fromQJsonValue(const QJsonValue &v) noexcept -{ - if (v.isArray()) { - return fromQJsonDocument(QJsonDocument(v.toArray())); - } - if (v.isObject()) { - return fromQJsonObject(v.toObject()); - } - - Q_ASSERT("QJsonValue should be object or array."); - abort(); -} - -template -error::Result fromQVariantMap(const QVariantMap &vmap) -{ - return fromQJsonObject(QJsonObjectfromVariantMap(vmap)); -} - } // namespace linglong::utils::serialize