Change the syntax of the backwards-compatible update scripts.

Instead of moving the whole <update> section to an embedded <update-v3>
node, just use a different name for the <install> section since older
clients will ignore the new <packages> section.

For older clients:

 * The <install> section lists the packages to download.  This will exist
   in addition to the <packages> section.
 * The real <install> section listing the files to install is renamed to
   <install-v3>
This commit is contained in:
Robert Knight 2011-08-25 12:23:04 +01:00
parent 78b3c14260
commit da2614d427
3 changed files with 94 additions and 65 deletions

View file

@ -16,3 +16,19 @@ inline bool strToBool(const std::string& str)
{
return str == "true" || atoi(str.c_str()) != 0;
}
/** Returns @p text if non-null or a pointer
* to an empty null-terminated string otherwise.
*/
inline const char* notNullString(const char* text)
{
if (text)
{
return text;
}
else
{
return "";
}
}

View file

@ -5,6 +5,15 @@
#include "tinyxml/tinyxml.h"
std::string elementText(const TiXmlElement* element)
{
if (!element)
{
return std::string();
}
return element->GetText();
}
UpdateScript::UpdateScript()
{
}
@ -21,18 +30,7 @@ void UpdateScript::parse(const std::string& path)
LOG(Info,"Loaded script from " + path);
const TiXmlElement* updateNode = document.RootElement();
const TiXmlElement* v3UpdateNode = updateNode->FirstChildElement("update-v3");
if (v3UpdateNode)
{
// this XML file is structured for backwards compatibility
// with Mendeley Desktop <= 1.0 clients. The normal update XML contents
// are wrapped in an <update-v3> node.
parseUpdate(v3UpdateNode);
}
else
{
parseUpdate(updateNode);
}
parseUpdate(updateNode);
}
else
{
@ -47,6 +45,8 @@ bool UpdateScript::isValid() const
void UpdateScript::parseUpdate(const TiXmlElement* updateNode)
{
bool isV2Compatible = strToBool(notNullString(updateNode->Attribute("v2-compatible")));
const TiXmlElement* depsNode = updateNode->FirstChildElement("dependencies");
const TiXmlElement* depFileNode = depsNode->FirstChildElement("file");
while (depFileNode)
@ -55,7 +55,22 @@ void UpdateScript::parseUpdate(const TiXmlElement* updateNode)
depFileNode = depFileNode->NextSiblingElement("file");
}
const TiXmlElement* installNode = updateNode->FirstChildElement("install");
const char* installNodeName;
if (isV2Compatible)
{
// this update script has been generated for backwards compatibility with
// Mendeley Desktop 1.0 which downloads files specified in the <install>
// section instead of the <packages> section. The <install> section
// in this case lists the packages and the real list of files to install
// is in the <install-v3> section
installNodeName = "install-v3";
}
else
{
installNodeName = "install";
}
const TiXmlElement* installNode = updateNode->FirstChildElement(installNodeName);
if (installNode)
{
const TiXmlElement* installFileNode = installNode->FirstChildElement("file");
@ -89,15 +104,6 @@ void UpdateScript::parseUpdate(const TiXmlElement* updateNode)
}
}
std::string elementText(const TiXmlElement* element)
{
if (!element)
{
return std::string();
}
return element->GetText();
}
UpdateScriptFile UpdateScript::parseFile(const TiXmlElement* element)
{
UpdateScriptFile file;

View file

@ -1,46 +1,53 @@
<?xml version="1.0"?>
<update version="3">
<!-- Update script designed for backwards compatibility with MD <= 1.0.
The packages to download are listed as if they were ordinary files
to install in a top-level <install> section.
The standard V3 version of the update XML format is then wrapped inside
an <update-v3> element.
!-->
<update-v3>
<targetVersion>2.0</targetVersion>
<platform>Test</platform>
<dependencies>
<!-- The new updater is standalone and has no dependencies,
except for standard system libraries.
!-->
</dependencies>
<packages>
<package>
<name>app-pkg</name>
<hash>$APP_PACKAGE_HASH</hash>
<size>$APP_PACKAGE_SIZE</size>
<source>http://some/dummy/URL</source>
</package>
</packages>
<install>
<file>
<name>app</name>
<hash>$UPDATED_APP_HASH</hash>
<size>$UPDATED_APP_SIZE</size>
<permissions>30549</permissions>
<package>app-pkg</package>
<is-main-binary>true</is-main-binary>
</file>
<!-- Test symlink !-->
<file>
<name>test-dir/app-symlink</name>
<target>../app</target>
</file>
</install>
<uninstall>
<!-- TODO - List some files to uninstall here !-->
<file>file-to-uninstall.txt</file>
</uninstall>
</update-v3>
<!-- The v2-compatible attribute lets the update script parser
know that it is dealing with a script structured for backwards
compatibility with the MD <= 1.0 updater.
!-->
<update version="3" v2-compatible="true">
<targetVersion>2.0</targetVersion>
<platform>Test</platform>
<dependencies>
<!-- The new updater is standalone and has no dependencies,
except for standard system libraries and itself.
!-->
</dependencies>
<packages>
<package>
<name>app-pkg</name>
<hash>$APP_PACKAGE_HASH</hash>
<size>$APP_PACKAGE_SIZE</size>
<source>http://some/dummy/URL</source>
</package>
</packages>
<!-- For compatibility with the update download in MD <= 1.0,
an <install> section lists the packages to download and
the real list of files to install is in the <install-v3>
section. !-->
<install>
<!-- A duplicate of the <packages> section should appear here,
except that each package is listed using the same structure
as files in the install-v3/files section.
!-->
</install>
<install-v3>
<file>
<name>$APP_FILENAME</name>
<hash>$UPDATED_APP_HASH</hash>
<size>$UPDATED_APP_SIZE</size>
<permissions>30549</permissions>
<package>app-pkg</package>
<is-main-binary>true</is-main-binary>
</file>
<!-- Test symlink !-->
<file>
<name>test-dir/app-symlink</name>
<target>../app</target>
</file>
</install-v3>
<uninstall>
<!-- TODO - List some files to uninstall here !-->
<file>file-to-uninstall.txt</file>
</uninstall>
</update>