From 5402acb3c6cf9b63c9df69ee463cae02259dfdef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 28 Dec 2015 04:45:49 +0100 Subject: [PATCH] GH-1360 add basic changelog based on github API, fix update dialog buttons --- application/BuildConfig.cpp.in | 47 ++++---- application/BuildConfig.h | 7 +- application/CMakeLists.txt | 51 +-------- application/MainWindow.cpp | 41 +++++-- application/MultiMC.cpp | 10 +- application/dialogs/UpdateDialog.cpp | 106 +++++++++++++++++- application/dialogs/UpdateDialog.h | 7 ++ application/dialogs/UpdateDialog.ui | 8 +- application/pages/global/MultiMCPage.cpp | 20 ++-- cmake/GetGitRevisionDescription.cmake | 130 +++++++++++++++++++++++ cmake/GetGitRevisionDescription.cmake.in | 41 +++++++ logic/Json.h | 8 +- tests/tst_DownloadTask.cpp | 22 ---- 13 files changed, 377 insertions(+), 121 deletions(-) create mode 100644 cmake/GetGitRevisionDescription.cmake create mode 100644 cmake/GetGitRevisionDescription.cmake.in diff --git a/application/BuildConfig.cpp.in b/application/BuildConfig.cpp.in index 36337aa4..be1797cb 100644 --- a/application/BuildConfig.cpp.in +++ b/application/BuildConfig.cpp.in @@ -6,18 +6,29 @@ Config BuildConfig; Config::Config() { // Version information - VERSION_MAJOR = @MultiMC_VERSION_MAJOR@; + VERSION_MAJOR = @MultiMC_VERSION_MAJOR@; VERSION_MINOR = @MultiMC_VERSION_MINOR@; VERSION_HOTFIX = @MultiMC_VERSION_HOTFIX@; VERSION_BUILD = @MultiMC_VERSION_BUILD@; - VERSION_CHANNEL = "@MultiMC_VERSION_CHANNEL@"; BUILD_PLATFORM = "@MultiMC_BUILD_PLATFORM@"; CHANLIST_URL = "@MultiMC_CHANLIST_URL@"; NOTIFICATION_URL = "@MultiMC_NOTIFICATION_URL@"; FULL_VERSION_STR = "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_BUILD@"; GIT_COMMIT = "@MultiMC_GIT_COMMIT@"; + GIT_REFSPEC = "@MultiMC_GIT_REFSPEC@"; + if(GIT_REFSPEC.startsWith("refs/heads/") && !CHANLIST_URL.isEmpty() && VERSION_BUILD >= 0) + { + VERSION_CHANNEL = GIT_REFSPEC; + VERSION_CHANNEL.remove("refs/heads/"); + UPDATER_ENABLED = true; + } + else + { + VERSION_CHANNEL = QObject::tr("custom"); + } + VERSION_STR = "@MultiMC_VERSION_STRING@"; NEWS_RSS_URL = "@MultiMC_NEWS_RSS_URL@"; PASTE_EE_KEY = "@MultiMC_PASTE_EE_API_KEY@"; @@ -25,30 +36,24 @@ Config::Config() QString Config::printableVersionString() const { - QString vstr = QString("%1.%2").arg(QString::number(VERSION_MAJOR), QString::number(VERSION_MINOR)); + QString vstr = QString("%1.%2").arg(QString::number(VERSION_MAJOR), QString::number(VERSION_MINOR)); - if (VERSION_HOTFIX > 0) vstr += "." + QString::number(VERSION_HOTFIX); + // if this is a hotfix release, append that + if (VERSION_HOTFIX > 0) + { + vstr += "." + QString::number(VERSION_HOTFIX); + } - // If the build is a development build or release candidate, add that info to the end. - if(VERSION_CHANNEL == "stable") + // If the build is not a main release, append the channel + if(VERSION_CHANNEL != "stable") { - return vstr; + vstr += "-" + VERSION_CHANNEL; } - else if(VERSION_CHANNEL == "develop") + + // if a build number is set, also add it to the end + if(VERSION_BUILD >= 0) { - vstr += "-dev-" + QString::number(VERSION_BUILD); - } - else if(VERSION_CHANNEL == "unstable") - { - vstr += "-nuke-" + QString::number(VERSION_BUILD); - } - else if(VERSION_CHANNEL == "custom") - { - vstr += "-local"; - } - else - { - vstr += "-" + VERSION_CHANNEL + "-" + QString::number(VERSION_BUILD); + vstr += "-" + QString::number(VERSION_BUILD); } return vstr; } diff --git a/application/BuildConfig.h b/application/BuildConfig.h index a81d16ed..edba18e3 100644 --- a/application/BuildConfig.h +++ b/application/BuildConfig.h @@ -23,6 +23,8 @@ public: */ QString VERSION_CHANNEL; + bool UPDATER_ENABLED = false; + /// A short string identifying this build's platform. For example, "lin64" or "win32". QString BUILD_PLATFORM; @@ -35,9 +37,12 @@ public: /// Used for matching notifications QString FULL_VERSION_STR; - /// The commit hash of this build + /// The git commit hash of this build QString GIT_COMMIT; + /// The git refspec of this build + QString GIT_REFSPEC; + /// This is printed on start to standard output QString VERSION_STR; diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt index d9c37a45..65bee8c9 100644 --- a/application/CMakeLists.txt +++ b/application/CMakeLists.txt @@ -11,72 +11,31 @@ set(MultiMC_VERSION_HOTFIX 8) # Build number set(MultiMC_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.") -# Version type -set(MultiMC_VERSION_TYPE "Custom" CACHE STRING "MultiMC's version type. This should be one of 'Custom', 'Release', 'ReleaseCandidate', or 'Development', depending on what type of version this is.") - # Build platform. set(MultiMC_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used by the notification system and to display in the about dialog.") -# Version channel -set(MultiMC_VERSION_CHANNEL "" CACHE STRING "The current build's channel. Included in the version string.") - # Channel list URL set(MultiMC_CHANLIST_URL "" CACHE STRING "URL for the channel list.") -# Updater enabled? -set(MultiMC_UPDATER false CACHE BOOL "Whether or not the update system is enabled. If this is enabled, you must also set MultiMC_CHANLIST_URL and MultiMC_VERSION_CHANNEL in order for it to work properly.") - # Notification URL set(MultiMC_NOTIFICATION_URL "" CACHE STRING "URL for checking for notifications.") # paste.ee API key set(MultiMC_PASTE_EE_API_KEY "" CACHE STRING "API key you can get from paste.ee when you register an account") -#### Check the current Git commit -include(GitFunctions) -git_run(COMMAND rev-parse HEAD DEFAULT "Unknown" OUTPUT_VAR MultiMC_GIT_COMMIT) +#### Check the current Git commit and branch +include(GetGitRevisionDescription) +get_git_head_revision(MultiMC_GIT_REFSPEC MultiMC_GIT_COMMIT) message(STATUS "Git commit: ${MultiMC_GIT_COMMIT}") +message(STATUS "Git refspec: ${MultiMC_GIT_REFSPEC}") set(MultiMC_RELEASE_VERSION_NAME "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}") if(MultiMC_VERSION_HOTFIX GREATER 0) set(MultiMC_RELEASE_VERSION_NAME "${MultiMC_RELEASE_VERSION_NAME}.${MultiMC_VERSION_HOTFIX}") endif() -# Build a version string to display in the configure logs. -if(MultiMC_VERSION_TYPE STREQUAL "Custom") - message(STATUS "Version Type: Custom") - set(MultiMC_VERSION_STRING "${MultiMC_RELEASE_VERSION_NAME}") -elseif(MultiMC_VERSION_TYPE STREQUAL "Release") - message(STATUS "Version Type: Stable Release") - set(MultiMC_VERSION_STRING "${MultiMC_RELEASE_VERSION_NAME}") -elseif(MultiMC_VERSION_TYPE STREQUAL "Development") - message(STATUS "Version Type: Development") - set(MultiMC_VERSION_STRING "${MultiMC_RELEASE_VERSION_NAME}-dev${MultiMC_VERSION_BUILD}") -else() - message(ERROR "Invalid build type.") -endif() - -message(STATUS "MultiMC 5 Version: ${MultiMC_VERSION_STRING}") - #### Custom target to just print the version. -add_custom_target(version echo "Version: ${MultiMC_VERSION_STRING}") - -# If the update system is enabled, make sure MultiMC_CHANLIST_URL and MultiMC_VERSION_CHANNEL are set. -if(MultiMC_UPDATER) - if(MultiMC_VERSION_CHANNEL STREQUAL "") - message(FATAL_ERROR "Update system is enabled, but MultiMC_VERSION_CHANNEL is not set.\n" - "Please ensure the CMake variables MultiMC_VERSION_CHANNEL, MultiMC_CHANLIST_URL, and MultiMC_VERSION_BUILD are set.") - endif() - if(MultiMC_CHANLIST_URL STREQUAL "") - message(FATAL_ERROR "Update system is enabled, but MultiMC_CHANLIST_URL is not set.\n" - "Please ensure the CMake variables MultiMC_VERSION_CHANNEL, MultiMC_CHANLIST_URL, and MultiMC_VERSION_BUILD are set.") - endif() - if(MultiMC_VERSION_BUILD LESS 0) - message(FATAL_ERROR "Update system is enabled, but MultiMC_VERSION_BUILD is not set.\n" - "Please ensure the CMake variables MultiMC_VERSION_CHANNEL, MultiMC_CHANLIST_URL, and MultiMC_VERSION_BUILD are set.") - endif() - message(STATUS "Updater is enabled. Channel list URL: ${MultiMC_CHANLIST_URL}") -endif() +add_custom_target(version echo "Version: ${MultiMC_RELEASE_VERSION_NAME}") ######## Configure header ######## configure_file("${PROJECT_SOURCE_DIR}/BuildConfig.cpp.in" "${PROJECT_BINARY_DIR}/BuildConfig.cpp") diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp index d2bddd00..2fab40cb 100644 --- a/application/MainWindow.cpp +++ b/application/MainWindow.cpp @@ -149,9 +149,12 @@ public: actionViewCentralModsFolder = new QAction(MainWindow); actionViewCentralModsFolder->setObjectName(QStringLiteral("actionViewCentralModsFolder")); actionViewCentralModsFolder->setIcon(MMC->getThemedIcon("centralmods")); - actionCheckUpdate = new QAction(MainWindow); - actionCheckUpdate->setObjectName(QStringLiteral("actionCheckUpdate")); - actionCheckUpdate->setIcon(MMC->getThemedIcon("checkupdate")); + if(BuildConfig.UPDATER_ENABLED) + { + actionCheckUpdate = new QAction(MainWindow); + actionCheckUpdate->setObjectName(QStringLiteral("actionCheckUpdate")); + actionCheckUpdate->setIcon(MMC->getThemedIcon("checkupdate")); + } actionSettings = new QAction(MainWindow); actionSettings->setObjectName(QStringLiteral("actionSettings")); actionSettings->setIcon(MMC->getThemedIcon("settings")); @@ -253,7 +256,10 @@ public: mainToolBar->addAction(actionViewCentralModsFolder); mainToolBar->addAction(actionRefresh); mainToolBar->addSeparator(); - mainToolBar->addAction(actionCheckUpdate); + if(BuildConfig.UPDATER_ENABLED) + { + mainToolBar->addAction(actionCheckUpdate); + } mainToolBar->addAction(actionSettings); mainToolBar->addSeparator(); mainToolBar->addAction(actionReportBug); @@ -299,9 +305,12 @@ public: actionViewCentralModsFolder->setText(QApplication::translate("MainWindow", "View Central Mods Folder", 0)); actionViewCentralModsFolder->setToolTip(QApplication::translate("MainWindow", "Open the central mods folder in a file browser.", 0)); actionViewCentralModsFolder->setStatusTip(QApplication::translate("MainWindow", "Open the central mods folder in a file browser.", 0)); - actionCheckUpdate->setText(QApplication::translate("MainWindow", "Check for Updates", 0)); - actionCheckUpdate->setToolTip(QApplication::translate("MainWindow", "Check for new updates for MultiMC", 0)); - actionCheckUpdate->setStatusTip(QApplication::translate("MainWindow", "Check for new updates for MultiMC", 0)); + if(BuildConfig.UPDATER_ENABLED) + { + actionCheckUpdate->setText(QApplication::translate("MainWindow", "Check for Updates", 0)); + actionCheckUpdate->setToolTip(QApplication::translate("MainWindow", "Check for new updates for MultiMC", 0)); + actionCheckUpdate->setStatusTip(QApplication::translate("MainWindow", "Check for new updates for MultiMC", 0)); + } actionSettings->setText(QApplication::translate("MainWindow", "Settings", 0)); actionSettings->setToolTip(QApplication::translate("MainWindow", "Change settings.", 0)); actionSettings->setStatusTip(QApplication::translate("MainWindow", "Change settings.", 0)); @@ -551,7 +560,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow m_newsChecker->reloadNews(); updateNewsLabel(); + } + if(BuildConfig.UPDATER_ENABLED) + { // set up the updater object. auto updater = MMC->updateChecker(); connect(updater.get(), &UpdateChecker::updateAvailable, this, &MainWindow::updateAvailable); @@ -559,9 +571,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow // if automatic update checks are allowed, start one. if (MMC->settings()->get("AutoUpdate").toBool()) { - auto updater = MMC->updateChecker(); updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), false); } + } + + { auto checker = new NotificationChecker(); checker->setNotificationsUrl(QUrl(BuildConfig.NOTIFICATION_URL)); checker->setApplicationChannel(BuildConfig.VERSION_CHANNEL); @@ -1322,8 +1336,15 @@ void MainWindow::on_actionConfig_Folder_triggered() void MainWindow::on_actionCheckUpdate_triggered() { - auto updater = MMC->updateChecker(); - updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), true); + if(BuildConfig.UPDATER_ENABLED) + { + auto updater = MMC->updateChecker(); + updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), true); + } + else + { + qWarning() << "Updater not set up. Cannot check for updates."; + } } void MainWindow::on_actionSettings_triggered() diff --git a/application/MultiMC.cpp b/application/MultiMC.cpp index 1c1fe835..cd5e145a 100644 --- a/application/MultiMC.cpp +++ b/application/MultiMC.cpp @@ -116,7 +116,7 @@ MultiMC::MultiMC(int &argc, char **argv, bool test_mode) : QApplication(argc, ar // display version and exit if (args["version"].toBool()) { - std::cout << "Version " << BuildConfig.VERSION_STR.toStdString() << std::endl; + std::cout << "Version " << BuildConfig.printableVersionString().toStdString() << std::endl; std::cout << "Git " << BuildConfig.GIT_COMMIT.toStdString() << std::endl; m_status = MultiMC::Succeeded; return; @@ -175,8 +175,9 @@ MultiMC::MultiMC(int &argc, char **argv, bool test_mode) : QApplication(argc, ar initLogger(); qDebug() << "MultiMC 5, (c) 2013-2015 MultiMC Contributors"; - qDebug() << "Version : " << BuildConfig.VERSION_STR; + qDebug() << "Version : " << BuildConfig.printableVersionString(); qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT; + qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC; if (adjustedBy.size()) { qDebug() << "Work dir before adjustment : " << origcwdPath; @@ -197,7 +198,10 @@ MultiMC::MultiMC(int &argc, char **argv, bool test_mode) : QApplication(argc, ar initTranslations(); // initialize the updater - m_updateChecker.reset(new UpdateChecker(BuildConfig.CHANLIST_URL, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD)); + if(BuildConfig.UPDATER_ENABLED) + { + m_updateChecker.reset(new UpdateChecker(BuildConfig.CHANLIST_URL, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD)); + } m_translationChecker.reset(new TranslationDownloader()); diff --git a/application/dialogs/UpdateDialog.cpp b/application/dialogs/UpdateDialog.cpp index 4661bcb5..ff9513d1 100644 --- a/application/dialogs/UpdateDialog.cpp +++ b/application/dialogs/UpdateDialog.cpp @@ -3,10 +3,13 @@ #include #include "MultiMC.h" #include +#include #include #include +#include "BuildConfig.h" + UpdateDialog::UpdateDialog(bool hasUpdate, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateDialog) { ui->setupUi(this); @@ -18,7 +21,8 @@ UpdateDialog::UpdateDialog(bool hasUpdate, QWidget *parent) : QDialog(parent), u else { ui->label->setText(tr("No %1 updates found. You are running the latest version.").arg(channel)); - ui->btnUpdateNow->setDisabled(true); + ui->btnUpdateNow->setHidden(true); + ui->btnUpdateLater->setText(tr("Close")); } loadChangelog(); } @@ -31,7 +35,17 @@ void UpdateDialog::loadChangelog() { auto channel = MMC->settings()->get("UpdateChannel").toString(); dljob.reset(new NetJob("Changelog")); - auto url = QString("https://raw.githubusercontent.com/MultiMC/MultiMC5/%1/changelog.md").arg(channel); + QString url; + if(channel == "stable") + { + url = QString("https://raw.githubusercontent.com/MultiMC/MultiMC5/%1/changelog.md").arg(channel); + m_changelogType = CHANGELOG_MARKDOWN; + } + else + { + url = QString("https://api.github.com/repos/MultiMC/MultiMC5/compare/%1...%2").arg(BuildConfig.GIT_COMMIT, channel); + m_changelogType = CHANGELOG_COMMITS; + } changelogDownload = ByteArrayDownload::make(QUrl(url)); dljob->addNetAction(changelogDownload); connect(dljob.get(), &NetJob::succeeded, this, &UpdateDialog::changelogLoaded); @@ -106,10 +120,94 @@ QString reprocessMarkdown(QByteArray markdown) return output; } +QString reprocessCommits(QByteArray json) +{ + auto channel = MMC->settings()->get("UpdateChannel").toString(); + try + { + QString result; + auto document = Json::requireDocument(json); + auto rootobject = Json::requireObject(document); + auto status = Json::requireString(rootobject, "status"); + auto diff_url = Json::requireString(rootobject, "html_url"); + + auto print_commits = [&]() + { + result += ""; + auto commitarray = Json::requireArray(rootobject, "commits"); + for(int i = commitarray.size() - 1; i >= 0; i--) + { + const auto & commitval = commitarray[i]; + auto commitobj = Json::requireObject(commitval); + auto commit_url = Json::requireString(commitobj, "html_url"); + auto commit_info = Json::requireObject(commitobj, "commit"); + auto commit_message = Json::requireString(commit_info, "message"); + auto lines = commit_message.split('\n'); + QRegularExpression regexp("(?(GH-(?[0-9]+))|(NOISSUE)|(SCRATCH))? *(?.*) *"); + auto match = regexp.match(lines.takeFirst(), 0, QRegularExpression::NormalMatch); + auto issuenr = match.captured("issuenr"); + auto prefix = match.captured("prefix"); + auto rest = match.captured("rest"); + result += ""; + lines.prepend(rest); + result += ""; + } + result += "
"; + if(issuenr.length()) + { + result += QString("GH-%2").arg(issuenr, issuenr); + } + else if(prefix.length()) + { + result += QString("%2").arg(commit_url, prefix); + } + else + { + result += QString("NOISSUE").arg(commit_url); + } + result += "

" + lines.join("
") + "

"; + }; + + if(status == "identical") + { + return QObject::tr("

There is are no code changes between your current version and %1 HEAD.

").arg(channel); + } + else if(status == "ahead") + { + result += QObject::tr("

Following commits were added since last update:

"); + print_commits(); + } + else if(status == "diverged") + { + auto commit_ahead = Json::requireInteger(rootobject, "ahead_by"); + auto commit_behind = Json::requireInteger(rootobject, "behind_by"); + result += QObject::tr("

The update removes %1 commits and adds the following %2:

").arg(commit_behind, commit_ahead); + print_commits(); + } + result += QObject::tr("

You can look at the changes on github.

").arg(diff_url); + return result; + } + catch (JSONValidationError & e) + { + qWarning() << "Got an unparseable commit log from github:" << e.what(); + qDebug() << json; + } + return QString(); +} + void UpdateDialog::changelogLoaded() { - auto html = reprocessMarkdown(changelogDownload->m_data); - ui->changelogBrowser->setHtml(html); + QString result; + switch(m_changelogType) + { + case CHANGELOG_COMMITS: + result = reprocessCommits(changelogDownload->m_data); + break; + case CHANGELOG_MARKDOWN: + result = reprocessMarkdown(changelogDownload->m_data); + break; + } + ui->changelogBrowser->setHtml(result); } void UpdateDialog::changelogFailed(QString reason) diff --git a/application/dialogs/UpdateDialog.h b/application/dialogs/UpdateDialog.h index 5237df5c..403b78ad 100644 --- a/application/dialogs/UpdateDialog.h +++ b/application/dialogs/UpdateDialog.h @@ -30,6 +30,12 @@ enum UpdateAction UPDATE_NOW = QDialog::Accepted, }; +enum ChangelogType +{ + CHANGELOG_MARKDOWN, + CHANGELOG_COMMITS +}; + class UpdateDialog : public QDialog { Q_OBJECT @@ -56,4 +62,5 @@ public slots: private: ByteArrayDownloadPtr changelogDownload; NetJobPtr dljob; + ChangelogType m_changelogType = CHANGELOG_MARKDOWN; }; diff --git a/application/dialogs/UpdateDialog.ui b/application/dialogs/UpdateDialog.ui index cbe1ef74..8e34a521 100644 --- a/application/dialogs/UpdateDialog.ui +++ b/application/dialogs/UpdateDialog.ui @@ -46,7 +46,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Oxygen-Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Noto Sans'; font-size:12pt; font-weight:400; font-style:normal;"> <p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:22pt;">Loading changelog...</span></p></body></html> @@ -55,8 +55,8 @@ p, li { white-space: pre-wrap; } - - + + @@ -69,7 +69,7 @@ p, li { white-space: pre-wrap; } - + diff --git a/application/pages/global/MultiMCPage.cpp b/application/pages/global/MultiMCPage.cpp index 18f30010..c1a24a56 100644 --- a/application/pages/global/MultiMCPage.cpp +++ b/application/pages/global/MultiMCPage.cpp @@ -27,6 +27,7 @@ #include "settings/SettingsObject.h" #include #include "MultiMC.h" +#include "BuildConfig.h" // FIXME: possibly move elsewhere enum InstSortMode @@ -55,16 +56,23 @@ MultiMCPage::MultiMCPage(QWidget *parent) : QWidget(parent), ui(new Ui::MultiMCP loadSettings(); - QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this, - &MultiMCPage::refreshUpdateChannelList); - - if (MMC->updateChecker()->hasChannels()) + if(BuildConfig.UPDATER_ENABLED) { - refreshUpdateChannelList(); + QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this, + &MultiMCPage::refreshUpdateChannelList); + + if (MMC->updateChecker()->hasChannels()) + { + refreshUpdateChannelList(); + } + else + { + MMC->updateChecker()->updateChanList(false); + } } else { - MMC->updateChecker()->updateChanList(false); + ui->updateSettingsBox->setHidden(true); } connect(ui->fontSizeBox, SIGNAL(valueChanged(int)), SLOT(refreshFontPreview())); connect(ui->consoleFont, SIGNAL(currentFontChanged(QFont)), SLOT(refreshFontPreview())); diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake new file mode 100644 index 00000000..85eae156 --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake @@ -0,0 +1,130 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ ...]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +function(get_git_head_revision _refspecvar _hashvar) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories + set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") + get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) + if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) + # We have reached the root directory, we are not in git + set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + endwhile() + # check if this is a submodule + if(NOT IS_DIRECTORY ${GIT_DIR}) + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${GIT_DIR}/HEAD") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" + @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) + set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + describe + ${hash} + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/GetGitRevisionDescription.cmake.in new file mode 100644 index 00000000..6d8b708e --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake.in @@ -0,0 +1,41 @@ +# +# Internal file for GetGitRevisionDescription.cmake +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(HEAD_HASH) + +file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) + +string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) +if(HEAD_CONTENTS MATCHES "ref") + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + else() + configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) + file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_HASH "${CMAKE_MATCH_1}") + endif() + endif() +else() + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) +endif() + +if(NOT HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) +endif() diff --git a/logic/Json.h b/logic/Json.h index f03f777a..5d3186ce 100644 --- a/logic/Json.h +++ b/logic/Json.h @@ -35,13 +35,13 @@ QByteArray toText(const QJsonObject &obj); QByteArray toText(const QJsonArray &array); /// @throw JsonException -QJsonDocument requireDocument(const QByteArray &data, const QString &what = "Document"); +MULTIMC_LOGIC_EXPORT QJsonDocument requireDocument(const QByteArray &data, const QString &what = "Document"); /// @throw JsonException -QJsonDocument requireDocument(const QString &filename, const QString &what = "Document"); +MULTIMC_LOGIC_EXPORT QJsonDocument requireDocument(const QString &filename, const QString &what = "Document"); /// @throw JsonException -QJsonObject requireObject(const QJsonDocument &doc, const QString &what = "Document"); +MULTIMC_LOGIC_EXPORT QJsonObject requireObject(const QJsonDocument &doc, const QString &what = "Document"); /// @throw JsonException -QJsonArray requireArray(const QJsonDocument &doc, const QString &what = "Document"); +MULTIMC_LOGIC_EXPORT QJsonArray requireArray(const QJsonDocument &doc, const QString &what = "Document"); /////////////////// WRITING //////////////////// diff --git a/tests/tst_DownloadTask.cpp b/tests/tst_DownloadTask.cpp index 978449f1..743bf514 100644 --- a/tests/tst_DownloadTask.cpp +++ b/tests/tst_DownloadTask.cpp @@ -185,29 +185,7 @@ slots: qDebug() << expectedOperations; QCOMPARE(operations, expectedOperations); } -/* - void test_masterTest() - { - qDebug() << "#####################"; - MMC->m_version.build = 1; - MMC->m_version.channel = "develop"; - auto channels = - QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/channels.json")); - auto root = QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")); - qDebug() << "channels: " << channels; - qDebug() << "root: " << root; - MMC->updateChecker()->setChannelListUrl(channels.toString()); - MMC->updateChecker()->setCurrentChannel("develop"); - DownloadTask task(root.toString(), 2); - - QSignalSpy succeededSpy(&task, SIGNAL(succeeded())); - - task.start(); - - QVERIFY(succeededSpy.wait()); - } -*/ void test_OSXPathFixup() { QString path, pathOrig;