diff options
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | MultiMC.cpp | 95 | ||||
-rw-r--r-- | MultiMC.h | 39 | ||||
-rw-r--r-- | config.h.in | 8 | ||||
-rw-r--r-- | gui/MainWindow.cpp | 8 | ||||
-rw-r--r-- | logic/updater/DownloadUpdateTask.cpp | 50 | ||||
-rw-r--r-- | logic/updater/DownloadUpdateTask.h | 4 | ||||
-rw-r--r-- | logic/updater/UpdateChecker.cpp | 1 | ||||
-rw-r--r-- | main.cpp | 8 | ||||
-rw-r--r-- | mmc_updater/src/UpdateInstaller.cpp | 106 | ||||
-rw-r--r-- | mmc_updater/src/UpdateInstaller.h | 16 | ||||
-rw-r--r-- | mmc_updater/src/UpdateScript.h | 1 | ||||
-rw-r--r-- | mmc_updater/src/UpdaterOptions.cpp | 77 | ||||
-rw-r--r-- | mmc_updater/src/UpdaterOptions.h | 5 | ||||
-rw-r--r-- | mmc_updater/src/main.cpp | 1 |
15 files changed, 199 insertions, 223 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index ec81051e..1a9bd32c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -503,6 +503,9 @@ IF(WIN32) ) ENDIF(WIN32) +OPTION(MultiMC_UPDATER_DRY_RUN "Enable updater dry-run mode -- for updater development." OFF) +OPTION(MultiMC_UPDATER_FORCE_LOCAL "Do not download updated updater -- for updater development." OFF) + OPTION(MultiMC_CODE_COVERAGE "Compiles for code coverage" OFF) IF(MultiMC_CODE_COVERAGE) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 --coverage") diff --git a/MultiMC.cpp b/MultiMC.cpp index 9807a0c2..a13ad794 100644 --- a/MultiMC.cpp +++ b/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(); @@ -268,6 +261,7 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override) return; } */ + connect(this, SIGNAL(aboutToQuit()), SLOT(onExit())); m_status = MultiMC::Initialized; } @@ -341,7 +335,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 @@ -470,7 +464,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(); } @@ -519,46 +513,51 @@ std::shared_ptr<JavaVersionList> MultiMC::javalist() return m_javalist; } -void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish) +void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags) { + // if we are going to update on exit, save the params now + if(flags & OnExit) + { + m_updateOnExitPath = updateFilesDir; + m_updateOnExitFlags = flags & ~OnExit; + return; + } + // otherwise if there already were some params for on exit update, clear them and continue + else if(m_updateOnExitPath.size()) + { + m_updateOnExitFlags = None; + m_updateOnExitPath.clear(); + } 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()); - - if (restartOnFinish) + if(flags & DryRun) + args << "--dry-run"; + if (flags & RestartOnFinish) args << "--finish-cmd" << finishCmd; QLOG_INFO() << "Running updater with command" << updaterBinary << args.join(" "); QFile::setPermissions(updaterBinary, (QFileDevice::Permission)0x7755); - if (!QProcess::startDetached(updaterBinary, args)) + if (!QProcess::startDetached(updaterBinary, args/*, root()*/)) { QLOG_ERROR() << "Failed to start the updater process!"; return; @@ -568,14 +567,12 @@ void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish MMC->quit(); } -void MultiMC::setUpdateOnExit(const QString &updateFilesDir) +void MultiMC::onExit() { - m_updateOnExitPath = updateFilesDir; -} - -QString MultiMC::getExitUpdatePath() const -{ - return m_updateOnExitPath; + if(m_updateOnExitPath.size()) + { + installUpdates(m_updateOnExitPath, m_updateOnExitFlags); + } } bool MultiMC::openJsonEditor(const QString &filename) @@ -1,10 +1,12 @@ #pragma once +#include "config.h" #include <QApplication> #include "MultiMCVersion.h" #include <memory> #include "logger/QsLog.h" #include "logger/QsLogDest.h" +#include <QFlag> class MinecraftVersionList; class LWJGLVersionList; @@ -31,9 +33,19 @@ enum InstSortMode // Sort alphabetically by name. Sort_Name, // Sort by which instance was launched most recently. - Sort_LastLaunch, + Sort_LastLaunch }; +enum UpdateFlag +{ + None = 0x0, + RestartOnFinish = 0x1, + DryRun = 0x2, + OnExit = 0x4 +}; +Q_DECLARE_FLAGS(UpdateFlags, UpdateFlag); +Q_DECLARE_OPERATORS_FOR_FLAGS(UpdateFlags); + class MultiMC : public QApplication { Q_OBJECT @@ -42,7 +54,7 @@ public: { Failed, Succeeded, - Initialized, + Initialized }; public: @@ -109,21 +121,7 @@ public: std::shared_ptr<JavaVersionList> javalist(); - /*! - * Installs update from the given update files directory. - */ - void installUpdates(const QString &updateFilesDir, bool restartOnFinish = false); - - /*! - * Sets MultiMC to install updates from the given directory when it exits. - */ - void setUpdateOnExit(const QString &updateFilesDir); - - /*! - * Gets the path to install updates from on exit. - * If this is an empty string, no updates should be installed on exit. - */ - QString getExitUpdatePath() const; + void installUpdates(const QString updateFilesDir, UpdateFlags flags = None); /*! * Opens a json file using either a system default editor, or, if note empty, the editor @@ -154,6 +152,12 @@ public: return origcwdPath; } +private slots: + /** + * Do all the things that should be done before we exit + */ + void onExit(); + private: void initLogger(); @@ -186,6 +190,7 @@ private: QsLogging::DestinationPtr m_debugDestination; QString m_updateOnExitPath; + UpdateFlags m_updateOnExitFlags = None; QString rootPath; QString binPath; diff --git a/config.h.in b/config.h.in index 9681b825..8df1fc75 100644 --- a/config.h.in +++ b/config.h.in @@ -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,12 @@ // 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 + +// enabled for updater dry run +#cmakedefine MultiMC_UPDATER_FORCE_LOCAL + // The commit hash of this build #define GIT_COMMIT "@MultiMC_GIT_COMMIT@" diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index d1119028..968fecb7 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -595,10 +595,14 @@ void MainWindow::downloadUpdates(QString repo, int versionId, bool installOnExit // If the task succeeds, install the updates. if (updateDlg.exec(&updateTask)) { + UpdateFlags baseFlags = None; + #ifdef MultiMC_UPDATER_DRY_RUN + baseFlags |= DryRun; + #endif if (installOnExit) - MMC->setUpdateOnExit(updateTask.updateFilesDir()); + MMC->installUpdates(updateTask.updateFilesDir(), baseFlags | OnExit); else - MMC->installUpdates(updateTask.updateFilesDir(), true); + MMC->installUpdates(updateTask.updateFilesDir(), baseFlags | RestartOnFinish); } } diff --git a/logic/updater/DownloadUpdateTask.cpp b/logic/updater/DownloadUpdateTask.cpp index 029286dd..e16d2aa2 100644 --- a/logic/updater/DownloadUpdateTask.cpp +++ b/logic/updater/DownloadUpdateTask.cpp @@ -290,12 +290,11 @@ DownloadUpdateTask::processFileLists(NetJob *job, // delete anything in the current one version's list that isn't in the new version's list. for (VersionFileEntry entry : currentVersion) { - QFileInfo toDelete(entry.path); + QFileInfo toDelete(PathCombine(MMC->root(), entry.path)); if (!toDelete.exists()) { QLOG_ERROR() << "Expected file " << toDelete.absoluteFilePath() << " doesn't exist!"; - QLOG_ERROR() << "CWD: " << QDir::currentPath(); } bool keep = false; @@ -314,7 +313,6 @@ DownloadUpdateTask::processFileLists(NetJob *job, // If the loop reaches the end and we didn't find a match, delete the file. if (!keep) { - QFileInfo toDelete(entry.path); if (toDelete.exists()) ops.append(UpdateOperation::DeleteOp(entry.path)); } @@ -326,8 +324,9 @@ DownloadUpdateTask::processFileLists(NetJob *job, // TODO: Let's not MD5sum a ton of files on the GUI thread. We should probably find a // way to do this in the background. QString fileMD5; - QFile entryFile(entry.path); - QFileInfo entryInfo(entry.path); + QString realEntryPath = PathCombine(MMC->root(), entry.path); + QFile entryFile(realEntryPath); + QFileInfo entryInfo(realEntryPath); bool needs_upgrade = false; if (!entryFile.exists()) @@ -339,49 +338,52 @@ DownloadUpdateTask::processFileLists(NetJob *job, bool pass = true; if (!entryInfo.isReadable()) { - QLOG_ERROR() << "File " << entry.path << " is not readable."; + QLOG_ERROR() << "File " << realEntryPath << " is not readable."; pass = false; } if (!entryInfo.isWritable()) { - QLOG_ERROR() << "File " << entry.path << " is not writable."; + QLOG_ERROR() << "File " << realEntryPath << " is not writable."; pass = false; } if (!entryFile.open(QFile::ReadOnly)) { - QLOG_ERROR() << "File " << entry.path << " cannot be opened for reading."; + QLOG_ERROR() << "File " << realEntryPath << " cannot be opened for reading."; pass = false; } if (!pass) { - QLOG_ERROR() << "CWD: " << QDir::currentPath(); + QLOG_ERROR() << "ROOT: " << MMC->root(); ops.clear(); return false; } } - QCryptographicHash hash(QCryptographicHash::Md5); - auto foo = entryFile.readAll(); - - hash.addData(foo); - fileMD5 = hash.result().toHex(); - if ((fileMD5 != entry.md5)) + if(!needs_upgrade) { - QLOG_DEBUG() << "MD5Sum does not match!"; - QLOG_DEBUG() << "Expected:'" << entry.md5 << "'"; - QLOG_DEBUG() << "Got: '" << fileMD5 << "'"; - needs_upgrade = true; + QCryptographicHash hash(QCryptographicHash::Md5); + auto foo = entryFile.readAll(); + + hash.addData(foo); + fileMD5 = hash.result().toHex(); + if ((fileMD5 != entry.md5)) + { + QLOG_DEBUG() << "MD5Sum does not match!"; + QLOG_DEBUG() << "Expected:'" << entry.md5 << "'"; + QLOG_DEBUG() << "Got: '" << fileMD5 << "'"; + needs_upgrade = true; + } } // skip file. it doesn't need an upgrade. if (!needs_upgrade) { - QLOG_DEBUG() << "File" << entry.path << " does not need updating."; + QLOG_DEBUG() << "File" << realEntryPath << " does not need updating."; continue; } // yep. this file actually needs an upgrade. PROCEED. - QLOG_DEBUG() << "Found file" << entry.path << " that needs updating."; + QLOG_DEBUG() << "Found file" << realEntryPath << " that needs updating."; // if it's the updater we want to treat it separately bool isUpdater = entry.path.endsWith("updater") || entry.path.endsWith("updater.exe"); @@ -402,12 +404,17 @@ DownloadUpdateTask::processFileLists(NetJob *job, if (isUpdater) { +#ifdef MultiMC_UPDATER_FORCE_LOCAL + 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 +521,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 diff --git a/logic/updater/DownloadUpdateTask.h b/logic/updater/DownloadUpdateTask.h index b1d14846..4feab871 100644 --- a/logic/updater/DownloadUpdateTask.h +++ b/logic/updater/DownloadUpdateTask.h @@ -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); diff --git a/logic/updater/UpdateChecker.cpp b/logic/updater/UpdateChecker.cpp index acf74f40..489e7769 100644 --- a/logic/updater/UpdateChecker.cpp +++ b/logic/updater/UpdateChecker.cpp @@ -17,7 +17,6 @@ #include "MultiMC.h" -#include "config.h" #include "logger/QsLog.h" #include <QJsonObject> @@ -10,13 +10,7 @@ int main_gui(MultiMC &app) mainWin.show(); mainWin.checkMigrateLegacyAssets(); mainWin.checkSetDefaultJava(); - auto exitCode = app.exec(); - - // Update if necessary. - if (!app.getExitUpdatePath().isEmpty()) - app.installUpdates(app.getExitUpdatePath(), false); - - return exitCode; + return app.exec(); } int main(int argc, char *argv[]) diff --git a/mmc_updater/src/UpdateInstaller.cpp b/mmc_updater/src/UpdateInstaller.cpp index ced6ff39..aca23ff7 100644 --- a/mmc_updater/src/UpdateInstaller.cpp +++ b/mmc_updater/src/UpdateInstaller.cpp @@ -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,48 +249,62 @@ 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; + std::string absDestPath = FileUtils::makeAbsolute(destPath.c_str(), m_installDir.c_str()); + + LOG(Info,"Installing file " + sourceFile + " to " + absDestPath); // backup the existing file if any - backupFile(destPath); + backupFile(absDestPath); // create the target directory if it does not exist - std::string destDir = FileUtils::dirname(destPath.c_str()); + std::string destDir = FileUtils::dirname(absDestPath.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(),absDestPath.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(absDestPath.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(); + std::string path = FileUtils::makeAbsolute(iter->c_str(), m_installDir.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 + " 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; +} diff --git a/mmc_updater/src/UpdateInstaller.h b/mmc_updater/src/UpdateInstaller.h index 1eca0bc7..5cbac561 100644 --- a/mmc_updater/src/UpdateInstaller.h +++ b/mmc_updater/src/UpdateInstaller.h @@ -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; }; - diff --git a/mmc_updater/src/UpdateScript.h b/mmc_updater/src/UpdateScript.h index 5c863ff4..f55c7236 100644 --- a/mmc_updater/src/UpdateScript.h +++ b/mmc_updater/src/UpdateScript.h @@ -41,7 +41,6 @@ class UpdateScriptFile std::string source; /// The path to copy to. std::string dest; - std::string linkTarget; /** The permissions for this file, specified * using the standard Unix mode_t values. diff --git a/mmc_updater/src/UpdaterOptions.cpp b/mmc_updater/src/UpdaterOptions.cpp index 0945431b..5f9e97d8 100644 --- a/mmc_updater/src/UpdaterOptions.cpp +++ b/mmc_updater/src/UpdaterOptions.cpp @@ -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); - } } - - diff --git a/mmc_updater/src/UpdaterOptions.h b/mmc_updater/src/UpdaterOptions.h index b4473a82..d9104804 100644 --- a/mmc_updater/src/UpdaterOptions.h +++ b/mmc_updater/src/UpdaterOptions.h @@ -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); }; diff --git a/mmc_updater/src/main.cpp b/mmc_updater/src/main.cpp index fb072ab5..f6b31a32 100644 --- a/mmc_updater/src/main.cpp +++ b/mmc_updater/src/main.cpp @@ -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) { |