summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx5
-rw-r--r--Source/CPack/cmCPackNuGetGenerator.cxx140
-rw-r--r--Source/CPack/cmCPackNuGetGenerator.h37
4 files changed, 183 insertions, 0 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index d9e07e5b3e..316d50b4cb 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -886,6 +886,7 @@ set(CPACK_SRCS
CPack/cmCPackGenerator.cxx
CPack/cmCPackLog.cxx
CPack/cmCPackNSISGenerator.cxx
+ CPack/cmCPackNuGetGenerator.cxx
CPack/cmCPackSTGZGenerator.cxx
CPack/cmCPackTGZGenerator.cxx
CPack/cmCPackTXZGenerator.cxx
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index 47e7527072..a395a8f8d5 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -15,6 +15,7 @@
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmCPackNSISGenerator.h"
+#include "cmCPackNuGetGenerator.h"
#include "cmCPackSTGZGenerator.h"
#include "cmCPackTGZGenerator.h"
#include "cmCPackTXZGenerator.h"
@@ -105,6 +106,10 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("DEB", "Debian packages",
cmCPackDebGenerator::CreateGenerator);
}
+ if (cmCPackNuGetGenerator::CanGenerate()) {
+ this->RegisterGenerator("NuGet", "NuGet packages",
+ cmCPackNuGetGenerator::CreateGenerator);
+ }
#ifdef __APPLE__
if (cmCPackDragNDropGenerator::CanGenerate()) {
this->RegisterGenerator("DragNDrop", "Mac OSX Drag And Drop",
diff --git a/Source/CPack/cmCPackNuGetGenerator.cxx b/Source/CPack/cmCPackNuGetGenerator.cxx
new file mode 100644
index 0000000000..2ebfb3db03
--- /dev/null
+++ b/Source/CPack/cmCPackNuGetGenerator.cxx
@@ -0,0 +1,140 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCPackNuGetGenerator.h"
+
+#include "cmAlgorithms.h"
+#include "cmCPackComponentGroup.h"
+#include "cmCPackLog.h"
+#include "cmSystemTools.h"
+
+#include <algorithm>
+#include <iterator>
+#include <map>
+#include <ostream>
+#include <string>
+#include <utility>
+#include <vector>
+
+bool cmCPackNuGetGenerator::SupportsComponentInstallation() const
+{
+ return IsOn("CPACK_NUGET_COMPONENT_INSTALL");
+}
+
+int cmCPackNuGetGenerator::PackageFiles()
+{
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl);
+
+ /* Reset package file name list it will be populated after the
+ * `CPackNuGet.cmake` run */
+ packageFileNames.clear();
+
+ /* Are we in the component packaging case */
+ if (WantsComponentInstallation()) {
+ if (componentPackageMethod == ONE_PACKAGE) {
+ // CASE 1 : COMPONENT ALL-IN-ONE package
+ // Meaning that all per-component pre-installed files
+ // goes into the single package.
+ this->SetOption("CPACK_NUGET_ALL_IN_ONE", "TRUE");
+ SetupGroupComponentVariables(true);
+ } else {
+ // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
+ // There will be 1 package for each component group
+ // however one may require to ignore component group and
+ // in this case you'll get 1 package for each component.
+ SetupGroupComponentVariables(componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
+ }
+ } else {
+ // CASE 3 : NON COMPONENT package.
+ this->SetOption("CPACK_NUGET_ORDINAL_MONOLITIC", "TRUE");
+ }
+
+ auto retval = this->ReadListFile("CPackNuGet.cmake");
+ if (retval) {
+ AddGeneratedPackageNames();
+ } else {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while execution CPackNuGet.cmake" << std::endl);
+ }
+
+ return retval;
+}
+
+void cmCPackNuGetGenerator::SetupGroupComponentVariables(bool ignoreGroup)
+{
+ // The default behavior is to have one package by component group
+ // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
+ if (!ignoreGroup) {
+ std::vector<std::string> groups;
+ for (auto const& compG : this->ComponentGroups) {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Packaging component group: " << compG.first << std::endl);
+ groups.push_back(compG.first);
+ auto compGUp =
+ cmSystemTools::UpperCase(cmSystemTools::MakeCidentifier(compG.first));
+
+ // Collect components for this group
+ std::vector<std::string> components;
+ std::transform(begin(compG.second.Components),
+ end(compG.second.Components),
+ std::back_inserter(components),
+ [](cmCPackComponent const* comp) { return comp->Name; });
+ this->SetOption("CPACK_NUGET_" + compGUp + "_GROUP_COMPONENTS",
+ cmJoin(components, ";").c_str());
+ }
+ if (!groups.empty()) {
+ this->SetOption("CPACK_NUGET_GROUPS", cmJoin(groups, ";").c_str());
+ }
+
+ // Handle Orphan components (components not belonging to any groups)
+ std::vector<std::string> components;
+ for (auto const& comp : this->Components) {
+ // Does the component belong to a group?
+ if (comp.second.Group == nullptr) {
+ cmCPackLogger(
+ cmCPackLog::LOG_VERBOSE, "Component <"
+ << comp.second.Name
+ << "> does not belong to any group, package it separately."
+ << std::endl);
+ components.push_back(comp.first);
+ }
+ }
+ if (!components.empty()) {
+ this->SetOption("CPACK_NUGET_COMPONENTS",
+ cmJoin(components, ";").c_str());
+ }
+
+ } else {
+ std::vector<std::string> components;
+ components.reserve(this->Components.size());
+ std::transform(begin(this->Components), end(this->Components),
+ std::back_inserter(components),
+ [](std::pair<std::string, cmCPackComponent> const& comp) {
+ return comp.first;
+ });
+ this->SetOption("CPACK_NUGET_COMPONENTS", cmJoin(components, ";").c_str());
+ }
+}
+
+void cmCPackNuGetGenerator::AddGeneratedPackageNames()
+{
+ const char* const files_list = this->GetOption("GEN_CPACK_OUTPUT_FILES");
+ if (!files_list) {
+ cmCPackLogger(
+ cmCPackLog::LOG_ERROR,
+ "Error while execution CPackNuGet.cmake: No NuGet package has generated"
+ << std::endl);
+ return;
+ }
+ // add the generated packages to package file names list
+ std::string fileNames{ files_list };
+ const char sep = ';';
+ std::string::size_type pos1 = 0;
+ std::string::size_type pos2 = fileNames.find(sep, pos1 + 1);
+ while (pos2 != std::string::npos) {
+ packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1));
+ pos1 = pos2 + 1;
+ pos2 = fileNames.find(sep, pos1 + 1);
+ }
+ packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1));
+}
diff --git a/Source/CPack/cmCPackNuGetGenerator.h b/Source/CPack/cmCPackNuGetGenerator.h
new file mode 100644
index 0000000000..a59db2d04e
--- /dev/null
+++ b/Source/CPack/cmCPackNuGetGenerator.h
@@ -0,0 +1,37 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCPackNuGetGenerator_h
+#define cmCPackNuGetGenerator_h
+
+#include "cmCPackGenerator.h"
+
+/** \class cmCPackNuGetGenerator
+ * \brief A generator for RPM packages
+ */
+class cmCPackNuGetGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackNuGetGenerator, cmCPackGenerator);
+
+ // NOTE In fact, it is possible to have NuGet not only for Windows...
+ // https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools
+ static bool CanGenerate() { return true; }
+
+protected:
+ bool SupportsComponentInstallation() const override;
+ int PackageFiles() override;
+
+ const char* GetOutputExtension() override { return ".nupkg"; }
+ bool SupportsAbsoluteDestination() const override { return false; }
+ /**
+ * The method used to prepare variables when component
+ * install is used.
+ */
+ void SetupGroupComponentVariables(bool ignoreGroup);
+ /**
+ * Populate \c packageFileNames vector of built packages.
+ */
+ void AddGeneratedPackageNames();
+};
+
+#endif