GH-1360 add basic changelog based on github API, fix update dialog buttons
This commit is contained 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; | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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") | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -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()); | ||||
|  | ||||
|   | ||||
| @@ -3,10 +3,13 @@ | ||||
| #include <QDebug> | ||||
| #include "MultiMC.h" | ||||
| #include <settings/SettingsObject.h> | ||||
| #include <Json.h> | ||||
|  | ||||
| #include <hoedown/html.h> | ||||
| #include <hoedown/document.h> | ||||
|  | ||||
| #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 += "<table cellspacing=0 cellpadding=2 style='border-width: 1px; border-style: solid'>"; | ||||
| 			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("(?<prefix>(GH-(?<issuenr>[0-9]+))|(NOISSUE)|(SCRATCH))? *(?<rest>.*) *"); | ||||
| 				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 += "<tr><td>"; | ||||
| 				if(issuenr.length()) | ||||
| 				{ | ||||
| 					result += QString("<a href=\"https://github.com/MultiMC/MultiMC5/issues/%1\">GH-%2</a>").arg(issuenr, issuenr); | ||||
| 				} | ||||
| 				else if(prefix.length()) | ||||
| 				{ | ||||
| 					result += QString("<a href=\"%1\">%2</a>").arg(commit_url, prefix); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					result += QString("<a href=\"%1\">NOISSUE</a>").arg(commit_url); | ||||
| 				} | ||||
| 				result += "</td>"; | ||||
| 				lines.prepend(rest); | ||||
| 				result += "<td><p>" + lines.join("<br />") + "</p></td></tr>"; | ||||
| 			} | ||||
| 			result += "</table>"; | ||||
| 		}; | ||||
|  | ||||
| 		if(status == "identical") | ||||
| 		{ | ||||
| 			return QObject::tr("<p>There is are no code changes between your current version and %1 HEAD.</p>").arg(channel); | ||||
| 		} | ||||
| 		else if(status == "ahead") | ||||
| 		{ | ||||
| 			result += QObject::tr("<p>Following commits were added since last update:</p>"); | ||||
| 			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("<p>The update removes %1 commits and adds the following %2:</p>").arg(commit_behind, commit_ahead); | ||||
| 			print_commits(); | ||||
| 		} | ||||
| 		result += QObject::tr("<p>You can <a href=\"%1\">look at the changes on github</a>.</p>").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) | ||||
|   | ||||
| @@ -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; | ||||
| }; | ||||
|   | ||||
| @@ -46,7 +46,7 @@ | ||||
|       <string><!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></string> | ||||
|      </property> | ||||
|      <property name="openExternalLinks"> | ||||
| @@ -55,8 +55,8 @@ p, li { white-space: pre-wrap; } | ||||
|     </widget> | ||||
|    </item> | ||||
|    <item> | ||||
|     <layout class="QHBoxLayout" name="horizontalLayout"> | ||||
|      <item> | ||||
|     <layout class="QGridLayout" name="gridLayout"> | ||||
|      <item row="0" column="0"> | ||||
|       <widget class="QPushButton" name="btnUpdateNow"> | ||||
|        <property name="sizePolicy"> | ||||
|         <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||||
| @@ -69,7 +69,7 @@ p, li { white-space: pre-wrap; } | ||||
|        </property> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|      <item row="0" column="1"> | ||||
|       <widget class="QPushButton" name="btnUpdateLater"> | ||||
|        <property name="sizePolicy"> | ||||
|         <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||||
|   | ||||
| @@ -27,6 +27,7 @@ | ||||
| #include "settings/SettingsObject.h" | ||||
| #include <FileSystem.h> | ||||
| #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())); | ||||
|   | ||||
							
								
								
									
										130
									
								
								cmake/GetGitRevisionDescription.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								cmake/GetGitRevisionDescription.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -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(<refspecvar> <hashvar> [<additional arguments to git describe> ...]) | ||||
| # | ||||
| # Returns the refspec and sha hash of the current head revision | ||||
| # | ||||
| #  git_describe(<var> [<additional arguments to 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(<var> [<additional arguments to git describe> ...]) | ||||
| # | ||||
| # 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 <rpavlik@iastate.edu> <abiryan@ryand.net> | ||||
| # 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() | ||||
							
								
								
									
										41
									
								
								cmake/GetGitRevisionDescription.cmake.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								cmake/GetGitRevisionDescription.cmake.in
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <rpavlik@iastate.edu> <abiryan@ryand.net> | ||||
| # 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() | ||||
| @@ -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 //////////////////// | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user