diff options
Diffstat (limited to 'mmc_updater')
-rw-r--r-- | mmc_updater/src/UpdateInstaller.cpp | 121 | ||||
-rw-r--r-- | mmc_updater/src/UpdateInstaller.h | 18 | ||||
-rw-r--r-- | mmc_updater/src/UpdateScript.h | 1 | ||||
-rw-r--r-- | mmc_updater/src/UpdaterOptions.cpp | 82 | ||||
-rw-r--r-- | mmc_updater/src/UpdaterOptions.h | 6 | ||||
-rw-r--r-- | mmc_updater/src/main.cpp | 5 | ||||
-rw-r--r-- | mmc_updater/src/tests/CMakeLists.txt | 1 | ||||
-rw-r--r-- | mmc_updater/src/tests/TestUpdaterOptions.cpp | 68 | ||||
-rw-r--r-- | mmc_updater/src/tests/TestUpdaterOptions.h | 8 |
9 files changed, 110 insertions, 200 deletions
diff --git a/mmc_updater/src/UpdateInstaller.cpp b/mmc_updater/src/UpdateInstaller.cpp index ced6ff39..b29c5316 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; @@ -56,6 +46,11 @@ void UpdateInstaller::setFinishCmd(const std::string& cmd) m_finishCmd = cmd; } +void UpdateInstaller::setFinishDir(const std::string &dir) +{ + m_finishDir = dir; +} + std::list<std::string> UpdateInstaller::updaterArgs() const { std::list<std::string> args; @@ -69,6 +64,15 @@ std::list<std::string> UpdateInstaller::updaterArgs() const { args.push_back("--auto-close"); } + if (m_dryRun) + { + args.push_back("--dry-run"); + } + if (m_finishDir.size()) + { + args.push_back("--dir"); + args.push_back(m_finishDir); + } return args; } @@ -255,48 +259,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 +332,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 +359,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 +402,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) @@ -393,8 +430,16 @@ void UpdateInstaller::restartMainApp() if (!command.empty()) { + if(!m_finishDir.empty()) + { + args.push_back("--dir"); + args.push_back(m_finishDir); + } LOG(Info,"Starting main application " + command); - ProcessUtils::runAsync(command,args); + if(!m_dryRun) + { + ProcessUtils::runAsync(command,args); + } } else { @@ -415,7 +460,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 +473,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..5920deec 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,7 +32,9 @@ 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 setFinishDir(const std::string& dir); void setObserver(UpdateObserver* observer); @@ -57,16 +58,17 @@ 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; + std::string m_finishDir; + 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..abc7c6d7 100644 --- a/mmc_updater/src/UpdaterOptions.cpp +++ b/mmc_updater/src/UpdaterOptions.cpp @@ -34,82 +34,19 @@ 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; parser.setOption("install-dir"); parser.setOption("package-dir"); parser.setOption("finish-cmd"); + parser.setOption("finish-dir"); parser.setOption("script"); parser.setOption("wait"); parser.setOption("mode"); parser.setFlag("version"); parser.setFlag("force-elevated"); + parser.setFlag("dry-run"); parser.setFlag("auto-close"); parser.processCommandArgs(argc,argv); @@ -138,18 +75,13 @@ void UpdaterOptions::parse(int argc, char** argv) { finishCmd = parser.getValue("finish-cmd"); } + if (parser.getValue("finish-dir")) + { + finishDir = parser.getValue("finish-dir"); + } 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..d4345490 100644 --- a/mmc_updater/src/UpdaterOptions.h +++ b/mmc_updater/src/UpdaterOptions.h @@ -15,14 +15,12 @@ class UpdaterOptions std::string packageDir; std::string scriptPath; std::string finishCmd; + std::string finishDir; 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..602c30a6 100644 --- a/mmc_updater/src/main.cpp +++ b/mmc_updater/src/main.cpp @@ -138,7 +138,8 @@ int main(int argc, char** argv) + ", wait-pid: " + intToStr(options.waitPid) + ", script-path: " + options.scriptPath + ", mode: " + intToStr(options.mode) - + ", finish-cmd: " + options.finishCmd); + + ", finish-cmd: " + options.finishCmd + + ", finish-dir: " + options.finishDir); installer.setMode(options.mode); installer.setInstallDir(options.installDir); @@ -148,6 +149,8 @@ int main(int argc, char** argv) installer.setForceElevated(options.forceElevated); installer.setAutoClose(options.autoClose); installer.setFinishCmd(options.finishCmd); + installer.setFinishDir(options.finishDir); + installer.setDryRun(options.dryRun); if (options.mode == UpdateInstaller::Main) { diff --git a/mmc_updater/src/tests/CMakeLists.txt b/mmc_updater/src/tests/CMakeLists.txt index 79402245..08501a98 100644 --- a/mmc_updater/src/tests/CMakeLists.txt +++ b/mmc_updater/src/tests/CMakeLists.txt @@ -44,5 +44,4 @@ macro(ADD_UPDATER_TEST CLASS) endmacro() add_updater_test(TestParseScript) -add_updater_test(TestUpdaterOptions) add_updater_test(TestFileUtils) diff --git a/mmc_updater/src/tests/TestUpdaterOptions.cpp b/mmc_updater/src/tests/TestUpdaterOptions.cpp deleted file mode 100644 index a4cb7d33..00000000 --- a/mmc_updater/src/tests/TestUpdaterOptions.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "TestUpdaterOptions.h" - -#include "FileUtils.h" -#include "Platform.h" -#include "TestUtils.h" -#include "UpdaterOptions.h" - -#include <string.h> -#include <stdlib.h> - -void TestUpdaterOptions::testOldFormatArgs() -{ - const int argc = 6; - char* argv[argc]; - argv[0] = strdup("updater"); - - std::string currentDir("CurrentDir="); - const char* appDir = 0; - - // CurrentDir is the path to the directory containing the main - // Mendeley Desktop binary, on Linux and Mac this differs from - // the root of the install directory -#ifdef PLATFORM_LINUX - appDir = "/tmp/path-to-app/lib/mendeleydesktop/libexec/"; - FileUtils::mkpath(appDir); -#elif defined(PLATFORM_MAC) - appDir = "/tmp/path-to-app/Contents/MacOS/"; - FileUtils::mkpath(appDir); -#elif defined(PLATFORM_WINDOWS) - appDir = "C:/path/to/app/"; -#endif - currentDir += appDir; - - argv[1] = strdup(currentDir.c_str()); - argv[2] = strdup("TempDir=/tmp/updater"); - argv[3] = strdup("UpdateScriptFileName=/tmp/updater/file_list.xml"); - argv[4] = strdup("AppFileName=/path/to/app/theapp"); - argv[5] = strdup("PID=123456"); - - UpdaterOptions options; - options.parse(argc,argv); - - TEST_COMPARE(options.mode,UpdateInstaller::Setup); -#ifdef PLATFORM_LINUX - TEST_COMPARE(options.installDir,"/tmp/path-to-app"); -#elif defined(PLATFORM_MAC) - // /tmp is a symlink to /private/tmp on Mac - TEST_COMPARE(options.installDir,"/private/tmp/path-to-app"); -#else - TEST_COMPARE(options.installDir,"C:/path/to/app/"); -#endif - TEST_COMPARE(options.packageDir,"/tmp/updater"); - TEST_COMPARE(options.scriptPath,"/tmp/updater/file_list.xml"); - TEST_COMPARE(options.waitPid,123456); - - for (int i=0; i < argc; i++) - { - free(argv[i]); - } -} - -int main(int,char**) -{ - TestList<TestUpdaterOptions> tests; - tests.addTest(&TestUpdaterOptions::testOldFormatArgs); - return TestUtils::runTest(tests); -} - diff --git a/mmc_updater/src/tests/TestUpdaterOptions.h b/mmc_updater/src/tests/TestUpdaterOptions.h deleted file mode 100644 index 5ed102c1..00000000 --- a/mmc_updater/src/tests/TestUpdaterOptions.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -class TestUpdaterOptions -{ - public: - void testOldFormatArgs(); -}; - |