Mess with the updater again.
This commit is contained in:
parent
e558584af0
commit
b49fa9d2a9
@ -503,6 +503,8 @@ IF(WIN32)
|
|||||||
)
|
)
|
||||||
ENDIF(WIN32)
|
ENDIF(WIN32)
|
||||||
|
|
||||||
|
OPTION(MultiMC_UPDATER_DRY_RUN "Enable updater dry-run mode." OFF)
|
||||||
|
|
||||||
OPTION(MultiMC_CODE_COVERAGE "Compiles for code coverage" OFF)
|
OPTION(MultiMC_CODE_COVERAGE "Compiles for code coverage" OFF)
|
||||||
IF(MultiMC_CODE_COVERAGE)
|
IF(MultiMC_CODE_COVERAGE)
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 --coverage")
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 --coverage")
|
||||||
|
60
MultiMC.cpp
60
MultiMC.cpp
@ -35,17 +35,6 @@
|
|||||||
#include "logger/QsLog.h"
|
#include "logger/QsLog.h"
|
||||||
#include <logger/QsLogDest.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;
|
using namespace Util::Commandline;
|
||||||
|
|
||||||
MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
|
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;
|
adjustedBy += "Command line " + dirParam;
|
||||||
dataPath = dirParam;
|
dataPath = dirParam;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataPath = applicationDirPath();
|
||||||
|
adjustedBy += "Fallback to binary path " + dataPath;
|
||||||
|
}
|
||||||
if(!ensureFolderPathExists(dataPath) || !QDir::setCurrent(dataPath))
|
if(!ensureFolderPathExists(dataPath) || !QDir::setCurrent(dataPath))
|
||||||
{
|
{
|
||||||
// BAD STUFF. WHAT DO?
|
// BAD STUFF. WHAT DO?
|
||||||
@ -150,8 +144,7 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
|
|||||||
QDir foo(PathCombine(binPath, ".."));
|
QDir foo(PathCombine(binPath, ".."));
|
||||||
rootPath = foo.absolutePath();
|
rootPath = foo.absolutePath();
|
||||||
#elif defined(Q_OS_WIN32)
|
#elif defined(Q_OS_WIN32)
|
||||||
QDir foo(PathCombine(binPath, ".."));
|
rootPath = binPath;
|
||||||
rootPath = foo.absolutePath();
|
|
||||||
#elif defined(Q_OS_MAC)
|
#elif defined(Q_OS_MAC)
|
||||||
QDir foo(PathCombine(binPath, "../.."));
|
QDir foo(PathCombine(binPath, "../.."));
|
||||||
rootPath = foo.absolutePath();
|
rootPath = foo.absolutePath();
|
||||||
@ -341,7 +334,7 @@ void MultiMC::initLogger()
|
|||||||
QsLogging::Logger &logger = QsLogging::Logger::instance();
|
QsLogging::Logger &logger = QsLogging::Logger::instance();
|
||||||
logger.setLoggingLevel(QsLogging::TraceLevel);
|
logger.setLoggingLevel(QsLogging::TraceLevel);
|
||||||
m_fileDestination = QsLogging::DestinationFactory::MakeFileDestination(logBase.arg(0));
|
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_fileDestination.get());
|
||||||
logger.addDestination(m_debugDestination.get());
|
logger.addDestination(m_debugDestination.get());
|
||||||
// log all the things
|
// log all the things
|
||||||
@ -468,7 +461,7 @@ void MultiMC::initHttpMetaCache()
|
|||||||
m_metacache->addBase("libraries", QDir("libraries").absolutePath());
|
m_metacache->addBase("libraries", QDir("libraries").absolutePath());
|
||||||
m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
|
m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
|
||||||
m_metacache->addBase("skins", QDir("accounts/skins").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();
|
m_metacache->Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,36 +513,29 @@ std::shared_ptr<JavaVersionList> MultiMC::javalist()
|
|||||||
void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish)
|
void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish)
|
||||||
{
|
{
|
||||||
QLOG_INFO() << "Installing updates.";
|
QLOG_INFO() << "Installing updates.";
|
||||||
#if LINUX
|
#ifdef WINDOWS
|
||||||
// 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();
|
QString finishCmd = MMC->applicationFilePath();
|
||||||
#endif
|
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
|
||||||
|
|
||||||
// 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);
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
// ./updater --install-dir $INSTALL_DIR --package-dir $UPDATEFILES_DIR --script
|
// ./updater --install-dir $INSTALL_DIR --package-dir $UPDATEFILES_DIR --script
|
||||||
// $UPDATEFILES_DIR/file_list.xml --wait $PID --mode main
|
// $UPDATEFILES_DIR/file_list.xml --wait $PID --mode main
|
||||||
args << "--install-dir" << appDir;
|
args << "--install-dir" << root();
|
||||||
args << "--package-dir" << updateFilesDir;
|
args << "--package-dir" << updateFilesDir;
|
||||||
args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
|
args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
|
||||||
args << "--wait" << QString::number(MMC->applicationPid());
|
args << "--wait" << QString::number(MMC->applicationPid());
|
||||||
|
#ifdef MultiMC_UPDATER_DRY_RUN
|
||||||
|
args << "--dry-run";
|
||||||
|
#endif
|
||||||
if (restartOnFinish)
|
if (restartOnFinish)
|
||||||
args << "--finish-cmd" << finishCmd;
|
args << "--finish-cmd" << finishCmd;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include "MultiMCVersion.h"
|
#include "MultiMCVersion.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
// Minor and major version, used to communicate changes to users.
|
// Minor and major version, used to communicate changes to users.
|
||||||
#define VERSION_MAJOR @MultiMC_VERSION_MAJOR@
|
#define VERSION_MAJOR @MultiMC_VERSION_MAJOR@
|
||||||
#define VERSION_MINOR @MultiMC_VERSION_MINOR@
|
#define VERSION_MINOR @MultiMC_VERSION_MINOR@
|
||||||
@ -16,6 +18,9 @@
|
|||||||
// Used for matching notifications
|
// Used for matching notifications
|
||||||
#define FULL_VERSION_STR "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_BUILD@"
|
#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
|
// The commit hash of this build
|
||||||
#define GIT_COMMIT "@MultiMC_GIT_COMMIT@"
|
#define GIT_COMMIT "@MultiMC_GIT_COMMIT@"
|
||||||
|
|
||||||
|
@ -402,12 +402,17 @@ DownloadUpdateTask::processFileLists(NetJob *job,
|
|||||||
|
|
||||||
if (isUpdater)
|
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);
|
auto cache_entry = MMC->metacache()->resolveEntry("root", entry.path);
|
||||||
QLOG_DEBUG() << "Updater will be in " << cache_entry->getFullPath();
|
QLOG_DEBUG() << "Updater will be in " << cache_entry->getFullPath();
|
||||||
// force check.
|
// force check.
|
||||||
cache_entry->stale = true;
|
cache_entry->stale = true;
|
||||||
|
|
||||||
auto download = CacheDownload::make(QUrl(source.url), cache_entry);
|
auto download = CacheDownload::make(QUrl(source.url), cache_entry);
|
||||||
job->addNetAction(download);
|
job->addNetAction(download);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -514,7 +519,6 @@ bool DownloadUpdateTask::fixPathForOSX(QString &path)
|
|||||||
{
|
{
|
||||||
// remove the prefix and add a new, more appropriate one.
|
// remove the prefix and add a new, more appropriate one.
|
||||||
path.remove(0, 12);
|
path.remove(0, 12);
|
||||||
path = QString("../../") + path;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -206,11 +206,9 @@ protected:
|
|||||||
* The updater runs in MultiMC.app/Contents/MacOs by default
|
* The updater runs in MultiMC.app/Contents/MacOs by default
|
||||||
* The destination paths are such as this: MultiMC.app/blah/blah
|
* 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)
|
* 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);
|
static bool fixPathForOSX(QString &path);
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
#include "MultiMC.h"
|
#include "MultiMC.h"
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "logger/QsLog.h"
|
#include "logger/QsLog.h"
|
||||||
|
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
@ -6,16 +6,6 @@
|
|||||||
#include "ProcessUtils.h"
|
#include "ProcessUtils.h"
|
||||||
#include "UpdateObserver.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)
|
void UpdateInstaller::setWaitPid(PLATFORM_PID pid)
|
||||||
{
|
{
|
||||||
m_waitPid = pid;
|
m_waitPid = pid;
|
||||||
@ -69,6 +59,10 @@ std::list<std::string> UpdateInstaller::updaterArgs() const
|
|||||||
{
|
{
|
||||||
args.push_back("--auto-close");
|
args.push_back("--auto-close");
|
||||||
}
|
}
|
||||||
|
if (m_dryRun)
|
||||||
|
{
|
||||||
|
args.push_back("--dry-run");
|
||||||
|
}
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,48 +249,62 @@ void UpdateInstaller::cleanup()
|
|||||||
|
|
||||||
void UpdateInstaller::revert()
|
void UpdateInstaller::revert()
|
||||||
{
|
{
|
||||||
|
LOG(Info,"Reverting installation!");
|
||||||
std::map<std::string,std::string>::const_iterator iter = m_backups.begin();
|
std::map<std::string,std::string>::const_iterator iter = m_backups.begin();
|
||||||
for (;iter != m_backups.end();iter++)
|
for (;iter != m_backups.end();iter++)
|
||||||
{
|
{
|
||||||
const std::string& installedFile = iter->first;
|
const std::string& installedFile = iter->first;
|
||||||
const std::string& backupFile = iter->second;
|
const std::string& backupFile = iter->second;
|
||||||
|
LOG(Info,"Restoring " + installedFile);
|
||||||
|
if(!m_dryRun)
|
||||||
|
{
|
||||||
if (FileUtils::fileExists(installedFile.c_str()))
|
if (FileUtils::fileExists(installedFile.c_str()))
|
||||||
{
|
{
|
||||||
FileUtils::removeFile(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)
|
void UpdateInstaller::installFile(const UpdateScriptFile& file)
|
||||||
{
|
{
|
||||||
|
std::string sourceFile = file.source;
|
||||||
std::string destPath = file.dest;
|
std::string destPath = file.dest;
|
||||||
std::string target = file.linkTarget;
|
std::string target = file.linkTarget;
|
||||||
|
|
||||||
|
LOG(Info,"Installing file " + sourceFile + " to " + destPath);
|
||||||
|
|
||||||
// backup the existing file if any
|
// backup the existing file if any
|
||||||
backupFile(destPath);
|
backupFile(destPath);
|
||||||
|
|
||||||
// create the target directory if it does not exist
|
// create the target directory if it does not exist
|
||||||
std::string destDir = FileUtils::dirname(destPath.c_str());
|
std::string destDir = FileUtils::dirname(destPath.c_str());
|
||||||
if (!FileUtils::fileExists(destDir.c_str()))
|
if (!FileUtils::fileExists(destDir.c_str()))
|
||||||
|
{
|
||||||
|
LOG(Info,"Destination path missing. Creating " + destDir);
|
||||||
|
if(!m_dryRun)
|
||||||
{
|
{
|
||||||
FileUtils::mkpath(destDir.c_str());
|
FileUtils::mkpath(destDir.c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string sourceFile = file.source;
|
|
||||||
if (!FileUtils::fileExists(sourceFile.c_str()))
|
if (!FileUtils::fileExists(sourceFile.c_str()))
|
||||||
{
|
{
|
||||||
throw "Source file does not exist: " + sourceFile;
|
throw "Source file does not exist: " + sourceFile;
|
||||||
}
|
}
|
||||||
|
if(!m_dryRun)
|
||||||
|
{
|
||||||
FileUtils::copyFile(sourceFile.c_str(),destPath.c_str());
|
FileUtils::copyFile(sourceFile.c_str(),destPath.c_str());
|
||||||
|
|
||||||
// set the permissions on the newly extracted file
|
// set the permissions on the newly extracted file
|
||||||
FileUtils::chmod(destPath.c_str(),file.permissions);
|
FileUtils::chmod(destPath.c_str(),file.permissions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateInstaller::installFiles()
|
void UpdateInstaller::installFiles()
|
||||||
{
|
{
|
||||||
|
LOG(Info,"Installing files.");
|
||||||
std::vector<UpdateScriptFile>::const_iterator iter = m_script->filesToInstall().begin();
|
std::vector<UpdateScriptFile>::const_iterator iter = m_script->filesToInstall().begin();
|
||||||
int filesInstalled = 0;
|
int filesInstalled = 0;
|
||||||
for (;iter != m_script->filesToInstall().end();iter++)
|
for (;iter != m_script->filesToInstall().end();iter++)
|
||||||
@ -314,14 +322,19 @@ void UpdateInstaller::installFiles()
|
|||||||
|
|
||||||
void UpdateInstaller::uninstallFiles()
|
void UpdateInstaller::uninstallFiles()
|
||||||
{
|
{
|
||||||
|
LOG(Info,"Uninstalling files.");
|
||||||
std::vector<std::string>::const_iterator iter = m_script->filesToUninstall().begin();
|
std::vector<std::string>::const_iterator iter = m_script->filesToUninstall().begin();
|
||||||
for (;iter != m_script->filesToUninstall().end();iter++)
|
for (;iter != m_script->filesToUninstall().end();iter++)
|
||||||
{
|
{
|
||||||
std::string path = m_installDir + '/' + iter->c_str();
|
std::string path = m_installDir + '/' + iter->c_str();
|
||||||
if (FileUtils::fileExists(path.c_str()))
|
if (FileUtils::fileExists(path.c_str()))
|
||||||
|
{
|
||||||
|
LOG(Info,"Uninstalling " + path);
|
||||||
|
if(!m_dryRun)
|
||||||
{
|
{
|
||||||
FileUtils::removeFile(path.c_str());
|
FileUtils::removeFile(path.c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(Warn,"Unable to uninstall file " + path + " because it does not exist.");
|
LOG(Warn,"Unable to uninstall file " + path + " because it does not exist.");
|
||||||
@ -336,40 +349,54 @@ void UpdateInstaller::backupFile(const std::string& path)
|
|||||||
// no existing file to backup
|
// no existing file to backup
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string backupPath = path + ".bak";
|
std::string backupPath = path + ".bak";
|
||||||
|
LOG(Info,"Backing up file: " + path + " as " + backupPath);
|
||||||
|
if(!m_dryRun)
|
||||||
|
{
|
||||||
FileUtils::removeFile(backupPath.c_str());
|
FileUtils::removeFile(backupPath.c_str());
|
||||||
FileUtils::moveFile(path.c_str(), backupPath.c_str());
|
FileUtils::moveFile(path.c_str(), backupPath.c_str());
|
||||||
|
}
|
||||||
m_backups[path] = backupPath;
|
m_backups[path] = backupPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateInstaller::removeBackups()
|
void UpdateInstaller::removeBackups()
|
||||||
{
|
{
|
||||||
|
LOG(Info,"Removing backups.");
|
||||||
std::map<std::string,std::string>::const_iterator iter = m_backups.begin();
|
std::map<std::string,std::string>::const_iterator iter = m_backups.begin();
|
||||||
for (;iter != m_backups.end();iter++)
|
for (;iter != m_backups.end();iter++)
|
||||||
{
|
{
|
||||||
const std::string& backupFile = iter->second;
|
const std::string& backupFile = iter->second;
|
||||||
|
LOG(Info,"Removing " + backupFile);
|
||||||
|
if(!m_dryRun)
|
||||||
|
{
|
||||||
FileUtils::removeFile(backupFile.c_str());
|
FileUtils::removeFile(backupFile.c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UpdateInstaller::checkAccess()
|
bool UpdateInstaller::checkAccess()
|
||||||
{
|
{
|
||||||
std::string testFile = m_installDir + "/update-installer-test-file";
|
std::string testFile = m_installDir + "/update-installer-test-file";
|
||||||
|
LOG(Info,"Checking for access: " + testFile);
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if(!m_dryRun)
|
||||||
{
|
{
|
||||||
FileUtils::removeFile(testFile.c_str());
|
FileUtils::removeFile(testFile.c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (const FileUtils::IOException& error)
|
catch (const FileUtils::IOException& error)
|
||||||
{
|
{
|
||||||
LOG(Info,"Removing existing access check file failed " + std::string(error.what()));
|
LOG(Info,"Removing existing access check file failed " + std::string(error.what()));
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if(!m_dryRun)
|
||||||
{
|
{
|
||||||
FileUtils::touch(testFile.c_str());
|
FileUtils::touch(testFile.c_str());
|
||||||
FileUtils::removeFile(testFile.c_str());
|
FileUtils::removeFile(testFile.c_str());
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (const FileUtils::IOException& error)
|
catch (const FileUtils::IOException& error)
|
||||||
@ -394,8 +421,11 @@ void UpdateInstaller::restartMainApp()
|
|||||||
if (!command.empty())
|
if (!command.empty())
|
||||||
{
|
{
|
||||||
LOG(Info,"Starting main application " + command);
|
LOG(Info,"Starting main application " + command);
|
||||||
|
if(!m_dryRun)
|
||||||
|
{
|
||||||
ProcessUtils::runAsync(command,args);
|
ProcessUtils::runAsync(command,args);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(Error,"No main binary specified");
|
LOG(Error,"No main binary specified");
|
||||||
@ -415,7 +445,11 @@ void UpdateInstaller::postInstallUpdate()
|
|||||||
// touch the application's bundle directory so that
|
// touch the application's bundle directory so that
|
||||||
// OS X' Launch Services notices any changes in the application's
|
// OS X' Launch Services notices any changes in the application's
|
||||||
// Info.plist file.
|
// Info.plist file.
|
||||||
|
LOG(Info,"Touching " + m_installDir.c_str() + " to notify OSX of metadata changes.");
|
||||||
|
if(!m_dryRun)
|
||||||
|
{
|
||||||
FileUtils::touch(m_installDir.c_str());
|
FileUtils::touch(m_installDir.c_str());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,3 +458,7 @@ void UpdateInstaller::setAutoClose(bool autoClose)
|
|||||||
m_autoClose = autoClose;
|
m_autoClose = autoClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateInstaller::setDryRun(bool dryRun)
|
||||||
|
{
|
||||||
|
m_dryRun = dryRun;
|
||||||
|
}
|
||||||
|
@ -24,7 +24,6 @@ class UpdateInstaller
|
|||||||
Main
|
Main
|
||||||
};
|
};
|
||||||
|
|
||||||
UpdateInstaller();
|
|
||||||
void setInstallDir(const std::string& path);
|
void setInstallDir(const std::string& path);
|
||||||
void setPackageDir(const std::string& path);
|
void setPackageDir(const std::string& path);
|
||||||
void setBackupDir(const std::string& path);
|
void setBackupDir(const std::string& path);
|
||||||
@ -33,6 +32,7 @@ class UpdateInstaller
|
|||||||
void setWaitPid(PLATFORM_PID pid);
|
void setWaitPid(PLATFORM_PID pid);
|
||||||
void setForceElevated(bool elevated);
|
void setForceElevated(bool elevated);
|
||||||
void setAutoClose(bool autoClose);
|
void setAutoClose(bool autoClose);
|
||||||
|
void setDryRun(bool dryRun);
|
||||||
void setFinishCmd(const std::string& cmd);
|
void setFinishCmd(const std::string& cmd);
|
||||||
|
|
||||||
void setObserver(UpdateObserver* observer);
|
void setObserver(UpdateObserver* observer);
|
||||||
@ -57,16 +57,16 @@ class UpdateInstaller
|
|||||||
std::list<std::string> updaterArgs() const;
|
std::list<std::string> updaterArgs() const;
|
||||||
std::string friendlyErrorForError(const FileUtils::IOException& ex) const;
|
std::string friendlyErrorForError(const FileUtils::IOException& ex) const;
|
||||||
|
|
||||||
Mode m_mode;
|
Mode m_mode = Setup;
|
||||||
std::string m_installDir;
|
std::string m_installDir;
|
||||||
std::string m_packageDir;
|
std::string m_packageDir;
|
||||||
std::string m_backupDir;
|
std::string m_backupDir;
|
||||||
std::string m_finishCmd;
|
std::string m_finishCmd;
|
||||||
PLATFORM_PID m_waitPid;
|
PLATFORM_PID m_waitPid = 0;
|
||||||
UpdateScript* m_script;
|
UpdateScript* m_script = nullptr;
|
||||||
UpdateObserver* m_observer;
|
UpdateObserver* m_observer = nullptr;
|
||||||
std::map<std::string,std::string> m_backups;
|
std::map<std::string,std::string> m_backups;
|
||||||
bool m_forceElevated;
|
bool m_forceElevated = false;
|
||||||
bool m_autoClose;
|
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)
|
void UpdaterOptions::parse(int argc, char** argv)
|
||||||
{
|
{
|
||||||
AnyOption parser;
|
AnyOption parser;
|
||||||
@ -110,6 +45,7 @@ void UpdaterOptions::parse(int argc, char** argv)
|
|||||||
parser.setOption("mode");
|
parser.setOption("mode");
|
||||||
parser.setFlag("version");
|
parser.setFlag("version");
|
||||||
parser.setFlag("force-elevated");
|
parser.setFlag("force-elevated");
|
||||||
|
parser.setFlag("dry-run");
|
||||||
parser.setFlag("auto-close");
|
parser.setFlag("auto-close");
|
||||||
|
|
||||||
parser.processCommandArgs(argc,argv);
|
parser.processCommandArgs(argc,argv);
|
||||||
@ -141,15 +77,6 @@ void UpdaterOptions::parse(int argc, char** argv)
|
|||||||
|
|
||||||
showVersion = parser.getFlag("version");
|
showVersion = parser.getFlag("version");
|
||||||
forceElevated = parser.getFlag("force-elevated");
|
forceElevated = parser.getFlag("force-elevated");
|
||||||
|
dryRun = parser.getFlag("dry-run");
|
||||||
autoClose = parser.getFlag("auto-close");
|
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;
|
PLATFORM_PID waitPid;
|
||||||
std::string logFile;
|
std::string logFile;
|
||||||
bool showVersion;
|
bool showVersion;
|
||||||
|
bool dryRun;
|
||||||
bool forceElevated;
|
bool forceElevated;
|
||||||
bool autoClose;
|
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.setForceElevated(options.forceElevated);
|
||||||
installer.setAutoClose(options.autoClose);
|
installer.setAutoClose(options.autoClose);
|
||||||
installer.setFinishCmd(options.finishCmd);
|
installer.setFinishCmd(options.finishCmd);
|
||||||
|
installer.setDryRun(options.dryRun);
|
||||||
|
|
||||||
if (options.mode == UpdateInstaller::Main)
|
if (options.mode == UpdateInstaller::Main)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user