summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Podsvirov <konstantin@podsvirov.pro>2016-05-17 17:00:29 +0300
committerBrad King <brad.king@kitware.com>2016-05-18 09:49:14 -0400
commit41199f8c1ea02bacb516ae8bd57d9c9e1d3fd4ee (patch)
tree07b7d562e9896dc36de8a79dffb5a80290b560ab
parent6ca6b0dd7b1f4bb7429cbe039101558c58f3ea27 (diff)
downloadcmake-41199f8c1ea02bacb516ae8bd57d9c9e1d3fd4ee.tar.gz
CPackIFW: Add support for Promoting Updates
Add support for this feature added by QtIFW 2.0.3: http://doc.qt.io/qtinstallerframework/ifw-updates.html Add a `cpack_ifw_update_repository` command as porcelain.
-rw-r--r--Help/release/dev/cpack-ifw-updates.rst6
-rw-r--r--Modules/CPackIFW.cmake83
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx62
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.h9
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.cxx78
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.h13
-rw-r--r--Source/CPack/IFW/cmCPackIFWRepository.cxx341
-rw-r--r--Source/CPack/IFW/cmCPackIFWRepository.h105
9 files changed, 607 insertions, 91 deletions
diff --git a/Help/release/dev/cpack-ifw-updates.rst b/Help/release/dev/cpack-ifw-updates.rst
new file mode 100644
index 0000000000..868f46cfe2
--- /dev/null
+++ b/Help/release/dev/cpack-ifw-updates.rst
@@ -0,0 +1,6 @@
+cpack-ifw-updates
+-----------------
+
+* The :module:`CPackIFW` module gained a new
+ :command:`cpack_ifw_update_repository` command to update a QtIFW-specific
+ repository from a remote repository.
diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake
index c089347198..4cfc9d231b 100644
--- a/Modules/CPackIFW.cmake
+++ b/Modules/CPackIFW.cmake
@@ -134,6 +134,7 @@
#
# The default value of this variable is computed by CPack and contains
# all repositories added with command :command:`cpack_ifw_add_repository`
+# or updated with command :command:`cpack_ifw_update_repository`.
#
# .. variable:: CPACK_IFW_DOWNLOAD_ALL
#
@@ -249,7 +250,7 @@
#
# .. command:: cpack_ifw_add_repository
#
-# Add QtIFW_ specific remote repository.
+# Add QtIFW_ specific remote repository to binary installer.
#
# ::
#
@@ -272,6 +273,38 @@
#
# ``DISPLAY_NAME`` is string to display instead of the URL.
#
+#
+# --------------------------------------------------------------------------
+#
+# .. command:: cpack_ifw_update_repository
+#
+# Update QtIFW_ specific repository from remote repository.
+#
+# ::
+#
+# cpack_ifw_update_repository(<reponame>
+# [[ADD|REMOVE] URL <url>]|
+# [REPLACE OLD_URL <old_url> NEW_URL <new_url>]]
+# [USERNAME <username>]
+# [PASSWORD <password>]
+# [DISPLAY_NAME <display_name>])
+#
+# Specified will
+# This macro will also add the repository action
+# to a variable :variable:`CPACK_IFW_REPOSITORIES_ALL`
+#
+# ``URL`` is points to a list of available components.
+#
+# ``OLD_URL`` is points to a list that will replaced.
+#
+# ``NEW_URL`` is points to a list that will replace to.
+#
+# ``USERNAME`` is used as user on a protected repository.
+#
+# ``PASSWORD`` is password to use on a protected repository.
+#
+# ``DISPLAY_NAME`` is string to display instead of the URL.
+#
# Example usage
# ^^^^^^^^^^^^^
#
@@ -331,6 +364,9 @@
# Predefined Variables
# http://doc.qt.io/qtinstallerframework/scripting.html#predefined-variables
#
+# Promoting Updates
+# http://doc.qt.io/qtinstallerframework/ifw-updates.html
+#
# Download Qt Installer Framework for you platform from Qt site:
# http://download.qt.io/official_releases/qt-installer-framework
#
@@ -610,6 +646,51 @@ macro(cpack_ifw_add_repository reponame)
endmacro()
+# Macro for updating repository
+macro(cpack_ifw_update_repository reponame)
+
+ string(TOUPPER ${reponame} _CPACK_IFWREPO_UNAME)
+
+ set(_IFW_OPT ADD REMOVE REPLACE DISABLED)
+ set(_IFW_ARGS URL OLD_URL NEW_URL USERNAME PASSWORD DISPLAY_NAME)
+ set(_IFW_MULTI_ARGS)
+ cmake_parse_arguments(CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
+
+ set(_CPACK_IFWREPO_STR "\n# Configuration for IFW repository \"${reponame}\" update\n")
+
+ foreach(_IFW_ARG_NAME ${_IFW_OPT})
+ cpack_append_option_set_command(
+ CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWREPO_STR)
+ endforeach()
+
+ foreach(_IFW_ARG_NAME ${_IFW_ARGS})
+ cpack_append_string_variable_set_command(
+ CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWREPO_STR)
+ endforeach()
+
+ foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS})
+ cpack_append_variable_set_command(
+ CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWREPO_STR)
+ endforeach()
+
+ if(CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_ADD
+ OR CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_REMOVE
+ OR CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_REPLACE)
+ list(APPEND CPACK_IFW_REPOSITORIES_ALL ${reponame})
+ set(_CPACK_IFWREPO_STR "${_CPACK_IFWREPO_STR}list(APPEND CPACK_IFW_REPOSITORIES_ALL ${reponame})\n")
+ else()
+ set(_CPACK_IFWREPO_STR)
+ endif()
+
+ if(CPack_CMake_INCLUDED AND _CPACK_IFWREPO_STR)
+ file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWREPO_STR}")
+ endif()
+
+endmacro()
+
# Resolve package control script
_cpack_ifw_resolve_script(CPACK_IFW_PACKAGE_CONTROL_SCRIPT)
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 467b6926db..3223831f0f 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -662,6 +662,7 @@ set(CPACK_SRCS
CPack/cmCPackNSISGenerator.cxx
CPack/IFW/cmCPackIFWPackage.cxx
CPack/IFW/cmCPackIFWInstaller.cxx
+ CPack/IFW/cmCPackIFWRepository.cxx
CPack/IFW/cmCPackIFWGenerator.cxx
CPack/cmCPackSTGZGenerator.cxx
CPack/cmCPackTGZGenerator.cxx
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 2c25f43a29..c1ff526cf4 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -12,9 +12,6 @@
#include "cmCPackIFWGenerator.h"
-#include "cmCPackIFWInstaller.h"
-#include "cmCPackIFWPackage.h"
-
#include <CPack/cmCPackComponentGroup.h>
#include <CPack/cmCPackLog.h>
@@ -72,7 +69,7 @@ int cmCPackIFWGenerator::PackageFiles()
ifwTmpFile += "/IFWOutput.log";
// Run repogen
- if (!Installer.Repositories.empty()) {
+ if (!Installer.RemoteRepositories.empty()) {
std::string ifwCmd = RepoGen;
if (IsVersionLess("2.0.0")) {
@@ -117,6 +114,14 @@ int cmCPackIFWGenerator::PackageFiles()
<< std::endl);
return 0;
}
+
+ if (!Repository.RepositoryUpdate.empty() &&
+ !Repository.PatchUpdatesXml()) {
+ cmCPackLogger(cmCPackLog::LOG_WARNING, "Problem patch IFW \"Updates\" "
+ << "file: " << this->toplevel + "/repository/Updates.xml"
+ << std::endl);
+ }
+
cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- repository: "
<< this->toplevel << "/repository generated" << std::endl);
}
@@ -137,7 +142,7 @@ int cmCPackIFWGenerator::PackageFiles()
if (OnlineOnly) {
ifwCmd += " --online-only";
} else if (!DownloadedPackages.empty() &&
- !Installer.Repositories.empty()) {
+ !Installer.RemoteRepositories.empty()) {
ifwCmd += " -e ";
std::set<cmCPackIFWPackage*>::iterator it = DownloadedPackages.begin();
ifwCmd += (*it)->Name;
@@ -272,6 +277,24 @@ int cmCPackIFWGenerator::InitializeInternal()
Installer.Generator = this;
Installer.ConfigureFromOptions();
+ // Repository
+ Repository.Generator = this;
+ Repository.Name = "Unspecified";
+ if (const char* site = this->GetOption("CPACK_DOWNLOAD_SITE")) {
+ Repository.Url = site;
+ Installer.RemoteRepositories.push_back(&Repository);
+ }
+
+ // Repositories
+ if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) {
+ std::vector<std::string> RepoAllVector;
+ cmSystemTools::ExpandListArgument(RepoAllStr, RepoAllVector);
+ for (std::vector<std::string>::iterator rit = RepoAllVector.begin();
+ rit != RepoAllVector.end(); ++rit) {
+ GetRepository(*rit);
+ }
+ }
+
if (const char* ifwDownloadAll = this->GetOption("CPACK_IFW_DOWNLOAD_ALL")) {
OnlineOnly = cmSystemTools::IsOn(ifwDownloadAll);
} else if (const char* cpackDownloadAll =
@@ -281,7 +304,7 @@ int cmCPackIFWGenerator::InitializeInternal()
OnlineOnly = false;
}
- if (!Installer.Repositories.empty() && RepoGen.empty()) {
+ if (!Installer.RemoteRepositories.empty() && RepoGen.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Cannot find QtIFW repository generator \"repogen\": "
"likely it is not installed, or not in your PATH"
@@ -507,6 +530,33 @@ cmCPackIFWPackage* cmCPackIFWGenerator::GetComponentPackage(
return pit != ComponentPackages.end() ? pit->second : 0;
}
+cmCPackIFWRepository* cmCPackIFWGenerator::GetRepository(
+ const std::string& repositoryName)
+{
+ RepositoriesMap::iterator rit = Repositories.find(repositoryName);
+ if (rit != Repositories.end())
+ return &(rit->second);
+
+ cmCPackIFWRepository* repository = &Repositories[repositoryName];
+ repository->Name = repositoryName;
+ repository->Generator = this;
+ if (repository->ConfigureFromOptions()) {
+ if (repository->Update == cmCPackIFWRepository::None) {
+ Installer.RemoteRepositories.push_back(repository);
+ } else {
+ Repository.RepositoryUpdate.push_back(repository);
+ }
+ } else {
+ Repositories.erase(repositoryName);
+ repository = 0;
+ cmCPackLogger(cmCPackLog::LOG_WARNING, "Invalid repository \""
+ << repositoryName << "\""
+ << " configuration. Repository will be skipped."
+ << std::endl);
+ }
+ return repository;
+}
+
void cmCPackIFWGenerator::WriteGeneratedByToStrim(cmXMLWriter& xout)
{
std::stringstream comment;
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.h b/Source/CPack/IFW/cmCPackIFWGenerator.h
index d8cc562f93..2b35749d50 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.h
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.h
@@ -17,6 +17,7 @@
#include "cmCPackIFWInstaller.h"
#include "cmCPackIFWPackage.h"
+#include "cmCPackIFWRepository.h"
class cmXMLWriter;
@@ -31,6 +32,7 @@ public:
cmCPackTypeMacro(cmCPackIFWGenerator, cmCPackGenerator);
typedef std::map<std::string, cmCPackIFWPackage> PackagesMap;
+ typedef std::map<std::string, cmCPackIFWRepository> RepositoriesMap;
typedef std::map<std::string, cmCPackComponent> ComponentsMap;
typedef std::map<std::string, cmCPackComponentGroup> ComponentGoupsMap;
typedef std::map<std::string, cmCPackIFWPackage::DependenceStruct>
@@ -122,6 +124,8 @@ protected:
cmCPackIFWPackage* GetGroupPackage(cmCPackComponentGroup* group) const;
cmCPackIFWPackage* GetComponentPackage(cmCPackComponent* component) const;
+ cmCPackIFWRepository* GetRepository(const std::string& repositoryName);
+
void WriteGeneratedByToStrim(cmXMLWriter& xout);
protected:
@@ -129,11 +133,16 @@ protected:
friend class cmCPackIFWPackage;
friend class cmCPackIFWInstaller;
+ friend class cmCPackIFWRepository;
// Installer
cmCPackIFWInstaller Installer;
+ // Repository
+ cmCPackIFWRepository Repository;
// Collection of packages
PackagesMap Packages;
+ // Collection of repositories
+ RepositoriesMap Repositories;
// Collection of binary packages
std::set<cmCPackIFWPackage*> BinaryPackages;
// Collection of downloaded packages
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
index b9a98615b9..dfc509bc62 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
@@ -159,57 +159,6 @@ void cmCPackIFWInstaller::ConfigureFromOptions()
AdminTargetDir = option;
}
- // Repositories
- Repositories.clear();
- RepositoryStruct Repo;
- if (const char* site = this->GetOption("CPACK_DOWNLOAD_SITE")) {
- Repo.Url = site;
- Repositories.push_back(Repo);
- }
- if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) {
- std::vector<std::string> RepoAllVector;
- cmSystemTools::ExpandListArgument(RepoAllStr, RepoAllVector);
- for (std::vector<std::string>::iterator rit = RepoAllVector.begin();
- rit != RepoAllVector.end(); ++rit) {
- std::string prefix =
- "CPACK_IFW_REPOSITORY_" + cmsys::SystemTools::UpperCase(*rit) + "_";
- // Url
- if (const char* url = GetOption(prefix + "URL")) {
- Repo.Url = url;
- } else {
- Repo.Url = "";
- }
- // Enabled
- if (IsOn(prefix + "DISABLED")) {
- Repo.Enabled = "0";
- } else {
- Repo.Enabled = "";
- }
- // Username
- if (const char* username = GetOption(prefix + "USERNAME")) {
- Repo.Username = username;
- } else {
- Repo.Username = "";
- }
- // Password
- if (const char* password = GetOption(prefix + "PASSWORD")) {
- Repo.Password = password;
- } else {
- Repo.Password = "";
- }
- // DisplayName
- if (const char* displayName = GetOption(prefix + "DISPLAY_NAME")) {
- Repo.DisplayName = displayName;
- } else {
- Repo.DisplayName = "";
- }
-
- if (!Repo.Url.empty()) {
- Repositories.push_back(Repo);
- }
- }
- }
-
// Maintenance tool
if (const char* optIFW_MAINTENANCE_TOOL =
this->GetOption("CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME")) {
@@ -320,30 +269,11 @@ void cmCPackIFWInstaller::GenerateInstallerFile()
}
// Remote repositories
- if (!Repositories.empty()) {
+ if (!RemoteRepositories.empty()) {
xout.StartElement("RemoteRepositories");
- for (std::vector<RepositoryStruct>::iterator rit = Repositories.begin();
- rit != Repositories.end(); ++rit) {
- xout.StartElement("Repository");
- // Url
- xout.Element("Url", rit->Url);
- // Enabled
- if (!rit->Enabled.empty()) {
- xout.Element("Enabled", rit->Enabled);
- }
- // Username
- if (!rit->Username.empty()) {
- xout.Element("Username", rit->Username);
- }
- // Password
- if (!rit->Password.empty()) {
- xout.Element("Password", rit->Password);
- }
- // DisplayName
- if (!rit->DisplayName.empty()) {
- xout.Element("DisplayName", rit->DisplayName);
- }
- xout.EndElement();
+ for (RepositoriesVector::iterator rit = RemoteRepositories.begin();
+ rit != RemoteRepositories.end(); ++rit) {
+ (*rit)->WriteRepositoryConfig(xout);
}
xout.EndElement();
}
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.h b/Source/CPack/IFW/cmCPackIFWInstaller.h
index 84a789e2d5..3170116b1a 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.h
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.h
@@ -17,6 +17,7 @@
class cmCPackIFWPackage;
class cmCPackIFWGenerator;
+class cmCPackIFWRepository;
class cmXMLWriter;
/** \class cmCPackIFWInstaller
@@ -28,15 +29,7 @@ public:
// Types
typedef std::map<std::string, cmCPackIFWPackage*> PackagesMap;
-
- struct RepositoryStruct
- {
- std::string Url;
- std::string Enabled;
- std::string Username;
- std::string Password;
- std::string DisplayName;
- };
+ typedef std::vector<cmCPackIFWRepository*> RepositoriesVector;
public:
// Constructor
@@ -115,7 +108,7 @@ public:
cmCPackIFWGenerator* Generator;
PackagesMap Packages;
- std::vector<RepositoryStruct> Repositories;
+ RepositoriesVector RemoteRepositories;
std::string Directory;
protected:
diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx
new file mode 100644
index 0000000000..b149f81430
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx
@@ -0,0 +1,341 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPackIFWRepository.h"
+
+#include "cmCPackIFWGenerator.h"
+
+#include <CPack/cmCPackLog.h>
+
+#include <cmGeneratedFileStream.h>
+#include <cmXMLParser.h>
+#include <cmXMLWriter.h>
+
+#ifdef cmCPackLogger
+#undef cmCPackLogger
+#endif
+#define cmCPackLogger(logType, msg) \
+ do { \
+ std::ostringstream cmCPackLog_msg; \
+ cmCPackLog_msg << msg; \
+ if (Generator) { \
+ Generator->Logger->Log(logType, __FILE__, __LINE__, \
+ cmCPackLog_msg.str().c_str()); \
+ } \
+ } while (0)
+
+cmCPackIFWRepository::cmCPackIFWRepository()
+ : Update(None)
+ , Generator(0)
+{
+}
+
+bool cmCPackIFWRepository::IsValid() const
+{
+ bool valid = true;
+
+ switch (Update) {
+ case None:
+ valid = Url.empty() ? false : true;
+ break;
+ case Add:
+ valid = Url.empty() ? false : true;
+ break;
+ case Remove:
+ valid = Url.empty() ? false : true;
+ break;
+ case Replace:
+ valid = (OldUrl.empty() || NewUrl.empty()) ? false : true;
+ break;
+ }
+
+ return valid;
+}
+
+const char* cmCPackIFWRepository::GetOption(const std::string& op) const
+{
+ return Generator ? Generator->GetOption(op) : 0;
+}
+
+bool cmCPackIFWRepository::IsOn(const std::string& op) const
+{
+ return Generator ? Generator->IsOn(op) : false;
+}
+
+bool cmCPackIFWRepository::IsVersionLess(const char* version)
+{
+ return Generator ? Generator->IsVersionLess(version) : false;
+}
+
+bool cmCPackIFWRepository::IsVersionGreater(const char* version)
+{
+ return Generator ? Generator->IsVersionGreater(version) : false;
+}
+
+bool cmCPackIFWRepository::IsVersionEqual(const char* version)
+{
+ return Generator ? Generator->IsVersionEqual(version) : false;
+}
+
+bool cmCPackIFWRepository::ConfigureFromOptions()
+{
+ // Name;
+ if (Name.empty())
+ return false;
+
+ std::string prefix =
+ "CPACK_IFW_REPOSITORY_" + cmsys::SystemTools::UpperCase(Name) + "_";
+
+ // Update
+ if (IsOn(prefix + "ADD")) {
+ Update = Add;
+ } else if (IsOn(prefix + "REMOVE")) {
+ Update = Remove;
+ } else if (IsOn(prefix + "REPLACE")) {
+ Update = Replace;
+ } else {
+ Update = None;
+ }
+
+ // Url
+ if (const char* url = GetOption(prefix + "URL")) {
+ Url = url;
+ } else {
+ Url = "";
+ }
+
+ // Old url
+ if (const char* oldUrl = GetOption(prefix + "OLD_URL")) {
+ OldUrl = oldUrl;
+ } else {
+ OldUrl = "";
+ }
+
+ // New url
+ if (const char* newUrl = GetOption(prefix + "NEW_URL")) {
+ NewUrl = newUrl;
+ } else {
+ NewUrl = "";
+ }
+
+ // Enabled
+ if (IsOn(prefix + "DISABLED")) {
+ Enabled = "0";
+ } else {
+ Enabled = "";
+ }
+
+ // Username
+ if (const char* username = GetOption(prefix + "USERNAME")) {
+ Username = username;
+ } else {
+ Username = "";
+ }
+
+ // Password
+ if (const char* password = GetOption(prefix + "PASSWORD")) {
+ Password = password;
+ } else {
+ Password = "";
+ }
+
+ // DisplayName
+ if (const char* displayName = GetOption(prefix + "DISPLAY_NAME")) {
+ DisplayName = displayName;
+ } else {
+ DisplayName = "";
+ }
+
+ return IsValid();
+}
+
+/** \class cmCPackeIFWUpdatesPatcher
+ * \brief Helper class that parses and patch Updates.xml file (QtIFW)
+ */
+class cmCPackeIFWUpdatesPatcher : public cmXMLParser
+{
+public:
+ cmCPackeIFWUpdatesPatcher(cmCPackIFWRepository* r, cmXMLWriter& x)
+ : repository(r)
+ , xout(x)
+ , patched(false)
+ {
+ }
+
+ cmCPackIFWRepository* repository;
+ cmXMLWriter& xout;
+ bool patched;
+
+protected:
+ virtual void StartElement(const std::string& name, const char** atts)
+ {
+ xout.StartElement(name);
+ StartFragment(atts);
+ }
+
+ void StartFragment(const char** atts)
+ {
+ for (size_t i = 0; atts[i]; i += 2) {
+ const char* key = atts[i];
+ const char* value = atts[i + 1];
+ xout.Attribute(key, value);
+ }
+ }
+
+ virtual void EndElement(const std::string& name)
+ {
+ if (name == "Updates" && !patched) {
+ repository->WriteRepositoryUpdates(xout);
+ patched = true;
+ }
+ xout.EndElement();
+ if (patched)
+ return;
+ if (name == "Checksum") {
+ repository->WriteRepositoryUpdates(xout);
+ patched = true;
+ }
+ }
+
+ virtual void CharacterDataHandler(const char* data, int length)
+ {
+ std::string content(data, data + length);
+ if (content == "" || content == " " || content == " " || content == "\n")
+ return;
+ xout.Content(content);
+ }
+};
+
+bool cmCPackIFWRepository::PatchUpdatesXml()
+{
+ // Lazy directory initialization
+ if (Directory.empty() && Generator) {
+ Directory = Generator->toplevel;
+ }
+
+ // Filenames
+ std::string updatesXml = Directory + "/repository/Updates.xml";
+ std::string updatesPatchXml = Directory + "/repository/UpdatesPatch.xml";
+
+ // Output stream
+ cmGeneratedFileStream fout(updatesPatchXml.data());
+ cmXMLWriter xout(fout);
+
+ xout.StartDocument();
+
+ WriteGeneratedByToStrim(xout);
+
+ // Patch
+ {
+ cmCPackeIFWUpdatesPatcher patcher(this, xout);
+ patcher.ParseFile(updatesXml.data());
+ }
+
+ xout.EndDocument();
+
+ fout.Close();
+
+ if (!cmSystemTools::RenameFile(updatesPatchXml.data(), updatesXml.data())) {
+ return false;
+ }
+
+ return true;
+}
+
+void cmCPackIFWRepository::WriteRepositoryConfig(cmXMLWriter& xout)
+{
+ xout.StartElement("Repository");
+
+ // Url
+ xout.Element("Url", Url);
+ // Enabled
+ if (!Enabled.empty()) {
+ xout.Element("Enabled", Enabled);
+ }
+ // Username
+ if (!Username.empty()) {
+ xout.Element("Username", Username);
+ }
+ // Password
+ if (!Password.empty()) {
+ xout.Element("Password", Password);
+ }
+ // DisplayName
+ if (!DisplayName.empty()) {
+ xout.Element("DisplayName", DisplayName);
+ }
+
+ xout.EndElement();
+}
+
+void cmCPackIFWRepository::WriteRepositoryUpdate(cmXMLWriter& xout)
+{
+ xout.StartElement("Repository");
+
+ switch (Update) {
+ case None:
+ break;
+ case Add:
+ xout.Attribute("action", "add");
+ break;
+ case Remove:
+ xout.Attribute("action", "remove");
+ break;
+ case Replace:
+ xout.Attribute("action", "replace");
+ break;
+ }
+
+ // Url
+ if (Update == Add || Update == Remove) {
+ xout.Attribute("url", Url);
+ } else if (Update == Replace) {
+ xout.Attribute("oldurl", OldUrl);
+ xout.Attribute("newurl", NewUrl);
+ }
+ // Enabled
+ if (!Enabled.empty()) {
+ xout.Attribute("enabled", Enabled);
+ }
+ // Username
+ if (!Username.empty()) {
+ xout.Attribute("username", Username);
+ }
+ // Password
+ if (!Password.empty()) {
+ xout.Attribute("password", Password);
+ }
+ // DisplayName
+ if (!DisplayName.empty()) {
+ xout.Attribute("displayname", DisplayName);
+ }
+
+ xout.EndElement();
+}
+
+void cmCPackIFWRepository::WriteRepositoryUpdates(cmXMLWriter& xout)
+{
+ if (!RepositoryUpdate.empty()) {
+ xout.StartElement("RepositoryUpdate");
+ for (RepositoriesVector::iterator rit = RepositoryUpdate.begin();
+ rit != RepositoryUpdate.end(); ++rit) {
+ (*rit)->WriteRepositoryUpdate(xout);
+ }
+ xout.EndElement();
+ }
+}
+
+void cmCPackIFWRepository::WriteGeneratedByToStrim(cmXMLWriter& xout)
+{
+ if (Generator)
+ Generator->WriteGeneratedByToStrim(xout);
+}
diff --git a/Source/CPack/IFW/cmCPackIFWRepository.h b/Source/CPack/IFW/cmCPackIFWRepository.h
new file mode 100644
index 0000000000..5ffb775af7
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWRepository.h
@@ -0,0 +1,105 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackIFWRepository_h
+#define cmCPackIFWRepository_h
+
+#include <cmStandardIncludes.h>
+
+class cmCPackIFWGenerator;
+class cmXMLWriter;
+
+/** \class cmCPackIFWRepository
+ * \brief A remote repository to be created CPack IFW generator
+ */
+class cmCPackIFWRepository
+{
+public:
+ // Types
+
+ enum Action
+ {
+ None,
+ Add,
+ Remove,
+ Replace
+ };
+
+ typedef std::vector<cmCPackIFWRepository*> RepositoriesVector;
+
+public:
+ // Constructor
+
+ /**
+ * Construct repository
+ */
+ cmCPackIFWRepository();
+
+public:
+ // Configuration
+
+ /// Internal repository name
+ std::string Name;
+
+ /// Optional update action
+ Action Update;
+
+ /// Is points to a list of available components
+ std::string Url;
+
+ /// Is points to a list that will replaced
+ std::string OldUrl;
+
+ /// Is points to a list that will replace to
+ std::string NewUrl;
+
+ /// With "0" disabling this repository
+ std::string Enabled;
+
+ /// Is used as user on a protected repository
+ std::string Username;
+
+ /// Is password to use on a protected repository
+ std::string Password;
+
+ /// Is optional string to display instead of the URL
+ std::string DisplayName;
+
+public:
+ // Internal implementation
+
+ bool IsValid() const;
+
+ const char* GetOption(const std::string& op) const;
+ bool IsOn(const std::string& op) const;
+
+ bool IsVersionLess(const char* version);
+ bool IsVersionGreater(const char* version);
+ bool IsVersionEqual(const char* version);
+
+ bool ConfigureFromOptions();
+
+ bool PatchUpdatesXml();
+
+ void WriteRepositoryConfig(cmXMLWriter& xout);
+ void WriteRepositoryUpdate(cmXMLWriter& xout);
+ void WriteRepositoryUpdates(cmXMLWriter& xout);
+
+ cmCPackIFWGenerator* Generator;
+ RepositoriesVector RepositoryUpdate;
+ std::string Directory;
+
+protected:
+ void WriteGeneratedByToStrim(cmXMLWriter& xout);
+};
+
+#endif // cmCPackIFWRepository_h