Commit a869a8b1 authored by Harald Sitter's avatar Harald Sitter 🚔

drop internal os-release class in favor of KOSRelease of kcoreaddons 5.58

Summary:
KOSRelease was based on our class so it is fully API compatible and doesn't
require any changes besides different include and name

Test Plan: builds + modules still loads os release data

Reviewers: davidedmundson

Reviewed By: davidedmundson

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D21209
parent cc80afa3
......@@ -4,8 +4,4 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kcm-about-distro\")
add_subdirectory(src)
if(BUILD_TESTING)
add_subdirectory(autotests)
endif()
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
remove_definitions(-DQT_NO_CAST_FROM_ASCII)
include(ECMAddTests)
find_package(Qt5Test ${REQUIRED_QT_VERSION} CONFIG REQUIRED)
# Include src to get access to the OSRelease.h
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src)
add_library(about-distro-test STATIC ../src/OSRelease.cpp)
target_link_libraries(about-distro-test
PUBLIC
KF5::CoreAddons
)
ecm_add_tests(
OSReleaseTest.cpp
LINK_LIBRARIES
Qt5::Test
about-distro-test
)
ecm_mark_nongui_executable(OSReleaseTest)
/*
Copyright (C) 2019 Harald Sitter <sitter@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QTest>
#include "OSRelease.h"
class OSReleaseTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase() {}
void testParse()
{
auto r = OSRelease(QFINDTESTDATA("data/os-release"));
QCOMPARE(r.name(), "Name");
QCOMPARE(r.version(), "100.5");
QCOMPARE(r.id(), "theid");
QCOMPARE(r.idLike(), QStringList({"otherid", "otherotherid"}));
QCOMPARE(r.versionCodename(), "versioncodename");
QCOMPARE(r.versionId(), "500.1");
QCOMPARE(r.prettyName(), "Pretty Name");
QCOMPARE(r.ansiColor(), "1;34");
QCOMPARE(r.cpeName(), "cpe:/o:foo:bar:100");
QCOMPARE(r.homeUrl(), "https://url.home");
QCOMPARE(r.documentationUrl(), "https://url.docs");
QCOMPARE(r.supportUrl(), "https://url.support");
QCOMPARE(r.bugReportUrl(), "https://url.bugs");
QCOMPARE(r.privacyPolicyUrl(), "https://url.privacy");
QCOMPARE(r.buildId(), "105.5");
QCOMPARE(r.variant(), "Test Edition");
QCOMPARE(r.variantId(), "test");
QCOMPARE(r.logo(), "start-here-test");
QCOMPARE(r.extraKeys(), QStringList({"DEBIAN_BTS"}));
QCOMPARE(r.extraValue("DEBIAN_BTS"), "debbugs://bugs.debian.org/");
}
};
QTEST_MAIN(OSReleaseTest)
#include "OSReleaseTest.moc"
NAME="Name"
VERSION="100.5"
ID=theid
ID_LIKE="otherid otherotherid"
VERSION_CODENAME=versioncodename
VERSION_ID="500.1"
PRETTY_NAME="Pretty Name"
ANSI_COLOR="1;34"
CPE_NAME="cpe:/o:foo:bar:100"
HOME_URL="https://url.home"
DOCUMENTATION_URL="https://url.docs"
SUPPORT_URL="https://url.support"
BUG_REPORT_URL="https://url.bugs"
PRIVACY_POLICY_URL="https://url.privacy"
BUILD_ID="105.5"
# comment
VARIANT="Test Edition"
VARIANT_ID=test
# indented comment
LOGO=start-here-test
DEBIAN_BTS="debbugs://bugs.debian.org/"
......@@ -4,7 +4,6 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(kcm_SRCS
main.cpp
Module.cpp
OSRelease.cpp
)
ki18n_wrap_ui(kcm_SRCS Module.ui)
......
......@@ -33,6 +33,7 @@
#include <KDesktopFile>
#include <KFormat>
#include <KLocalizedString>
#include <KOSRelease>
#include <KSharedConfig>
#include <solid/device.h>
......@@ -46,7 +47,6 @@
#endif
#include <sys/utsname.h>
#include "OSRelease.h"
#include "Version.h"
static qlonglong calculateTotalRam()
......@@ -148,7 +148,7 @@ void Module::loadSoftware()
KConfig::NoGlobals);
KConfigGroup cg = KConfigGroup(config, "General");
OSRelease os;
KOSRelease os;
QString logoPath = cg.readEntry("LogoPath", os.logo());
if (logoPath.isEmpty()) {
......
/*
Copyright (C) 2014-2019 Harald Sitter <sitter@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "OSRelease.h"
#include <QDebug>
#include <QFile>
#include <KShell>
// Sets a QString var
static void setVar(QString *var, const QString &value)
{
// Values may contain quotation marks, strip them as we have no use for them.
KShell::Errors error;
QStringList args = KShell::splitArgs(value, KShell::NoOptions, &error);
if (error != KShell::NoError) { // Failed to parse.
return;
}
*var = args.join(QLatin1Char(' '));
}
// Sets a QStringList var (i.e. splits a string value)
static void setVar(QStringList *var, const QString &value)
{
// Instead of passing the verbatim value we manually strip any initial quotes
// and then run it through KShell. At this point KShell will actually split
// by spaces giving us the final QStringList.
// NOTE: Splitting like this does not actually allow escaped substrings to
// be handled correctly, so "kitteh \"french fries\"" would result in
// three list entries. I'd argue that if someone makes an id like that
// they are at fault for the bogus parsing here though as id explicitly
// is required to not contain spaces even if more advanced shell escaping
// is also allowed...
QString value_ = value;
if (value_.at(0) == QLatin1Char('"') && value_.at(value_.size()-1) == QLatin1Char('"')) {
value_.remove(0, 1);
value_.remove(-1, 1);
}
KShell::Errors error;
QStringList args = KShell::splitArgs(value_, KShell::NoOptions, &error);
if (error != KShell::NoError) { // Failed to parse.
return;
}
*var = args;
}
class Q_DECL_HIDDEN OSRelease::Private
{
public:
Private(const QString &filePath)
: name(QStringLiteral("Linux"))
, id(QStringLiteral("linux"))
, prettyName(QStringLiteral("Linux"))
{
// Default values for non-optional fields set above ^.
if (filePath.isEmpty()) {
return;
}
QHash<QString, QString *> stringHash = {
{ QStringLiteral("NAME"), &name },
{ QStringLiteral("VERSION"), &version },
{ QStringLiteral("ID"), &id },
// idLike is not a QString, special handling below!
{ QStringLiteral("VERSION_CODENAME"), &versionCodename },
{ QStringLiteral("VERSION_ID"), &versionId },
{ QStringLiteral("PRETTY_NAME"), &prettyName },
{ QStringLiteral("ANSI_COLOR"), &ansiColor },
{ QStringLiteral("CPE_NAME"), &cpeName },
{ QStringLiteral("HOME_URL"), &homeUrl },
{ QStringLiteral("DOCUMENTATION_URL"), &documentationUrl },
{ QStringLiteral("SUPPORT_URL"), &supportUrl },
{ QStringLiteral("BUG_REPORT_URL"), &bugReportUrl },
{ QStringLiteral("PRIVACY_POLICY_URL"), &privacyPolicyUrl },
{ QStringLiteral("BUILD_ID"), &buildId },
{ QStringLiteral("VARIANT"), &variant },
{ QStringLiteral("VARIANT_ID"), &variantId },
{ QStringLiteral("LOGO"), &logo }
};
QFile file(filePath);
// NOTE: The os-release specification defines default values for specific
// fields which means that even if we can not read the os-release file
// we have sort of expected default values to use.
// TODO: it might still be handy to indicate to the outside whether
// fallback values are being used or not.
file.open(QIODevice::ReadOnly | QIODevice::Text);
QString line;
QStringList parts;
while (!file.atEnd()) {
// Trimmed to handle indented comment lines properly
line = QString::fromLatin1(file.readLine()).trimmed();
if (line.startsWith(QLatin1Char('#'))) {
// Comment line
continue;
}
parts = line.split(QLatin1Char('='));
if (parts.size() != 2 || line.contains(QChar('#'))) {
// Invalid line...
// For the purposes of simple parsing we'll not support >2 =
// or >1 # characters.
// The former makes splitting and the latter makes comment
// stripping difficult.
continue;
}
QString key = parts.at(0);
QString value = parts.at(1).trimmed();
if (QString *var = stringHash.value(key, nullptr)) {
setVar(var, value);
continue;
}
// ID_LIKE is a list and parsed as such (rather than a QString).
if (key == QLatin1String("ID_LIKE")) {
setVar(&idLike, value);
continue;
}
// os-release explicitly allows for vendor specific additions, we'll
// collect them as strings and exposes them as "extras".
QString parsedValue;
setVar(&parsedValue, value);
extras.insert(key, parsedValue);
}
}
QString name;
QString version;
QString id;
QStringList idLike;
QString versionCodename;
QString versionId;
QString prettyName;
QString ansiColor;
QString cpeName;
QString homeUrl;
QString documentationUrl;
QString supportUrl;
QString bugReportUrl;
QString privacyPolicyUrl;
QString buildId;
QString variant;
QString variantId;
QString logo;
QHash<QString, QString> extras;
};
OSRelease::OSRelease(const QString &filePath)
: d(new Private(filePath))
{
}
OSRelease::~OSRelease()
{
delete d;
}
QString OSRelease::name() const
{
return d->name;
}
QString OSRelease::version() const
{
return d->version;
}
QString OSRelease::id() const
{
return d->id;
}
QStringList OSRelease::idLike() const
{
return d->idLike;
}
QString OSRelease::versionCodename() const
{
return d->versionCodename;
}
QString OSRelease::versionId() const
{
return d->versionId;
}
QString OSRelease::prettyName() const
{
return d->prettyName;
}
QString OSRelease::ansiColor() const
{
return d->ansiColor;
}
QString OSRelease::cpeName() const
{
return d->cpeName;
}
QString OSRelease::homeUrl() const
{
return d->homeUrl;
}
QString OSRelease::documentationUrl() const
{
return d->documentationUrl;
}
QString OSRelease::supportUrl() const
{
return d->supportUrl;
}
QString OSRelease::bugReportUrl() const
{
return d->bugReportUrl;
}
QString OSRelease::privacyPolicyUrl() const
{
return d->privacyPolicyUrl;
}
QString OSRelease::buildId() const
{
return d->buildId;
}
QString OSRelease::variant() const
{
return d->variant;
}
QString OSRelease::variantId() const
{
return d->variantId;
}
QString OSRelease::logo() const
{
return d->logo;
}
QStringList OSRelease::extraKeys() const
{
return d->extras.keys();
}
QString OSRelease::extraValue(const QString &key) const
{
return d->extras.value(key);
}
QString OSRelease::defaultFilePath()
{
if (QFile::exists(QStringLiteral("/etc/os-release"))) {
return QStringLiteral("/etc/os-release");
} else if (QFile::exists(QStringLiteral("/usr/lib/os-release"))) {
return QStringLiteral("/usr/lib/os-release");
} else {
return QString();
}
}
/*
Copyright (C) 2014-2019 Harald Sitter <sitter@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OSRELEASE_H
#define OSRELEASE_H
#include <QString>
#include <QStringList>
/**
* @brief The OSRelease class parses /etc/os-release files
*
* https://www.freedesktop.org/software/systemd/man/os-release.html
*
* os-release is a free software standard for describing an operating system.
* This class parses and models os-release files.
*/
class OSRelease
{
public:
/**
* Constructs a new OSRelease instance. Parsing happens in the constructor
* and the data is not cached across instances.
*
* @note For parsing simplicity neither trailing comments nor multiple '='
* characters are allowed.
*
* @param filePath The path to the os-release file. By default the first
* available file of the paths specified in the os-release manpage is
* parsed.
*/
explicit OSRelease(const QString &filePath = defaultFilePath());
~OSRelease();
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#NAME= */
QString name() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#VERSION= */
QString version() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#ID= */
QString id() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#ID_LIKE= */
QStringList idLike() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#VERSION_CODENAME= */
QString versionCodename() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#VERSION_ID= */
QString versionId() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#PRETTY_NAME= */
QString prettyName() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#ANSI_COLOR= */
QString ansiColor() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#CPE_NAME= */
QString cpeName() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#HOME_URL= */
QString homeUrl() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#HOME_URL= */
QString documentationUrl() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#HOME_URL= */
QString supportUrl() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#HOME_URL= */
QString bugReportUrl() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#HOME_URL= */
QString privacyPolicyUrl() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#BUILD_ID= */
QString buildId() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#VARIANT= */
QString variant() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#VARIANT_ID= */
QString variantId() const;
/** @see https://www.freedesktop.org/software/systemd/man/os-release.html#LOGO= */
QString logo() const;
/**
* Extra keys are keys that are unknown or specified by a vendor.
*/
QStringList extraKeys() const;
/** Extra values are values assoicated with keys that are unknown. */
QString extraValue(const QString &key) const;
private:
static QString defaultFilePath();
class Private;
Private *const d = nullptr;
};
#endif // OSRELEASE_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment