summaryrefslogtreecommitdiffstats
path: root/Source/CPack/cmCPackNuGetGenerator.cxx
blob: 19a3a0ad33a1d826e46aff963f7a6e429b531c8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* 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 "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmStringAlgorithms.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("Internal/CPack/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));
}