diff options
author | Konstantin Podsvirov <konstantin@podsvirov.pro> | 2016-05-17 14:00:29 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2016-05-18 13:49:14 (GMT) |
commit | 41199f8c1ea02bacb516ae8bd57d9c9e1d3fd4ee (patch) | |
tree | 07b7d562e9896dc36de8a79dffb5a80290b560ab /Source/CPack | |
parent | 6ca6b0dd7b1f4bb7429cbe039101558c58f3ea27 (diff) | |
download | CMake-41199f8c1ea02bacb516ae8bd57d9c9e1d3fd4ee.zip CMake-41199f8c1ea02bacb516ae8bd57d9c9e1d3fd4ee.tar.gz CMake-41199f8c1ea02bacb516ae8bd57d9c9e1d3fd4ee.tar.bz2 |
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.
Diffstat (limited to 'Source/CPack')
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWGenerator.cxx | 62 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWGenerator.h | 9 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWInstaller.cxx | 78 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWInstaller.h | 13 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWRepository.cxx | 341 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWRepository.h | 105 |
6 files changed, 518 insertions, 90 deletions
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx index 2c25f43..c1ff526 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 d8cc562..2b35749 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 b9a9861..dfc509b 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 84a789e..3170116 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 0000000..b149f81 --- /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 0000000..5ffb775 --- /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 |