Coverage Report

Created: 2026-10-28 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmPackageInfoReader.h
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#pragma once
4
5
#include "cmConfigure.h" // IWYU pragma: keep
6
7
#include <map>
8
#include <memory>
9
#include <string>
10
#include <vector>
11
12
#include <cm/optional>
13
#include <cm/string_view>
14
15
#include <cm3p/json/value.h>
16
17
class cmExecutionStatus;
18
class cmMakefile;
19
class cmTarget;
20
21
namespace cm {
22
enum class ImportedTargetScope;
23
enum class PackageDomain;
24
enum class TargetType;
25
} // namespace cm
26
27
struct cmPackageRequirement
28
{
29
  std::string Name;
30
  std::string Version;
31
  std::vector<std::string> Components;
32
  std::vector<std::string> Hints;
33
  std::vector<cm::PackageDomain> Domains;
34
};
35
36
/** \class cmPackageInfoReader
37
 * \brief Read and parse CPS files.
38
 *
39
 * This class encapsulates the functionality to read package configuration
40
 * files which use the Common Package Specification, and provides utilities to
41
 * translate the declarations therein into imported targets.
42
 */
43
class cmPackageInfoReader
44
{
45
public:
46
  static std::unique_ptr<cmPackageInfoReader> Read(
47
    cmMakefile* makefile, std::string const& path,
48
    cmPackageInfoReader const* parent = nullptr);
49
50
  std::string GetName() const;
51
  cm::optional<std::string> GetVersion() const;
52
  cm::optional<std::string> GetCompatVersion() const;
53
54
  // NOTE: The eventual intent is for CPS to support multiple version schemas,
55
  // and in particular, we expect to want to support "simple", "custom", "rpm",
56
  // "dpkg" and "pep440". Additionally, we desire to be able to parse each of
57
  // these to the maximum extent possible; in particular, we want to be able
58
  // to decompose "simple" and "pep440" versions into components represented
59
  // as numeric types rather than strings, which is not possible with the "rpm"
60
  // and "dpkg" schemas. Therefore, we require different data structures to
61
  // represent different version schemas.
62
63
  struct Pep440Version
64
  {
65
    // NOTE: This structure is currently incomplete as we only support the
66
    // "simple" schema at this time.
67
    bool Simple; // "simple" can be represented as a subset of "pep440"
68
    std::vector<unsigned> ReleaseComponents;
69
    cm::optional<std::string> LocalLabel;
70
  };
71
72
  // FIXME: Return a sum type (e.g. {cm,std}::variant) of possible versions
73
  // when we support more than just the "simple" (and possibly "pep440")
74
  // schema(s).
75
  /// If the package uses the 'simple' version scheme, parse the provided
76
  /// version string as a numeric tuple and optional trailing string.  Returns
77
  /// a disengaged optional for other schemes or if no version is specified.
78
  cm::optional<Pep440Version> ParseVersion(
79
    cm::optional<std::string> const& version) const;
80
81
  /// Requirements declared by this file, excluding inherited requirements.
82
  std::vector<cmPackageRequirement> const& GetRequirements() const
83
8.55k
  {
84
8.55k
    return this->Requirements;
85
8.55k
  }
86
  std::vector<std::string> GetComponentNames() const;
87
88
  /// Create targets for components specified in the CPS file.
89
  bool ImportTargets(cmMakefile* makefile, cmExecutionStatus& status,
90
                     cm::ImportedTargetScope scope);
91
92
  /// Add configuration-specific properties for targets.
93
  bool ImportTargetConfigurations(cmMakefile* makefile,
94
                                  cmExecutionStatus& status) const;
95
96
private:
97
12.8k
  cmPackageInfoReader() = default;
98
99
  cmTarget* AddComponent(cmMakefile* makefile, cm::TargetType type,
100
                         std::string const& name, Json::Value const& data,
101
                         std::string const& package,
102
                         cm::ImportedTargetScope scope) const;
103
104
  void AddTargetConfiguration(cmTarget* target,
105
                              cm::string_view configuration) const;
106
107
  void AddTargetSources(cmMakefile* makefile, cmTarget* target,
108
                        Json::Value const& data) const;
109
110
  void SetTargetProperties(cmMakefile* makefile, cmTarget* target,
111
                           Json::Value const& data, std::string const& package,
112
                           cm::string_view configuration) const;
113
  void SetImportProperty(cmMakefile* makefile, cmTarget* target,
114
                         cm::string_view property,
115
                         cm::string_view configuration,
116
                         Json::Value const& object,
117
                         std::string const& attribute) const;
118
  void SetMetaProperty(cmMakefile* makefile, cmTarget* target,
119
                       std::string const& property, Json::Value const& object,
120
                       std::string const& attribute,
121
                       std::string const& defaultValue = {}) const;
122
  void ReadCxxModulesMetadata(cmMakefile* makefile, cmTarget* target,
123
                              cm::string_view configuration,
124
                              Json::Value const& object) const;
125
126
  std::string ResolvePath(std::string path) const;
127
  std::string ResolveTargetName(cmMakefile* makefile, std::string const& name,
128
                                std::string const& context) const;
129
130
  void ReadRequirements();
131
132
  std::string Path;
133
  Json::Value Data;
134
  std::string Prefix;
135
  std::vector<cmPackageRequirement> Requirements;
136
  std::map<std::string, std::vector<cm::PackageDomain>> RequirementDomains;
137
138
  std::map<std::string, cmTarget*> ComponentTargets;
139
  std::vector<std::string> DefaultConfigurations;
140
  std::string DefaultLicense;
141
};