Mess with the updater again.
This commit is contained in:
		@@ -503,6 +503,8 @@ IF(WIN32)
 | 
			
		||||
	)
 | 
			
		||||
ENDIF(WIN32)
 | 
			
		||||
 | 
			
		||||
OPTION(MultiMC_UPDATER_DRY_RUN "Enable updater dry-run mode." OFF)
 | 
			
		||||
 | 
			
		||||
OPTION(MultiMC_CODE_COVERAGE "Compiles for code coverage" OFF)
 | 
			
		||||
IF(MultiMC_CODE_COVERAGE)
 | 
			
		||||
	SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 --coverage")
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								MultiMC.cpp
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								MultiMC.cpp
									
									
									
									
									
								
							@@ -35,17 +35,6 @@
 | 
			
		||||
#include "logger/QsLog.h"
 | 
			
		||||
#include <logger/QsLogDest.h>
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#ifdef WINDOWS
 | 
			
		||||
#define UPDATER_BIN "updater.exe"
 | 
			
		||||
#elif LINUX
 | 
			
		||||
#define UPDATER_BIN "updater"
 | 
			
		||||
#elif OSX
 | 
			
		||||
#define UPDATER_BIN "updater"
 | 
			
		||||
#else
 | 
			
		||||
#error Unsupported operating system.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using namespace Util::Commandline;
 | 
			
		||||
 | 
			
		||||
MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
 | 
			
		||||
@@ -136,6 +125,11 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
 | 
			
		||||
		adjustedBy += "Command line " + dirParam;
 | 
			
		||||
		dataPath = dirParam;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		dataPath = applicationDirPath();
 | 
			
		||||
		adjustedBy += "Fallback to binary path " + dataPath;
 | 
			
		||||
	}
 | 
			
		||||
	if(!ensureFolderPathExists(dataPath) || !QDir::setCurrent(dataPath))
 | 
			
		||||
	{
 | 
			
		||||
		// BAD STUFF. WHAT DO?
 | 
			
		||||
@@ -150,8 +144,7 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
 | 
			
		||||
		QDir foo(PathCombine(binPath, ".."));
 | 
			
		||||
		rootPath = foo.absolutePath();
 | 
			
		||||
	#elif defined(Q_OS_WIN32)
 | 
			
		||||
		QDir foo(PathCombine(binPath, ".."));
 | 
			
		||||
		rootPath = foo.absolutePath();
 | 
			
		||||
		rootPath = binPath;
 | 
			
		||||
	#elif defined(Q_OS_MAC)
 | 
			
		||||
		QDir foo(PathCombine(binPath, "../.."));
 | 
			
		||||
		rootPath = foo.absolutePath();
 | 
			
		||||
@@ -341,7 +334,7 @@ void MultiMC::initLogger()
 | 
			
		||||
	QsLogging::Logger &logger = QsLogging::Logger::instance();
 | 
			
		||||
	logger.setLoggingLevel(QsLogging::TraceLevel);
 | 
			
		||||
	m_fileDestination = QsLogging::DestinationFactory::MakeFileDestination(logBase.arg(0));
 | 
			
		||||
	m_debugDestination = QsLogging::DestinationFactory::MakeDebugOutputDestination();
 | 
			
		||||
	m_debugDestination = QsLogging::DestinationFactory::MakeQDebugDestination();
 | 
			
		||||
	logger.addDestination(m_fileDestination.get());
 | 
			
		||||
	logger.addDestination(m_debugDestination.get());
 | 
			
		||||
	// log all the things
 | 
			
		||||
@@ -468,7 +461,7 @@ void MultiMC::initHttpMetaCache()
 | 
			
		||||
	m_metacache->addBase("libraries", QDir("libraries").absolutePath());
 | 
			
		||||
	m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
 | 
			
		||||
	m_metacache->addBase("skins", QDir("accounts/skins").absolutePath());
 | 
			
		||||
	m_metacache->addBase("root", QDir(".").absolutePath());
 | 
			
		||||
	m_metacache->addBase("root", QDir(root()).absolutePath());
 | 
			
		||||
	m_metacache->Load();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -520,36 +513,29 @@ std::shared_ptr<JavaVersionList> MultiMC::javalist()
 | 
			
		||||
void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish)
 | 
			
		||||
{
 | 
			
		||||
	QLOG_INFO() << "Installing updates.";
 | 
			
		||||
#if LINUX
 | 
			
		||||
	// On Linux, the MultiMC executable file is actually in the bin folder inside the
 | 
			
		||||
	// installation directory.
 | 
			
		||||
	// This means that MultiMC's *actual* install path is the parent folder.
 | 
			
		||||
	// We need to tell the updater to run with this directory as the install path, rather than
 | 
			
		||||
	// the bin folder where the executable is.
 | 
			
		||||
	// On other operating systems, we'll just use the path to the executable.
 | 
			
		||||
	QString appDir = QFileInfo(MMC->applicationDirPath()).dir().path();
 | 
			
		||||
 | 
			
		||||
	// On Linux, we also need to set the finish command to the launch script, rather than the
 | 
			
		||||
	// binary.
 | 
			
		||||
	QString finishCmd = PathCombine(appDir, "MultiMC");
 | 
			
		||||
#else
 | 
			
		||||
	QString appDir = MMC->applicationDirPath();
 | 
			
		||||
	QString finishCmd = MMC->applicationFilePath();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	// Build the command we'll use to run the updater.
 | 
			
		||||
	// Note, the above comment about the app dir path on Linux is irrelevant here because the
 | 
			
		||||
	// updater binary is always in the
 | 
			
		||||
	// same folder as the main binary.
 | 
			
		||||
	QString updaterBinary = PathCombine(MMC->applicationDirPath(), UPDATER_BIN);
 | 
			
		||||
	#ifdef WINDOWS
 | 
			
		||||
		QString finishCmd = MMC->applicationFilePath();
 | 
			
		||||
		QString updaterBinary = PathCombine(bin(), "updater.exe");
 | 
			
		||||
	#elif LINUX
 | 
			
		||||
		QString finishCmd = PathCombine(root(), "MultiMC");
 | 
			
		||||
		QString updaterBinary = PathCombine(bin(), "updater");
 | 
			
		||||
	#elif OSX
 | 
			
		||||
		QString finishCmd = MMC->applicationFilePath();
 | 
			
		||||
		QString updaterBinary = PathCombine(bin(), "updater");
 | 
			
		||||
	#else
 | 
			
		||||
		#error Unsupported operating system.
 | 
			
		||||
	#endif
 | 
			
		||||
	
 | 
			
		||||
	QStringList args;
 | 
			
		||||
	// ./updater --install-dir $INSTALL_DIR --package-dir $UPDATEFILES_DIR --script
 | 
			
		||||
	// $UPDATEFILES_DIR/file_list.xml --wait $PID --mode main
 | 
			
		||||
	args << "--install-dir" << appDir;
 | 
			
		||||
	args << "--install-dir" << root();
 | 
			
		||||
	args << "--package-dir" << updateFilesDir;
 | 
			
		||||
	args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
 | 
			
		||||
	args << "--wait" << QString::number(MMC->applicationPid());
 | 
			
		||||
 | 
			
		||||
#ifdef MultiMC_UPDATER_DRY_RUN
 | 
			
		||||
	args << "--dry-run";
 | 
			
		||||
#endif
 | 
			
		||||
	if (restartOnFinish)
 | 
			
		||||
		args << "--finish-cmd" << finishCmd;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
#include "MultiMCVersion.h"
 | 
			
		||||
#include <memory>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
// Minor and major version, used to communicate changes to users.
 | 
			
		||||
#define VERSION_MAJOR		@MultiMC_VERSION_MAJOR@
 | 
			
		||||
#define VERSION_MINOR		@MultiMC_VERSION_MINOR@
 | 
			
		||||
@@ -16,6 +18,9 @@
 | 
			
		||||
// Used for matching notifications
 | 
			
		||||
#define FULL_VERSION_STR "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_BUILD@"
 | 
			
		||||
 | 
			
		||||
// enabled for updater dry run
 | 
			
		||||
#cmakedefine MultiMC_UPDATER_DRY_RUN
 | 
			
		||||
 | 
			
		||||
// The commit hash of this build
 | 
			
		||||
#define GIT_COMMIT		   "@MultiMC_GIT_COMMIT@"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -402,12 +402,17 @@ DownloadUpdateTask::processFileLists(NetJob *job,
 | 
			
		||||
 | 
			
		||||
				if (isUpdater)
 | 
			
		||||
				{
 | 
			
		||||
#ifdef MultiMC_UPDATER_DRY_RUN
 | 
			
		||||
					QLOG_DEBUG() << "Skipping updater download and using local version.";
 | 
			
		||||
#else
 | 
			
		||||
					auto cache_entry = MMC->metacache()->resolveEntry("root", entry.path);
 | 
			
		||||
					QLOG_DEBUG() << "Updater will be in " << cache_entry->getFullPath();
 | 
			
		||||
					// force check.
 | 
			
		||||
					cache_entry->stale = true;
 | 
			
		||||
 | 
			
		||||
					auto download = CacheDownload::make(QUrl(source.url), cache_entry);
 | 
			
		||||
					job->addNetAction(download);
 | 
			
		||||
#endif
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
@@ -514,7 +519,6 @@ bool DownloadUpdateTask::fixPathForOSX(QString &path)
 | 
			
		||||
	{
 | 
			
		||||
		// remove the prefix and add a new, more appropriate one.
 | 
			
		||||
		path.remove(0, 12);
 | 
			
		||||
		path = QString("../../") + path;
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
 
 | 
			
		||||
@@ -206,11 +206,9 @@ protected:
 | 
			
		||||
	 * The updater runs in MultiMC.app/Contents/MacOs by default
 | 
			
		||||
	 * The destination paths are such as this: MultiMC.app/blah/blah
 | 
			
		||||
	 * 
 | 
			
		||||
	 * Therefore we chop off the 'MultiMC.app' prefix and prepend ../..
 | 
			
		||||
	 * Therefore we chop off the 'MultiMC.app' prefix
 | 
			
		||||
	 * 
 | 
			
		||||
	 * Returns false if the path couldn't be fixed (is invalid)
 | 
			
		||||
	 * 
 | 
			
		||||
	 * Has no effect on systems that aren't OSX
 | 
			
		||||
	 */
 | 
			
		||||
	static bool fixPathForOSX(QString &path);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,6 @@
 | 
			
		||||
 | 
			
		||||
#include "MultiMC.h"
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "logger/QsLog.h"
 | 
			
		||||
 | 
			
		||||
#include <QJsonObject>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,16 +6,6 @@
 | 
			
		||||
#include "ProcessUtils.h"
 | 
			
		||||
#include "UpdateObserver.h"
 | 
			
		||||
 | 
			
		||||
UpdateInstaller::UpdateInstaller()
 | 
			
		||||
: m_mode(Setup)
 | 
			
		||||
, m_waitPid(0)
 | 
			
		||||
, m_script(0)
 | 
			
		||||
, m_observer(0)
 | 
			
		||||
, m_forceElevated(false)
 | 
			
		||||
, m_autoClose(false)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UpdateInstaller::setWaitPid(PLATFORM_PID pid)
 | 
			
		||||
{
 | 
			
		||||
	m_waitPid = pid;
 | 
			
		||||
@@ -69,6 +59,10 @@ std::list<std::string> UpdateInstaller::updaterArgs() const
 | 
			
		||||
	{
 | 
			
		||||
		args.push_back("--auto-close");
 | 
			
		||||
	}
 | 
			
		||||
	if (m_dryRun)
 | 
			
		||||
	{
 | 
			
		||||
		args.push_back("--dry-run");
 | 
			
		||||
	}
 | 
			
		||||
	return args;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -255,25 +249,32 @@ void UpdateInstaller::cleanup()
 | 
			
		||||
 | 
			
		||||
void UpdateInstaller::revert()
 | 
			
		||||
{
 | 
			
		||||
	LOG(Info,"Reverting installation!");
 | 
			
		||||
	std::map<std::string,std::string>::const_iterator iter = m_backups.begin();
 | 
			
		||||
	for (;iter != m_backups.end();iter++)
 | 
			
		||||
	{
 | 
			
		||||
		const std::string& installedFile = iter->first;
 | 
			
		||||
		const std::string& backupFile = iter->second;
 | 
			
		||||
 | 
			
		||||
		if (FileUtils::fileExists(installedFile.c_str()))
 | 
			
		||||
		LOG(Info,"Restoring " + installedFile);
 | 
			
		||||
		if(!m_dryRun)
 | 
			
		||||
		{
 | 
			
		||||
			FileUtils::removeFile(installedFile.c_str());
 | 
			
		||||
			if (FileUtils::fileExists(installedFile.c_str()))
 | 
			
		||||
			{
 | 
			
		||||
				FileUtils::removeFile(installedFile.c_str());
 | 
			
		||||
			}
 | 
			
		||||
			FileUtils::moveFile(backupFile.c_str(),installedFile.c_str());
 | 
			
		||||
		}
 | 
			
		||||
		FileUtils::moveFile(backupFile.c_str(),installedFile.c_str());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UpdateInstaller::installFile(const UpdateScriptFile& file)
 | 
			
		||||
{
 | 
			
		||||
	std::string sourceFile = file.source;
 | 
			
		||||
	std::string destPath = file.dest;
 | 
			
		||||
	std::string target = file.linkTarget;
 | 
			
		||||
 | 
			
		||||
	LOG(Info,"Installing file " + sourceFile + " to " + destPath);
 | 
			
		||||
 | 
			
		||||
	// backup the existing file if any
 | 
			
		||||
	backupFile(destPath);
 | 
			
		||||
 | 
			
		||||
@@ -281,22 +282,29 @@ void UpdateInstaller::installFile(const UpdateScriptFile& file)
 | 
			
		||||
	std::string destDir = FileUtils::dirname(destPath.c_str());
 | 
			
		||||
	if (!FileUtils::fileExists(destDir.c_str()))
 | 
			
		||||
	{
 | 
			
		||||
		FileUtils::mkpath(destDir.c_str());
 | 
			
		||||
		LOG(Info,"Destination path missing. Creating " + destDir);
 | 
			
		||||
		if(!m_dryRun)
 | 
			
		||||
		{
 | 
			
		||||
			FileUtils::mkpath(destDir.c_str());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::string sourceFile = file.source;
 | 
			
		||||
	if (!FileUtils::fileExists(sourceFile.c_str()))
 | 
			
		||||
	{
 | 
			
		||||
		throw "Source file does not exist: " + sourceFile;
 | 
			
		||||
	}
 | 
			
		||||
	FileUtils::copyFile(sourceFile.c_str(),destPath.c_str());
 | 
			
		||||
	if(!m_dryRun)
 | 
			
		||||
	{
 | 
			
		||||
		FileUtils::copyFile(sourceFile.c_str(),destPath.c_str());
 | 
			
		||||
 | 
			
		||||
	// set the permissions on the newly extracted file
 | 
			
		||||
	FileUtils::chmod(destPath.c_str(),file.permissions);
 | 
			
		||||
		// set the permissions on the newly extracted file
 | 
			
		||||
		FileUtils::chmod(destPath.c_str(),file.permissions);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UpdateInstaller::installFiles()
 | 
			
		||||
{
 | 
			
		||||
	LOG(Info,"Installing files.");
 | 
			
		||||
	std::vector<UpdateScriptFile>::const_iterator iter = m_script->filesToInstall().begin();
 | 
			
		||||
	int filesInstalled = 0;
 | 
			
		||||
	for (;iter != m_script->filesToInstall().end();iter++)
 | 
			
		||||
@@ -314,13 +322,18 @@ void UpdateInstaller::installFiles()
 | 
			
		||||
 | 
			
		||||
void UpdateInstaller::uninstallFiles()
 | 
			
		||||
{
 | 
			
		||||
	LOG(Info,"Uninstalling files.");
 | 
			
		||||
	std::vector<std::string>::const_iterator iter = m_script->filesToUninstall().begin();
 | 
			
		||||
	for (;iter != m_script->filesToUninstall().end();iter++)
 | 
			
		||||
	{
 | 
			
		||||
		std::string path = m_installDir + '/' + iter->c_str();
 | 
			
		||||
		if (FileUtils::fileExists(path.c_str()))
 | 
			
		||||
		{
 | 
			
		||||
			FileUtils::removeFile(path.c_str());
 | 
			
		||||
			LOG(Info,"Uninstalling " + path);
 | 
			
		||||
			if(!m_dryRun)
 | 
			
		||||
			{
 | 
			
		||||
				FileUtils::removeFile(path.c_str());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
@@ -336,30 +349,41 @@ void UpdateInstaller::backupFile(const std::string& path)
 | 
			
		||||
		// no existing file to backup
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	std::string backupPath = path + ".bak";
 | 
			
		||||
	FileUtils::removeFile(backupPath.c_str());
 | 
			
		||||
	FileUtils::moveFile(path.c_str(), backupPath.c_str());
 | 
			
		||||
	LOG(Info,"Backing up file: " + path + " as " + backupPath);
 | 
			
		||||
	if(!m_dryRun)
 | 
			
		||||
	{
 | 
			
		||||
		FileUtils::removeFile(backupPath.c_str());
 | 
			
		||||
		FileUtils::moveFile(path.c_str(), backupPath.c_str());
 | 
			
		||||
	}
 | 
			
		||||
	m_backups[path] = backupPath;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UpdateInstaller::removeBackups()
 | 
			
		||||
{
 | 
			
		||||
	LOG(Info,"Removing backups.");
 | 
			
		||||
	std::map<std::string,std::string>::const_iterator iter = m_backups.begin();
 | 
			
		||||
	for (;iter != m_backups.end();iter++)
 | 
			
		||||
	{
 | 
			
		||||
		const std::string& backupFile = iter->second;
 | 
			
		||||
		FileUtils::removeFile(backupFile.c_str());
 | 
			
		||||
		LOG(Info,"Removing " + backupFile);
 | 
			
		||||
		if(!m_dryRun)
 | 
			
		||||
		{
 | 
			
		||||
			FileUtils::removeFile(backupFile.c_str());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool UpdateInstaller::checkAccess()
 | 
			
		||||
{
 | 
			
		||||
	std::string testFile = m_installDir + "/update-installer-test-file";
 | 
			
		||||
 | 
			
		||||
	LOG(Info,"Checking for access: " + testFile);
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		FileUtils::removeFile(testFile.c_str());
 | 
			
		||||
		if(!m_dryRun)
 | 
			
		||||
		{
 | 
			
		||||
			FileUtils::removeFile(testFile.c_str());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	catch (const FileUtils::IOException& error)
 | 
			
		||||
	{
 | 
			
		||||
@@ -368,8 +392,11 @@ bool UpdateInstaller::checkAccess()
 | 
			
		||||
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		FileUtils::touch(testFile.c_str());
 | 
			
		||||
		FileUtils::removeFile(testFile.c_str());
 | 
			
		||||
		if(!m_dryRun)
 | 
			
		||||
		{
 | 
			
		||||
			FileUtils::touch(testFile.c_str());
 | 
			
		||||
			FileUtils::removeFile(testFile.c_str());
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	catch (const FileUtils::IOException& error)
 | 
			
		||||
@@ -394,7 +421,10 @@ void UpdateInstaller::restartMainApp()
 | 
			
		||||
		if (!command.empty())
 | 
			
		||||
		{
 | 
			
		||||
			LOG(Info,"Starting main application " + command);
 | 
			
		||||
			ProcessUtils::runAsync(command,args);
 | 
			
		||||
			if(!m_dryRun)
 | 
			
		||||
			{
 | 
			
		||||
				ProcessUtils::runAsync(command,args);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
@@ -415,7 +445,11 @@ void UpdateInstaller::postInstallUpdate()
 | 
			
		||||
	// touch the application's bundle directory so that
 | 
			
		||||
	// OS X' Launch Services notices any changes in the application's
 | 
			
		||||
	// Info.plist file.
 | 
			
		||||
	FileUtils::touch(m_installDir.c_str());
 | 
			
		||||
	LOG(Info,"Touching " + m_installDir.c_str() + " to notify OSX of metadata changes.");
 | 
			
		||||
	if(!m_dryRun)
 | 
			
		||||
	{
 | 
			
		||||
		FileUtils::touch(m_installDir.c_str());
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -424,3 +458,7 @@ void UpdateInstaller::setAutoClose(bool autoClose)
 | 
			
		||||
	m_autoClose = autoClose;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UpdateInstaller::setDryRun(bool dryRun)
 | 
			
		||||
{
 | 
			
		||||
	m_dryRun = dryRun;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,6 @@ class UpdateInstaller
 | 
			
		||||
			Main
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		UpdateInstaller();
 | 
			
		||||
		void setInstallDir(const std::string& path);
 | 
			
		||||
		void setPackageDir(const std::string& path);
 | 
			
		||||
		void setBackupDir(const std::string& path);
 | 
			
		||||
@@ -33,6 +32,7 @@ class UpdateInstaller
 | 
			
		||||
		void setWaitPid(PLATFORM_PID pid);
 | 
			
		||||
		void setForceElevated(bool elevated);
 | 
			
		||||
		void setAutoClose(bool autoClose);
 | 
			
		||||
		void setDryRun(bool dryRun);
 | 
			
		||||
		void setFinishCmd(const std::string& cmd);
 | 
			
		||||
 | 
			
		||||
		void setObserver(UpdateObserver* observer);
 | 
			
		||||
@@ -57,16 +57,16 @@ class UpdateInstaller
 | 
			
		||||
		std::list<std::string> updaterArgs() const;
 | 
			
		||||
		std::string friendlyErrorForError(const FileUtils::IOException& ex) const;
 | 
			
		||||
 | 
			
		||||
		Mode m_mode;
 | 
			
		||||
		Mode m_mode = Setup;
 | 
			
		||||
		std::string m_installDir;
 | 
			
		||||
		std::string m_packageDir;
 | 
			
		||||
		std::string m_backupDir;
 | 
			
		||||
		std::string m_finishCmd;
 | 
			
		||||
		PLATFORM_PID m_waitPid;
 | 
			
		||||
		UpdateScript* m_script;
 | 
			
		||||
		UpdateObserver* m_observer;
 | 
			
		||||
		PLATFORM_PID m_waitPid = 0;
 | 
			
		||||
		UpdateScript* m_script = nullptr;
 | 
			
		||||
		UpdateObserver* m_observer = nullptr;
 | 
			
		||||
		std::map<std::string,std::string> m_backups;
 | 
			
		||||
		bool m_forceElevated;
 | 
			
		||||
		bool m_autoClose;
 | 
			
		||||
		bool m_forceElevated = false;
 | 
			
		||||
		bool m_autoClose = false;
 | 
			
		||||
		bool m_dryRun = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,71 +34,6 @@ UpdateInstaller::Mode stringToMode(const std::string& modeStr)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UpdaterOptions::parseOldFormatArg(const std::string& arg, std::string* key, std::string* value)
 | 
			
		||||
{
 | 
			
		||||
	size_t pos = arg.find('=');
 | 
			
		||||
	if (pos != std::string::npos)
 | 
			
		||||
	{
 | 
			
		||||
		*key = arg.substr(0,pos);
 | 
			
		||||
		*value = arg.substr(pos+1);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this is a compatibility function to allow the updater binary
 | 
			
		||||
// to be involved by legacy versions of Mendeley Desktop
 | 
			
		||||
// which used a different syntax for the updater's command-line
 | 
			
		||||
// arguments
 | 
			
		||||
void UpdaterOptions::parseOldFormatArgs(int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
	for (int i=0; i < argc; i++)
 | 
			
		||||
	{
 | 
			
		||||
		std::string key;
 | 
			
		||||
		std::string value;
 | 
			
		||||
 | 
			
		||||
		parseOldFormatArg(argv[i],&key,&value);
 | 
			
		||||
 | 
			
		||||
		if (key == "CurrentDir")
 | 
			
		||||
		{
 | 
			
		||||
			// CurrentDir is the directory containing the main application
 | 
			
		||||
			// binary.  On Mac and Linux this differs from the root of
 | 
			
		||||
			// the installation directory
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_LINUX
 | 
			
		||||
			// the main binary is in lib/mendeleydesktop/libexec,
 | 
			
		||||
			// go up 3 levels
 | 
			
		||||
			installDir = FileUtils::canonicalPath((value + "/../../../").c_str());
 | 
			
		||||
#elif defined(PLATFORM_MAC)
 | 
			
		||||
			// the main binary is in Contents/MacOS,
 | 
			
		||||
			// go up 2 levels
 | 
			
		||||
			installDir = FileUtils::canonicalPath((value + "/../../").c_str());
 | 
			
		||||
#elif defined(PLATFORM_WINDOWS)
 | 
			
		||||
			// the main binary is in the root of the install directory
 | 
			
		||||
			installDir = value;
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
		else if (key == "TempDir")
 | 
			
		||||
		{
 | 
			
		||||
			packageDir = value;
 | 
			
		||||
		}
 | 
			
		||||
		else if (key == "UpdateScriptFileName")
 | 
			
		||||
		{
 | 
			
		||||
			scriptPath = value;
 | 
			
		||||
		}
 | 
			
		||||
		else if (key == "AppFileName")
 | 
			
		||||
		{
 | 
			
		||||
			// TODO - Store app file name
 | 
			
		||||
		}
 | 
			
		||||
		else if (key == "PID")
 | 
			
		||||
		{
 | 
			
		||||
			waitPid = static_cast<PLATFORM_PID>(atoll(value.c_str()));
 | 
			
		||||
		}
 | 
			
		||||
		else if (key == "--main")
 | 
			
		||||
		{
 | 
			
		||||
			mode = UpdateInstaller::Main;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UpdaterOptions::parse(int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
	AnyOption parser;
 | 
			
		||||
@@ -110,6 +45,7 @@ void UpdaterOptions::parse(int argc, char** argv)
 | 
			
		||||
	parser.setOption("mode");
 | 
			
		||||
	parser.setFlag("version");
 | 
			
		||||
	parser.setFlag("force-elevated");
 | 
			
		||||
	parser.setFlag("dry-run");
 | 
			
		||||
	parser.setFlag("auto-close");
 | 
			
		||||
 | 
			
		||||
	parser.processCommandArgs(argc,argv);
 | 
			
		||||
@@ -141,15 +77,6 @@ void UpdaterOptions::parse(int argc, char** argv)
 | 
			
		||||
 | 
			
		||||
	showVersion = parser.getFlag("version");
 | 
			
		||||
	forceElevated = parser.getFlag("force-elevated");
 | 
			
		||||
	dryRun = parser.getFlag("dry-run");
 | 
			
		||||
	autoClose = parser.getFlag("auto-close");
 | 
			
		||||
 | 
			
		||||
	if (installDir.empty())
 | 
			
		||||
	{
 | 
			
		||||
		// if no --install-dir argument is present, try parsing
 | 
			
		||||
		// the command-line arguments in the old format (which uses
 | 
			
		||||
		// a list of 'Key=Value' args)
 | 
			
		||||
		parseOldFormatArgs(argc,argv);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,11 +18,8 @@ class UpdaterOptions
 | 
			
		||||
		PLATFORM_PID waitPid;
 | 
			
		||||
		std::string logFile;
 | 
			
		||||
		bool showVersion;
 | 
			
		||||
		bool dryRun;
 | 
			
		||||
		bool forceElevated;
 | 
			
		||||
		bool autoClose;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void parseOldFormatArgs(int argc, char** argv);
 | 
			
		||||
		static void parseOldFormatArg(const std::string& arg, std::string* key, std::string* value);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -148,6 +148,7 @@ int main(int argc, char** argv)
 | 
			
		||||
	installer.setForceElevated(options.forceElevated);
 | 
			
		||||
	installer.setAutoClose(options.autoClose);
 | 
			
		||||
	installer.setFinishCmd(options.finishCmd);
 | 
			
		||||
	installer.setDryRun(options.dryRun);
 | 
			
		||||
 | 
			
		||||
	if (options.mode == UpdateInstaller::Main)
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user