Mess with the updater again.
This commit is contained in:
@ -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