Browse Source

CPackIFW: Added support for multiple repositories

Now user can add IFW specific repo with cpack_ifw_add_repository macro
Konstantin Podsvirov 11 years ago
parent
commit
ed9684a22c

+ 92 - 3
Modules/CPackIFW.cmake

@@ -85,6 +85,19 @@
 #  The root package name, which will be used if configuration group is not
 #  specified
 #
+# .. variable:: CPACK_IFW_REPOSITORIES_ALL
+#
+#  The list of remote repositories.
+#
+#  The default value of this variable is computed by CPack and contains
+#  all repositories added with command :command:`cpack_ifw_add_repository`
+#
+# .. variable:: CPACK_IFW_DOWNLOAD_ALL
+#
+#  If this is ``ON`` all components will be downloaded.
+#  By default is ``OFF`` or used value
+#  from :variable:`CPACK_DOWNLOAD_ALL` if set
+#
 # Components
 # """"""""""
 #
@@ -185,6 +198,33 @@
 # ``LICENSES`` pair of <display_name> and <file_path> of license text for this
 # component group. You can specify more then one license.
 #
+# --------------------------------------------------------------------------
+#
+# .. command:: cpack_ifw_add_repository
+#
+# Add QtIFW_ specific remote repository.
+#
+# ::
+#
+#   cpack_ifw_add_repository(<reponame> [DISABLED]
+#                       URL <url>
+#                       [USERNAME <username>]
+#                       [PASSWORD <password>]
+#                       [DISPLAY_NAME <display_name>])
+#
+# This macro will also add the <reponame> repository
+# to a variable :variable:`CPACK_IFW_REPOSITORIES_ALL`
+#
+# ``DISABLED`` if set, then the repository will be disabled by default.
+#
+# ``URL`` is points to a list of available components.
+#
+# ``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
 # ^^^^^^^^^^^^^
 #
@@ -192,7 +232,7 @@
 #
 #    set(CPACK_PACKAGE_NAME "MyPackage")
 #    set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyPackage Installation Example")
-#    set(CPACK_PACKAGE_VERSION "1.0.0")
+#    set(CPACK_PACKAGE_VERSION "1.0.0") # Version of installer
 #
 #    include(CPack)
 #    include(CPackIFW)
@@ -201,8 +241,15 @@
 #        DISPLAY_NAME "MyApp"
 #        DESCRIPTION "My Application")
 #    cpack_ifw_configure_component(myapp
-#        VERSION "1.2.3"
+#        VERSION "1.2.3" # Version of component
 #        SCRIPT "operations.qs")
+#    cpack_add_component(mybigplugin
+#        DISPLAY_NAME "MyBigPlugin"
+#        DESCRIPTION "My Big Downloadable Plugin"
+#        DOWNLOADED)
+#    cpack_ifw_add_repository(myrepo
+#        URL "http://example.com/ifw/repo/myapp"
+#        DISPLAY_NAME "My Application Repository")
 #
 #
 # Online installer
@@ -217,8 +264,11 @@
 # Then you would use the command :command:`cpack_configure_downloads`.
 # If you set ``ALL`` option all components will be downloaded.
 #
+# You also can use command :command:`cpack_ifw_add_repository` and
+# variable :variable:`CPACK_IFW_DOWNLOAD_ALL` for more specific configuration.
+#
 # CPack IFW generator create "repository" dir in current binary dir. You
-# would copy content of this dir to specified ``site``.
+# would copy content of this dir to specified ``site`` (``url``).
 #
 # See Also
 # ^^^^^^^^
@@ -425,4 +475,43 @@ macro(cpack_ifw_configure_component_group grpname)
   endif()
 endmacro()
 
+# Macro for adding repository
+macro(cpack_ifw_add_repository reponame)
+
+  string(TOUPPER ${reponame} _CPACK_IFWREPO_UNAME)
+
+  set(_IFW_OPT DISABLED)
+  set(_IFW_ARGS 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}\"\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()
+
+  list(APPEND CPACK_IFW_REPOSITORIES_ALL ${reponame})
+  set(_CPACK_IFWREPO_STR "${_CPACK_IFWREPO_STR}list(APPEND CPACK_IFW_REPOSITORIES_ALL ${reponame})\n")
+
+  if(CPack_CMake_INCLUDED)
+    file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWREPO_STR}")
+  endif()
+
+endmacro()
+
 endif() # NOT CPackIFW_CMake_INCLUDED

+ 18 - 12
Source/CPack/IFW/cmCPackIFWGenerator.cxx

@@ -56,7 +56,7 @@ int cmCPackIFWGenerator::PackageFiles()
   ifwTmpFile += "/IFWOutput.log";
 
   // Run repogen
-  if (!DownloadSite.empty())
+  if (!Installer.Repositories.empty())
     {
     std::string ifwCmd = RepoGen;
     ifwCmd += " -c " + this->toplevel + "/config/config.xml";
@@ -128,7 +128,7 @@ int cmCPackIFWGenerator::PackageFiles()
     {
     ifwCmd += " --online-only";
     }
-  else if (!DownloadedPackages.empty() && !DownloadSite.empty())
+  else if (!DownloadedPackages.empty() && !Installer.Repositories.empty())
     {
     ifwCmd += " -e ";
     std::set<cmCPackIFWPackage*>::iterator it
@@ -278,16 +278,26 @@ int cmCPackIFWGenerator::InitializeInternal()
                                       PkgsDirsVector);
     }
 
-  // Remote repository
+  // Installer
+  Installer.Generator = this;
+  Installer.ConfigureFromOptions();
 
-  if (const char *site = this->GetOption("CPACK_DOWNLOAD_SITE"))
+  if (const char* ifwDownloadAll =
+      this->GetOption("CPACK_IFW_DOWNLOAD_ALL"))
     {
-    DownloadSite = site;
+    OnlineOnly = cmSystemTools::IsOn(ifwDownloadAll);
+    }
+  else if (const char* cpackDownloadAll =
+           this->GetOption("CPACK_DOWNLOAD_ALL"))
+    {
+    OnlineOnly = cmSystemTools::IsOn(cpackDownloadAll);
+    }
+  else
+    {
+    OnlineOnly = false;
     }
 
-  OnlineOnly = this->IsOn("CPACK_DOWNLOAD_ALL") ? true : false;
-
-  if (!DownloadSite.empty() && RepoGen.empty()) {
+  if (!Installer.Repositories.empty() && RepoGen.empty()) {
   cmCPackLogger(cmCPackLog::LOG_ERROR,
                 "Cannot find QtIFW repository generator \"repogen\": "
                 "likely it is not installed, or not in your PATH"
@@ -295,10 +305,6 @@ int cmCPackIFWGenerator::InitializeInternal()
   return 0;
   }
 
-  // Installer
-  Installer.Generator = this;
-  Installer.ConfigureFromOptions();
-
   return this->Superclass::InitializeInternal();
 }
 

+ 0 - 2
Source/CPack/IFW/cmCPackIFWGenerator.h

@@ -127,8 +127,6 @@ private:
   std::string RepoGen;
   std::string BinCreator;
 
-  std::string DownloadSite;
-
   bool OnlineOnly;
   bool ResolveDuplicateNames;
   std::vector<std::string> PkgsDirsVector;

+ 113 - 11
Source/CPack/IFW/cmCPackIFWInstaller.cxx

@@ -44,6 +44,12 @@ const char *cmCPackIFWInstaller::GetOption(const std::string &op) const
   return Generator ? Generator->GetOption(op) : 0;
 }
 
+//----------------------------------------------------------------------------
+bool cmCPackIFWInstaller::IsOn(const std::string &op) const
+{
+  return Generator ? Generator->IsOn(op) : false;
+}
+
 //----------------------------------------------------------------------------
 void cmCPackIFWInstaller::ConfigureFromOptions()
 {
@@ -167,6 +173,78 @@ 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);
+          }
+      }
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -246,19 +324,43 @@ void cmCPackIFWInstaller::GenerateInstallerFile()
          << "</AdminTargetDir>" << std::endl;
     }
 
-  // Site
-  if (!Generator->DownloadSite.empty())
+  // Remote repositories
+  if (!Repositories.empty())
     {
     xout << "    <RemoteRepositories>" << std::endl;
-    xout << "        <Repository>" << std::endl;
-    xout << "            <Url>" << Generator->DownloadSite
-         << "</Url>" << std::endl;
-    // These properties can not be set from "cpack_configure_downloads"
-    //                 <Enabled>1</Enabled>
-    //                 <Username>user</Username>
-    //                 <Password>password</Password>
-    //                 <DisplayName>Example repository</DisplayName>
-    xout << "        </Repository>" << std::endl;
+    for(std::vector<RepositoryStruct>::iterator
+        rit = Repositories.begin(); rit != Repositories.end(); ++rit)
+      {
+      xout << "        <Repository>" << std::endl;
+      // Url
+      xout << "            <Url>" << rit->Url
+           << "</Url>" << std::endl;
+      // Enabled
+      if(!rit->Enabled.empty())
+        {
+        xout << "            <Enabled>" << rit->Enabled
+             << "</Enabled>" << std::endl;
+        }
+      // Username
+      if(!rit->Username.empty())
+        {
+        xout << "            <Username>" << rit->Username
+             << "</Username>" << std::endl;
+        }
+      // Password
+      if(!rit->Password.empty())
+        {
+        xout << "            <Password>" << rit->Password
+             << "</Password>" << std::endl;
+        }
+      // DisplayName
+      if(!rit->DisplayName.empty())
+        {
+        xout << "            <DisplayName>" << rit->DisplayName
+             << "</DisplayName>" << std::endl;
+        }
+      xout << "        </Repository>" << std::endl;
+      }
     xout << "    </RemoteRepositories>" << std::endl;
     }
 

+ 11 - 0
Source/CPack/IFW/cmCPackIFWInstaller.h

@@ -27,6 +27,15 @@ 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;
+  };
+
 public: // Constructor
 
   /**
@@ -69,6 +78,7 @@ public: // Configuration
 public: // Internal implementation
 
   const char* GetOption(const std::string& op) const;
+  bool IsOn(const std::string& op) const;
 
   void ConfigureFromOptions();
 
@@ -78,6 +88,7 @@ public: // Internal implementation
 
   cmCPackIFWGenerator* Generator;
   PackagesMap Packages;
+  std::vector<RepositoryStruct> Repositories;
   std::string Directory;
 };