Skip to content

Commit

Permalink
🤓 updater: added pre-releases versions when using a pre-release client (
Browse files Browse the repository at this point in the history
#93)

Pre-release updater
  • Loading branch information
Sclafus authored Mar 30, 2024
2 parents f5f6b32 + 08d668c commit 7bebb23
Show file tree
Hide file tree
Showing 7 changed files with 395 additions and 8 deletions.
44 changes: 37 additions & 7 deletions src/updater/updater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ Updater::Updater(QObject *parent)
void Updater::checkVersion()
{
qDebug() << "[Updater] starting version check";
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
auto *manager = new QNetworkAccessManager(this);
auto url = getUrl();
connect(manager, &QNetworkAccessManager::finished, this, &Updater::onReplyFinished);

QUrl url("https://api.github.com/repos/MirayaProject/miraya/releases/latest");
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::UserAgentHeader, "Miraya");
manager->get(request);
Expand All @@ -27,15 +27,45 @@ void Updater::onReplyFinished(QNetworkReply *reply)

QByteArray responseData = reply->readAll();
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
QJsonObject jsonObj = jsonDoc.object();

QString latestVersionStr = jsonObj.value("tag_name").toString();
QVersionNumber latestVersion = QVersionNumber::fromString(latestVersionStr);
QVersionNumber currentVersion = QVersionNumber::fromString(QCoreApplication::applicationVersion());
auto latestVersion = getLatestVersion(jsonDoc);
auto currentVersion = Version::fromString(QCoreApplication::applicationVersion());
qDebug() << "[Updater] current version: " << currentVersion.toString();
qDebug() << "[Updater] latest version: " << latestVersion.toString();

if(currentVersion >= latestVersion){

if (currentVersion >= latestVersion){
qDebug() << "[Updater] already running on latest or pre-release version";
return;
}
emit newVersionAvailable();
}


QUrl Updater::getUrl()
{
auto url = QUrl(UpdaterUrls::latestStable);

auto const version = Version::fromString(QCoreApplication::applicationVersion());

if (version.isPrerelease()) {
url = QUrl(UpdaterUrls::allReleases);
}
qDebug() << "[Updater] url: " << url.toString();
return url;
}

Version Updater::getLatestVersion(const QJsonDocument& json)
{
QString version;
if (json.isArray()) {
auto array = json.array();
auto first = array.at(0).toObject();
version = first.value("tag_name").toString();
}
else {
version = json.object().value("tag_name").toString();
}
qDebug() << "[Updater] latest version: " << version;
return Version::fromString(version);
}
8 changes: 7 additions & 1 deletion src/updater/updater.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include <QObject>
#include <QVersionNumber>

#include "updaterurls.h"
#include "version.h"

class Updater : public QObject
{
Q_OBJECT
Expand All @@ -21,8 +24,11 @@ class Updater : public QObject
signals:
void newVersionAvailable();

private slots:
private:
void onReplyFinished(QNetworkReply *reply);
// static bool isPreRelease(const QString& version);
static QUrl getUrl();
static Version getLatestVersion(const QJsonDocument& json);
};

#endif // UPDATER_H
13 changes: 13 additions & 0 deletions src/updater/updaterurls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef MIRAYA_UPDATERURLS_H
#define MIRAYA_UPDATERURLS_H

#include <QObject>

class UpdaterUrls{
public:
constexpr static const char* latestStable = "https://api.github.com/repos/MirayaProject/miraya/releases/latest";
constexpr static const char* allReleases = "https://api.github.com/repos/MirayaProject/miraya/releases";
};


#endif //MIRAYA_UPDATERURLS_H
66 changes: 66 additions & 0 deletions src/updater/version.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "version.h"

Version::Version(const QVersionNumber &version, const QString &suffix) {
this->version = version;
this->suffix = suffix;
}

Version Version::fromString(const QString &versionString) {
qsizetype suffixIndex;
auto v = QVersionNumber::fromString(versionString, &suffixIndex);
auto suffix = versionString.mid(suffixIndex);
qDebug() << "[Version] parsed version" << v << "with suffix" << suffix;
return {v, suffix};
}

bool Version::isPrerelease() const {
return suffix != "";
}

QString Version::toString() const {
return version.toString() + suffix;
}


bool Version::operator>(const Version &other) const {
// local version is newer than remote
if (this->version > other.version) {
return true;
}
// version is equal and no suffix
if (this->version == other.version && this->suffix.isEmpty() && other.suffix.isEmpty()) {
return false;
}

if (this->version == other.version && this->suffix.isEmpty() && !other.suffix.isEmpty()) {
return true;
}

// local version is equal to remote
if (this->version == other.version && !this->suffix.isEmpty() && !other.suffix.isEmpty()) {
// let's check the suffix
auto preReleaseType = this->suffix.split(".")[0];
auto otherPreReleaseType = other.suffix.split(".")[0];
if (preReleaseType > otherPreReleaseType) {
return true;
} else if (preReleaseType < otherPreReleaseType) {
return false;
}
// both are alpha/beta/rc versions, let's check the number at the end
auto preReleaseNumber = this->suffix.split(".")[1];
auto otherPreReleaseNumber = other.suffix.split(".")[1];
if (preReleaseNumber > otherPreReleaseNumber) {
return true;
}
return false;
}
return false;
}

bool Version::operator==(const Version &other) const {
return this->version == other.version && this->suffix == other.suffix;
}

bool Version::operator>=(const Version &other) const {
return *this > other || *this == other;
}
23 changes: 23 additions & 0 deletions src/updater/version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef MIRAYA_VERSION_H
#define MIRAYA_VERSION_H

#include <QVersionNumber>
#include <QDebug>

class Version {
public:
Version(const QVersionNumber& version, const QString& suffix);
static Version fromString(const QString& versionString);

[[nodiscard]] bool isPrerelease() const;
[[nodiscard]] QString toString() const;

bool operator>(const Version& other) const;
bool operator==(const Version& other) const;
bool operator>=(const Version& other) const;

QVersionNumber version;
QString suffix;
};

#endif //MIRAYA_VERSION_H
30 changes: 30 additions & 0 deletions tests/updater/version/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 3.16)
project(tests_updater_version VERSION 1.0.0 LANGUAGES CXX)

find_package(Qt6 REQUIRED COMPONENTS Test Core)

set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_AUTOUIC_SEARCH_PATHS})
set(CMAKE_AUTORCC ON)

enable_testing(true)

# ===========================Including Project Files===========================
file(GLOB_RECURSE SOURCES
../../../src/updater/version.cpp
../../../src/updater/version.h
test_updater_version.cpp
)
add_definitions(-DQT_NO_DEBUG_OUTPUT)

qt_add_executable(${PROJECT_NAME} ${SOURCES})
add_test(NAME ${PROJECT_NAME} COMMAND "${CMAKE_SOURCE_DIR}/bin/${PROJECT_NAME}")

target_link_libraries(${PROJECT_NAME} PRIVATE
Qt6::Core
Qt6::Test
)
Loading

0 comments on commit 7bebb23

Please sign in to comment.