mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
cmSbom: Fix names to ensure SBOM SPDX-3 compliance
This commit is contained in:
@@ -31,7 +31,9 @@ bool cmExportBuildSbomGenerator::GenerateMainFile(std::ostream& os)
|
||||
cmSbomDocument doc;
|
||||
doc.Graph.reserve(256);
|
||||
|
||||
cmSpdxDocument* project = insert_back(doc.Graph, this->GenerateSbom());
|
||||
cmSpdxCreationInfo const* ci =
|
||||
insert_back(doc.Graph, this->GenerateCreationInfo());
|
||||
cmSpdxDocument* project = insert_back(doc.Graph, this->GenerateSbom(ci));
|
||||
std::vector<TargetProperties> targets;
|
||||
|
||||
for (auto const& exp : this->Exports) {
|
||||
@@ -44,13 +46,14 @@ bool cmExportBuildSbomGenerator::GenerateMainFile(std::ostream& os)
|
||||
this->PopulateLinkLibrariesProperty(
|
||||
target, cmGeneratorExpression::BuildInterface, properties);
|
||||
|
||||
targets.push_back(TargetProperties{
|
||||
insert_back(project->RootElements, this->GenerateImportTarget(target)),
|
||||
target, std::move(properties) });
|
||||
targets.push_back(
|
||||
TargetProperties{ insert_back(project->RootElements,
|
||||
this->GenerateImportTarget(ci, target)),
|
||||
target, std::move(properties) });
|
||||
}
|
||||
|
||||
for (auto const& target : targets) {
|
||||
this->GenerateProperties(doc, project, target, targets);
|
||||
this->GenerateProperties(doc, project, ci, target, targets);
|
||||
}
|
||||
|
||||
this->WriteSbom(doc, os);
|
||||
|
||||
@@ -68,8 +68,9 @@ bool cmExportInstallSbomGenerator::GenerateMainFile(std::ostream& os)
|
||||
cmSbomDocument doc;
|
||||
doc.Graph.reserve(256);
|
||||
|
||||
cmSpdxDocument* project = insert_back(doc.Graph, this->GenerateSbom());
|
||||
|
||||
cmSpdxCreationInfo const* ci =
|
||||
insert_back(doc.Graph, this->GenerateCreationInfo());
|
||||
cmSpdxDocument* project = insert_back(doc.Graph, this->GenerateSbom(ci));
|
||||
std::vector<TargetProperties> targets;
|
||||
targets.reserve(allTargets.size());
|
||||
|
||||
@@ -84,14 +85,14 @@ bool cmExportInstallSbomGenerator::GenerateMainFile(std::ostream& os)
|
||||
this->PopulateInterfaceLinkLibrariesProperty(
|
||||
gt, cmGeneratorExpression::InstallInterface, properties);
|
||||
|
||||
targets.push_back(
|
||||
TargetProperties{ insert_back(project->RootElements,
|
||||
this->GenerateImportTarget(te->Target)),
|
||||
te->Target, std::move(properties) });
|
||||
targets.push_back(TargetProperties{
|
||||
insert_back(project->RootElements,
|
||||
this->GenerateImportTarget(ci, te->Target)),
|
||||
te->Target, std::move(properties) });
|
||||
}
|
||||
|
||||
for (auto const& target : targets) {
|
||||
this->GenerateProperties(doc, project, target, targets);
|
||||
this->GenerateProperties(doc, project, ci, target, targets);
|
||||
}
|
||||
|
||||
this->WriteSbom(doc, os);
|
||||
@@ -104,7 +105,9 @@ void cmExportInstallSbomGenerator::GenerateImportTargetsConfig(
|
||||
cmSbomDocument doc;
|
||||
doc.Graph.reserve(256);
|
||||
|
||||
cmSpdxDocument* project = insert_back(doc.Graph, this->GenerateSbom());
|
||||
cmSpdxCreationInfo const* ci =
|
||||
insert_back(doc.Graph, this->GenerateCreationInfo());
|
||||
cmSpdxDocument* project = insert_back(doc.Graph, this->GenerateSbom(ci));
|
||||
|
||||
std::vector<TargetProperties> targets;
|
||||
std::string cfg = (config.empty() ? "noconfig" : config);
|
||||
@@ -124,14 +127,14 @@ void cmExportInstallSbomGenerator::GenerateImportTargetsConfig(
|
||||
this->PopulateLinkLibrariesProperty(
|
||||
te->Target, cmGeneratorExpression::InstallInterface, properties);
|
||||
|
||||
targets.push_back(
|
||||
TargetProperties{ insert_back(project->RootElements,
|
||||
this->GenerateImportTarget(te->Target)),
|
||||
te->Target, std::move(properties) });
|
||||
targets.push_back(TargetProperties{
|
||||
insert_back(project->RootElements,
|
||||
this->GenerateImportTarget(ci, te->Target)),
|
||||
te->Target, std::move(properties) });
|
||||
}
|
||||
|
||||
for (auto const& target : targets) {
|
||||
this->GenerateProperties(doc, project, target, targets);
|
||||
this->GenerateProperties(doc, project, ci, target, targets);
|
||||
}
|
||||
|
||||
this->WriteSbom(doc, os);
|
||||
|
||||
@@ -85,7 +85,9 @@ bool cmExportSbomGenerator::AddPackageInformation(
|
||||
}
|
||||
|
||||
cmSpdxOrganization org;
|
||||
org.SpdxId = cmStrCat("urn:", name, "#Organization");
|
||||
org.Name = name;
|
||||
org.CreationInfo = artifact.CreationInfo;
|
||||
artifact.OriginatedBy.emplace_back(std::move(org));
|
||||
|
||||
if (package.Description) {
|
||||
@@ -111,20 +113,23 @@ bool cmExportSbomGenerator::AddPackageInformation(
|
||||
return true;
|
||||
}
|
||||
|
||||
cmSpdxDocument cmExportSbomGenerator::GenerateSbom() const
|
||||
cmSpdxCreationInfo cmExportSbomGenerator::GenerateCreationInfo() const
|
||||
{
|
||||
cmSpdxTool tool;
|
||||
tool.SpdxId = "CMake#Agent";
|
||||
tool.Name = "CMake";
|
||||
|
||||
cmSpdxCreationInfo ci;
|
||||
ci.SpdxId = "_:Build#CreationInfo";
|
||||
ci.Created = cmSystemTools::GetCurrentDateTime("%FT%TZ");
|
||||
ci.CreatedUsing = { tool };
|
||||
ci.CreatedBy = { "https://gitlab.kitware.com/cmake/cmake" };
|
||||
ci.Comment = "This SBOM was generated from the CMakeLists.txt File";
|
||||
ci.SpecVersion = "3.0.1";
|
||||
return ci;
|
||||
}
|
||||
|
||||
cmSpdxDocument cmExportSbomGenerator::GenerateSbom(
|
||||
cmSpdxCreationInfo const* ci) const
|
||||
{
|
||||
cmSpdxDocument proj;
|
||||
proj.Name = PackageName;
|
||||
proj.SpdxId = cmStrCat(PackageName, "#SPDXDocument");
|
||||
proj.SpdxId = cmStrCat("urn:", PackageName, "#SPDXDocument");
|
||||
proj.ProfileConformance = { "core", "software" };
|
||||
proj.CreationInfo = ci;
|
||||
|
||||
@@ -140,18 +145,13 @@ cmSpdxDocument cmExportSbomGenerator::GenerateSbom() const
|
||||
}
|
||||
|
||||
cmSpdxPackage cmExportSbomGenerator::GenerateImportTarget(
|
||||
cmGeneratorTarget const* target) const
|
||||
cmSpdxCreationInfo const* ci, cmGeneratorTarget const* target) const
|
||||
{
|
||||
cmSpdxPackage package;
|
||||
package.SpdxId = cmStrCat(target->GetName(), "#Package");
|
||||
package.SpdxId = cmStrCat("urn:", target->GetName(), "#Package");
|
||||
package.Name = target->GetName();
|
||||
package.PrimaryPurpose = GetPurpose(target->GetType());
|
||||
|
||||
cmSpdxExternalRef buildSystem;
|
||||
buildSystem.Locator = "CMake#Agent";
|
||||
buildSystem.ExternalRefType = "buildSystem";
|
||||
buildSystem.Comment = "Build System used for this target";
|
||||
package.ExternalRef = { buildSystem };
|
||||
package.CreationInfo = ci;
|
||||
|
||||
if (!this->PackageVersion.empty()) {
|
||||
package.PackageVersion = this->PackageVersion;
|
||||
@@ -169,8 +169,8 @@ cmSpdxPackage cmExportSbomGenerator::GenerateImportTarget(
|
||||
}
|
||||
|
||||
void cmExportSbomGenerator::GenerateLinkProperties(
|
||||
cmSbomDocument& doc, cmSpdxDocument* project, std::string const& libraries,
|
||||
TargetProperties const& current,
|
||||
cmSbomDocument& doc, cmSpdxDocument* project, cmSpdxCreationInfo const* ci,
|
||||
std::string const& libraries, TargetProperties const& current,
|
||||
std::vector<TargetProperties> const& allTargets) const
|
||||
{
|
||||
auto itProp = current.Properties.find(libraries);
|
||||
@@ -187,17 +187,19 @@ void cmExportSbomGenerator::GenerateLinkProperties(
|
||||
return;
|
||||
}
|
||||
|
||||
auto makeRel = [&](char const* desc) {
|
||||
auto makeRel = [&](char const* id, char const* desc) {
|
||||
cmSpdxRelationship r;
|
||||
r.SpdxId = cmStrCat("urn:", id, "#Relationship");
|
||||
r.RelationshipType = cmSpdxRelationship::RelationshipTypeId::DEPENDS_ON;
|
||||
r.Description = desc;
|
||||
r.From = current.Package;
|
||||
r.CreationInfo = ci;
|
||||
return r;
|
||||
};
|
||||
|
||||
auto linkLibraries = makeRel("Linked Libraries");
|
||||
auto linkRequires = makeRel("Required Runtime Libraries");
|
||||
auto buildRequires = makeRel("Required Build-Time Libraries");
|
||||
auto linkLibraries = makeRel("Static", "Linked Libraries");
|
||||
auto linkRequires = makeRel("Dynamic", "Required Runtime Libraries");
|
||||
auto buildRequires = makeRel("Shared", "Required Build-Time Libraries");
|
||||
|
||||
auto addArtifact =
|
||||
[&](std::string const& name) -> std::pair<bool, cmSpdxPackage const*> {
|
||||
@@ -215,7 +217,8 @@ void cmExportSbomGenerator::GenerateLinkProperties(
|
||||
cmStrCat(linkInfo.Package, ":", linkInfo.Component);
|
||||
cmSpdxPackage pkg;
|
||||
pkg.Name = pkgName;
|
||||
pkg.SpdxId = cmStrCat(pkgName, "#Package");
|
||||
pkg.SpdxId = cmStrCat("urn:", pkgName, "#Package");
|
||||
pkg.CreationInfo = ci;
|
||||
if (!linkInfo.Package.empty()) {
|
||||
auto const& pkgIt = this->Requirements.find(linkInfo.Package);
|
||||
if (pkgIt != this->Requirements.end() &&
|
||||
@@ -223,13 +226,13 @@ void cmExportSbomGenerator::GenerateLinkProperties(
|
||||
this->AddPackageInformation(pkg, pkgIt->first, pkgIt->second);
|
||||
}
|
||||
}
|
||||
|
||||
return { true, insert_back(project->Elements, std::move(pkg)) };
|
||||
}
|
||||
|
||||
cmSpdxPackage pkg;
|
||||
pkg.SpdxId = cmStrCat(name, "#Package");
|
||||
pkg.SpdxId = cmStrCat("urn:", name, "#Package");
|
||||
pkg.Name = name;
|
||||
pkg.CreationInfo = ci;
|
||||
return { false, insert_back(project->Elements, std::move(pkg)) };
|
||||
};
|
||||
|
||||
@@ -266,13 +269,14 @@ void cmExportSbomGenerator::GenerateLinkProperties(
|
||||
}
|
||||
|
||||
bool cmExportSbomGenerator::GenerateProperties(
|
||||
cmSbomDocument& doc, cmSpdxDocument* proj, TargetProperties const& current,
|
||||
cmSbomDocument& doc, cmSpdxDocument* proj, cmSpdxCreationInfo const* ci,
|
||||
TargetProperties const& current,
|
||||
std::vector<TargetProperties> const& allTargets) const
|
||||
{
|
||||
this->GenerateLinkProperties(doc, proj, "LINK_LIBRARIES", current,
|
||||
allTargets);
|
||||
this->GenerateLinkProperties(doc, proj, "INTERFACE_LINK_LIBRARIES", current,
|
||||
this->GenerateLinkProperties(doc, proj, ci, "LINK_LIBRARIES", current,
|
||||
allTargets);
|
||||
this->GenerateLinkProperties(doc, proj, ci, "INTERFACE_LINK_LIBRARIES",
|
||||
current, allTargets);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -348,7 +352,6 @@ bool cmExportSbomGenerator::NoteLinkedTarget(
|
||||
cmPackageInformation& req =
|
||||
this->Requirements.insert(std::move(*pkgInfo)).first->second;
|
||||
req.Components.emplace(std::move(component));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ class cmGeneratorTarget;
|
||||
struct cmSbomDocument;
|
||||
struct cmSpdxDocument;
|
||||
struct cmSpdxPackage;
|
||||
struct cmSpdxCreationInfo;
|
||||
|
||||
class cmExportSbomGenerator : virtual public cmExportFileGenerator
|
||||
{
|
||||
@@ -37,8 +38,10 @@ protected:
|
||||
|
||||
void WriteSbom(cmSbomDocument& doc, std::ostream& os) const;
|
||||
|
||||
cmSpdxDocument GenerateSbom() const;
|
||||
cmSpdxPackage GenerateImportTarget(cmGeneratorTarget const* target) const;
|
||||
cmSpdxCreationInfo GenerateCreationInfo() const;
|
||||
cmSpdxDocument GenerateSbom(cmSpdxCreationInfo const* ci) const;
|
||||
cmSpdxPackage GenerateImportTarget(cmSpdxCreationInfo const* ci,
|
||||
cmGeneratorTarget const* target) const;
|
||||
|
||||
std::string const& GetPackageName() const { return this->PackageName; }
|
||||
|
||||
@@ -47,13 +50,13 @@ protected:
|
||||
cmPackageInformation const& package) const;
|
||||
|
||||
bool GenerateProperties(
|
||||
cmSbomDocument& doc, cmSpdxDocument* project,
|
||||
cmSbomDocument& doc, cmSpdxDocument* project, cmSpdxCreationInfo const* ci,
|
||||
TargetProperties const& current,
|
||||
std::vector<TargetProperties> const& allTargets) const;
|
||||
|
||||
void GenerateLinkProperties(
|
||||
cmSbomDocument& doc, cmSpdxDocument* project, std::string const& libraries,
|
||||
TargetProperties const& current,
|
||||
cmSbomDocument& doc, cmSpdxDocument* project, cmSpdxCreationInfo const* ci,
|
||||
std::string const& libraries, TargetProperties const& current,
|
||||
std::vector<TargetProperties> const& allTargets) const;
|
||||
|
||||
bool NoteLinkedTarget(cmGeneratorTarget const* target,
|
||||
|
||||
+57
-55
@@ -60,29 +60,29 @@ std::string to_string(cmSpdxSoftwareArtifact::PurposeId id)
|
||||
{
|
||||
switch (id) {
|
||||
case cmSpdxSoftwareArtifact::PurposeId::APPLICATION:
|
||||
return "APPLICATION";
|
||||
return "application";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::ARCHIVE:
|
||||
return "ARCHIVE";
|
||||
return "archive";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::CONTAINER:
|
||||
return "CONTAINER";
|
||||
return "container";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::DATA:
|
||||
return "DATA";
|
||||
return "data";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::DEVICE:
|
||||
return "DEVICE";
|
||||
return "device";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::FIRMWARE:
|
||||
return "FIRMWARE";
|
||||
return "firmware";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::FILE:
|
||||
return "FILE";
|
||||
return "file";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::INSTALL:
|
||||
return "INSTALL";
|
||||
return "install";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::LIBRARY:
|
||||
return "LIBRARY";
|
||||
return "library";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::MODULE:
|
||||
return "MODULE";
|
||||
return "module";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::OPERATING_SYSTEM:
|
||||
return "OPERATING_SYSTEM";
|
||||
return "operatingSystem";
|
||||
case cmSpdxSoftwareArtifact::PurposeId::SOURCE:
|
||||
return "SOURCE";
|
||||
return "source";
|
||||
}
|
||||
throw std::invalid_argument("Unknown PurposeId");
|
||||
}
|
||||
@@ -91,19 +91,19 @@ std::string to_string(cmSpdxSbom::TypeId id)
|
||||
{
|
||||
switch (id) {
|
||||
case cmSpdxSbom::TypeId::ANALYZED:
|
||||
return "ANALYZED";
|
||||
return "analyzed";
|
||||
case cmSpdxSbom::TypeId::BUILD:
|
||||
return "BUILD";
|
||||
return "build";
|
||||
case cmSpdxSbom::TypeId::DEPLOYED:
|
||||
return "DEPLOYED";
|
||||
return "deployed";
|
||||
case cmSpdxSbom::TypeId::DESIGN:
|
||||
return "DESIGN";
|
||||
return "design";
|
||||
case cmSpdxSbom::TypeId::RUNTIME:
|
||||
return "RUNTIME";
|
||||
return "runtime";
|
||||
case cmSpdxSbom::TypeId::SOURCE:
|
||||
return "SOURCE";
|
||||
return "source";
|
||||
case cmSpdxSbom::TypeId::TEST:
|
||||
return "TEST";
|
||||
return "test";
|
||||
}
|
||||
throw std::invalid_argument("Unknown Sbom::TypeId");
|
||||
}
|
||||
@@ -112,9 +112,9 @@ std::string to_string(cmSpdxFile::FileKindId id)
|
||||
{
|
||||
switch (id) {
|
||||
case cmSpdxFile::FileKindId::DIRECTORY:
|
||||
return "DIRECTORY";
|
||||
return "directory";
|
||||
case cmSpdxFile::FileKindId::FILE:
|
||||
return "FILE";
|
||||
return "file";
|
||||
}
|
||||
throw std::invalid_argument("Unknown File::FileKindId");
|
||||
}
|
||||
@@ -123,13 +123,13 @@ std::string to_string(cmSpdxRelationship::RelationshipTypeId id)
|
||||
{
|
||||
switch (id) {
|
||||
case cmSpdxRelationship::RelationshipTypeId::DESCRIBES:
|
||||
return "DESCRIBES";
|
||||
return "describes";
|
||||
case cmSpdxRelationship::RelationshipTypeId::CONTAINS:
|
||||
return "CONTAINS";
|
||||
return "contains";
|
||||
case cmSpdxRelationship::RelationshipTypeId::DEPENDS_ON:
|
||||
return "DEPENDS_ON";
|
||||
return "dependsOn";
|
||||
case cmSpdxRelationship::RelationshipTypeId::OTHER:
|
||||
return "OTHER";
|
||||
return "other";
|
||||
}
|
||||
throw std::invalid_argument("Unknown RelationshipTypeId");
|
||||
}
|
||||
@@ -138,13 +138,13 @@ std::string to_string(cmSpdxLifecycleScopedRelationship::ScopeId id)
|
||||
{
|
||||
switch (id) {
|
||||
case cmSpdxLifecycleScopedRelationship::ScopeId::BUILD:
|
||||
return "BUILD";
|
||||
return "build";
|
||||
case cmSpdxLifecycleScopedRelationship::ScopeId::DESIGN:
|
||||
return "DESIGN";
|
||||
return "design";
|
||||
case cmSpdxLifecycleScopedRelationship::ScopeId::RUNTIME:
|
||||
return "RUNTIME";
|
||||
return "runtime";
|
||||
case cmSpdxLifecycleScopedRelationship::ScopeId::TEST:
|
||||
return "TEST";
|
||||
return "test";
|
||||
}
|
||||
throw std::invalid_argument("Unknown Lifecycle ScopeId");
|
||||
}
|
||||
@@ -153,9 +153,9 @@ std::string to_string(cmSpdxAnnotation::AnnotationTypeId id)
|
||||
{
|
||||
switch (id) {
|
||||
case cmSpdxAnnotation::AnnotationTypeId::REVIEW:
|
||||
return "REVIEW";
|
||||
return "review";
|
||||
case cmSpdxAnnotation::AnnotationTypeId::OTHER:
|
||||
return "OTHER";
|
||||
return "other";
|
||||
}
|
||||
throw std::invalid_argument("Unknown AnnotationTypeId");
|
||||
}
|
||||
@@ -164,11 +164,11 @@ std::string to_string(cmSpdxArtifact::SupportTypeId id)
|
||||
{
|
||||
switch (id) {
|
||||
case cmSpdxArtifact::SupportTypeId::COMMUNITY:
|
||||
return "COMMUNITY";
|
||||
return "community";
|
||||
case cmSpdxArtifact::SupportTypeId::COMMERCIAL:
|
||||
return "COMMERCIAL";
|
||||
return "commercial";
|
||||
case cmSpdxArtifact::SupportTypeId::NONE:
|
||||
return "NONE";
|
||||
return "none";
|
||||
}
|
||||
throw std::invalid_argument("Unknown SupportTypeId");
|
||||
}
|
||||
@@ -226,7 +226,7 @@ void cmSpdxIntegrityMethod::Serialize(cmSbomSerializer& serializer) const
|
||||
void cmSpdxElement::Serialize(cmSbomSerializer& serializer) const
|
||||
{
|
||||
serializer.AddString("type", "Element");
|
||||
SerializeIfPresent(serializer, "@id", SpdxId);
|
||||
SerializeIfPresent(serializer, "spdxId", SpdxId);
|
||||
SerializeIfPresent(serializer, "name", Name);
|
||||
SerializeIfPresent(serializer, "summary", Summary);
|
||||
SerializeIfPresent(serializer, "description", Description);
|
||||
@@ -437,30 +437,32 @@ void cmSpdxSoftwareArtifact::Serialize(cmSbomSerializer& serializer) const
|
||||
cmSpdxArtifact::Serialize(serializer);
|
||||
serializer.AddString("type", "software_SoftwareArtifact");
|
||||
if (PrimaryPurpose) {
|
||||
serializer.AddString("primaryPurpose", to_string(*PrimaryPurpose));
|
||||
serializer.AddString("software_primaryPurpose",
|
||||
to_string(*PrimaryPurpose));
|
||||
}
|
||||
if (AdditionalPurpose) {
|
||||
for (auto const& p : *AdditionalPurpose) {
|
||||
serializer.AddString("additionalPurpose", to_string(p));
|
||||
serializer.AddString("software_AdditionalPurpose", to_string(p));
|
||||
}
|
||||
}
|
||||
SerializeIfPresent(serializer, "copyrightText", CopyrightText);
|
||||
SerializeIfPresent(serializer, "attributionText", AttributionText);
|
||||
SerializeIfPresent(serializer, "software_copyrightText", CopyrightText);
|
||||
SerializeIfPresent(serializer, "software_attributionText", AttributionText);
|
||||
if (ContentIdentifier) {
|
||||
serializer.AddVisitable("contentIdentifier", *ContentIdentifier);
|
||||
serializer.AddVisitable("software_contentIdentifier", *ContentIdentifier);
|
||||
}
|
||||
SerializeIfPresent(serializer, "artifactSize", ArtifactSize);
|
||||
SerializeIfPresent(serializer, "software_artifactSize", ArtifactSize);
|
||||
}
|
||||
|
||||
void cmSpdxPackage::Serialize(cmSbomSerializer& serializer) const
|
||||
{
|
||||
cmSpdxSoftwareArtifact::Serialize(serializer);
|
||||
serializer.AddString("type", "software_Package");
|
||||
SerializeIfPresent(serializer, "downloadLocation", DownloadLocation);
|
||||
SerializeIfPresent(serializer, "homePage", Homepage);
|
||||
SerializeIfPresent(serializer, "packageVersion", PackageVersion);
|
||||
SerializeIfPresent(serializer, "packageUrl", PackageUrl);
|
||||
SerializeIfPresent(serializer, "sourceInfo", SourceInfo);
|
||||
SerializeIfPresent(serializer, "software_downloadLocation",
|
||||
DownloadLocation);
|
||||
SerializeIfPresent(serializer, "software_homePage", Homepage);
|
||||
SerializeIfPresent(serializer, "software_packageVersion", PackageVersion);
|
||||
SerializeIfPresent(serializer, "software_packageUrl", PackageUrl);
|
||||
SerializeIfPresent(serializer, "software_sourceInfo", SourceInfo);
|
||||
}
|
||||
|
||||
void cmSpdxFile::Serialize(cmSbomSerializer& serializer) const
|
||||
@@ -468,30 +470,30 @@ void cmSpdxFile::Serialize(cmSbomSerializer& serializer) const
|
||||
cmSpdxArtifact::Serialize(serializer);
|
||||
serializer.AddString("type", "software_File");
|
||||
if (ContentType) {
|
||||
serializer.AddString("contentType", *ContentType);
|
||||
serializer.AddString("software_contentType", *ContentType);
|
||||
}
|
||||
if (FileType) {
|
||||
serializer.AddString("fileType", to_string(*FileType));
|
||||
serializer.AddString("software_fileType", to_string(*FileType));
|
||||
}
|
||||
}
|
||||
|
||||
void cmSpdxContentIdentifier::Serialize(cmSbomSerializer& serializer) const
|
||||
{
|
||||
cmSpdxIntegrityMethod::Serialize(serializer);
|
||||
serializer.AddString("type", "software_ContentIdentifier");
|
||||
SerializeIfPresent(serializer, "contentIdentifierType",
|
||||
serializer.AddString("type", "software_contentIdentifier");
|
||||
SerializeIfPresent(serializer, "software_contentIdentifierType",
|
||||
ContentIdentifierType);
|
||||
SerializeIfPresent(serializer, "contentValue", ContentValue);
|
||||
SerializeIfPresent(serializer, "software_contentValue", ContentValue);
|
||||
}
|
||||
|
||||
void cmSpdxSnippet::Serialize(cmSbomSerializer& serializer) const
|
||||
{
|
||||
cmSpdxSoftwareArtifact::Serialize(serializer);
|
||||
serializer.AddString("type", "software_Snippet");
|
||||
SerializeIfPresent(serializer, "byteRange", ByteRange);
|
||||
SerializeIfPresent(serializer, "lineRange", LineRange);
|
||||
serializer.AddString("type", "software_snippet");
|
||||
SerializeIfPresent(serializer, "software_byteRange", ByteRange);
|
||||
SerializeIfPresent(serializer, "software_lineRange", LineRange);
|
||||
if (SnippetFromFile) {
|
||||
serializer.AddVisitable("snippetFromFile", *SnippetFromFile);
|
||||
serializer.AddVisitable("software_snippetFromFile", *SnippetFromFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -39,11 +39,12 @@ struct cmSpdxExternalRef
|
||||
|
||||
struct cmSpdxCreationInfo
|
||||
{
|
||||
cm::optional<std::string> Id;
|
||||
cm::optional<std::string> SpdxId;
|
||||
cm::optional<SemVer> SpecVersion;
|
||||
cm::optional<std::string> Comment;
|
||||
cm::optional<Datetime> Created;
|
||||
std::vector<cmSbomObject> CreatedBy;
|
||||
std::vector<std::string> CreatedBy;
|
||||
std::vector<cmSbomObject> CreatedUsing;
|
||||
|
||||
void Serialize(cmSbomSerializer&) const;
|
||||
|
||||
@@ -62,7 +62,7 @@ bool testSerializeSpdxJson()
|
||||
Json::Value const& docValue = graph[0];
|
||||
ASSERT_TRUE(docValue.isObject());
|
||||
ASSERT_EQUAL(docValue["type"].asString(), "SpdxDocument");
|
||||
ASSERT_EQUAL(docValue["@id"].asString(), "_:SPDXRef-Document");
|
||||
ASSERT_EQUAL(docValue["spdxId"].asString(), "_:SPDXRef-Document");
|
||||
|
||||
auto const& creationInfo = docValue["creationInfo"];
|
||||
ASSERT_EQUAL(creationInfo["@id"].asString(), "_:SPDXRef-CreationInfo");
|
||||
@@ -70,7 +70,7 @@ bool testSerializeSpdxJson()
|
||||
|
||||
auto const& package = docValue["rootElement"][0];
|
||||
ASSERT_EQUAL(package["type"].asString(), "software_Package");
|
||||
ASSERT_EQUAL(package["@id"].asString(), "_:SPDXRef-Package");
|
||||
ASSERT_EQUAL(package["spdxId"].asString(), "_:SPDXRef-Package");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test_project/test_targets.spdx.json" content)
|
||||
file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test/test_targets.spdx.json" content)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ProjectMetadata-install-check.cmake)
|
||||
|
||||
@@ -1,60 +1,44 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(CREATION_INFO [=[
|
||||
set(CREATION_INFO_EXPECTED [=[
|
||||
{
|
||||
"comment" : "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdUsing" :
|
||||
"@id": "_:Build#CreationInfo",
|
||||
"comment": "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdBy":
|
||||
[
|
||||
{
|
||||
"@id" : "CMake#Agent",
|
||||
"name" : "CMake",
|
||||
"type" : "Tool"
|
||||
}
|
||||
"https://gitlab.kitware.com/cmake/cmake"
|
||||
],
|
||||
"type" : "CreationInfo"
|
||||
"specVersion": "3.0.1",
|
||||
"type": "CreationInfo"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(ELEMENTS [=[
|
||||
[
|
||||
{
|
||||
"@id" : "bar:bar#Package",
|
||||
"name" : "bar:bar",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]
|
||||
]=])
|
||||
|
||||
set(SPDX_DOCUMENT [=[
|
||||
set(SPDX_DOCUMENT_EXPECTED [=[
|
||||
{
|
||||
"@id" : "application_targets#SPDXDocument",
|
||||
"name": "application_targets",
|
||||
"profileConformance": ["core", "software"],
|
||||
"type": "SpdxDocument"
|
||||
"name" : "application_targets",
|
||||
"profileConformance" :
|
||||
[
|
||||
"core",
|
||||
"software"
|
||||
],
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"spdxId" : "urn:application_targets#SPDXDocument",
|
||||
"type" : "SpdxDocument"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(APPLICATION [=[
|
||||
set(APPLICATION_EXPECTED [=[
|
||||
{
|
||||
"@id" : "application#Package",
|
||||
"externalRef" :
|
||||
[
|
||||
{
|
||||
"comment" : "Build System used for this target",
|
||||
"externalRefType" : "buildSystem",
|
||||
"locator" : "CMake#Agent",
|
||||
"type" : "ExternalRef"
|
||||
}
|
||||
],
|
||||
"spdxId" : "application#Package",
|
||||
"name" : "application",
|
||||
"primaryPurpose" : "APPLICATION",
|
||||
"software_primaryPurpose" : "application",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(DEPENDENCY [=[
|
||||
set(DEPENDENCY_EXPECTED [=[
|
||||
{
|
||||
"@id" : "bar:bar#Package",
|
||||
"spdxId" : "bar:bar#Package",
|
||||
"name" : "bar:bar",
|
||||
"originatedBy" :
|
||||
[
|
||||
@@ -63,19 +47,21 @@ set(DEPENDENCY [=[
|
||||
"type" : "Organization"
|
||||
}
|
||||
],
|
||||
"packageVersion" : "1.3.5",
|
||||
"software_packageVersion" : "1.3.5",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(BUILD_LINKED_LIBRARIES [=[
|
||||
set(BUILD_LINKED_LIBRARIES_EXPECTED [=[
|
||||
{
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"description" : "Linked Libraries",
|
||||
"from" : "application#Package",
|
||||
"relationshipType" : "DEPENDS_ON",
|
||||
"from" : "urn:application#Package",
|
||||
"relationshipType" : "dependsOn",
|
||||
"spdxId" : "urn:Static#Relationship",
|
||||
"to" :
|
||||
[
|
||||
"bar:bar#Package"
|
||||
"urn:bar:bar#Package"
|
||||
],
|
||||
"type" : "Relationship"
|
||||
}
|
||||
@@ -83,11 +69,12 @@ set(BUILD_LINKED_LIBRARIES [=[
|
||||
|
||||
|
||||
expect_value("${content}" "https://spdx.org/rdf/3.0.1/spdx-context.jsonld" "@context")
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT)
|
||||
expect_object("${SPDX_DOCUMENT}" CREATION_INFO "creationInfo")
|
||||
expect_object("${SPDX_DOCUMENT}" APPLICATION "rootElement" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" DEPENDENCY "element" "0")
|
||||
string(JSON CREATION_INFO GET "${content}" "@graph" "0")
|
||||
expect_object("${CREATION_INFO}" CREATION_INFO_EXPECTED)
|
||||
|
||||
string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "1")
|
||||
expect_object("${LINKED_LIBRARIES}" BUILD_LINKED_LIBRARIES)
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "1")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT_EXPECTED)
|
||||
expect_object("${SPDX_DOCUMENT}" APPLICATION_EXPECTED "rootElement" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" DEPENDENCY_EXPECTED "element" "0")
|
||||
string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "2")
|
||||
expect_object("${LINKED_LIBRARIES}" BUILD_LINKED_LIBRARIES_EXPECTED)
|
||||
|
||||
@@ -1,223 +1,193 @@
|
||||
function(format_path out)
|
||||
set(path_segments ${ARGN})
|
||||
set(path_string "")
|
||||
foreach(segment IN LISTS path_segments)
|
||||
if(segment MATCHES "^[0-9]+$")
|
||||
string(APPEND path_string "[${segment}]")
|
||||
else()
|
||||
if(path_string STREQUAL "")
|
||||
string(APPEND path_string "${segment}")
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
function(_json_format_path out_var)
|
||||
set(path_str "<root>")
|
||||
set(segments ${ARGN})
|
||||
if(segments)
|
||||
set(path_str "")
|
||||
foreach(seg IN LISTS segments)
|
||||
if(seg MATCHES "^[0-9]+$")
|
||||
string(APPEND path_str "[${seg}]")
|
||||
else()
|
||||
string(APPEND path_string ".${segment}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
if(path_string STREQUAL "")
|
||||
set(path_string "<root>")
|
||||
endif()
|
||||
set(${out} "${path_string}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
macro(fail_at entity actual expected)
|
||||
format_path(formatted_path ${ARGN})
|
||||
set(RunCMake_TEST_FAILED "Attribute '${formatted_path}' ${entity} '${actual}' does not match expected ${entity} '${expected}'")
|
||||
endmacro()
|
||||
|
||||
macro(fail_array_subset expected_index)
|
||||
format_path(formatted_path ${ARGN})
|
||||
set(RunCMake_TEST_FAILED "Attribute '${formatted_path}' array element (subset match) had no match for expected index ${expected_index}")
|
||||
endmacro()
|
||||
|
||||
macro(bubble_error)
|
||||
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
|
||||
endmacro()
|
||||
|
||||
function(json_matches out actual_node expected_node display_path)
|
||||
set(current_path ${display_path})
|
||||
|
||||
string(JSON actual_type TYPE "${actual_node}")
|
||||
string(JSON expected_type TYPE "${expected_node}")
|
||||
if (NOT actual_type STREQUAL expected_type)
|
||||
fail_at("type" "${actual_type}" "${expected_type}" ${current_path})
|
||||
bubble_error()
|
||||
set(${out} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (expected_type STREQUAL "OBJECT")
|
||||
string(JSON expected_length LENGTH "${expected_node}")
|
||||
math(EXPR expected_last_index "${expected_length}-1")
|
||||
foreach(key_index RANGE ${expected_last_index})
|
||||
string(JSON key MEMBER "${expected_node}" "${key_index}")
|
||||
|
||||
string(JSON probe ERROR_VARIABLE error GET "${actual_node}" "${key}")
|
||||
if (error STREQUAL "NOT_FOUND")
|
||||
fail_at("object member presence" "<missing>" "${key}" ${current_path} "${key}")
|
||||
bubble_error()
|
||||
set(${out} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(JSON actual_child_type TYPE "${actual_node}" "${key}")
|
||||
string(JSON expected_child_type TYPE "${expected_node}" "${key}")
|
||||
if (NOT actual_child_type STREQUAL expected_child_type)
|
||||
fail_at("type" "${actual_child_type}" "${expected_child_type}" ${current_path} "${key}")
|
||||
bubble_error()
|
||||
set(${out} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (expected_child_type STREQUAL "OBJECT" OR expected_child_type STREQUAL "ARRAY")
|
||||
string(JSON actual_child GET "${actual_node}" "${key}")
|
||||
string(JSON expected_child GET "${expected_node}" "${key}")
|
||||
set(next_path ${current_path})
|
||||
list(APPEND next_path "${key}")
|
||||
json_matches(is_ok "${actual_child}" "${expected_child}" "${next_path}")
|
||||
if (NOT is_ok)
|
||||
bubble_error()
|
||||
set(${out} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
else()
|
||||
string(JSON actual_value GET "${actual_node}" "${key}")
|
||||
string(JSON expected_value GET "${expected_node}" "${key}")
|
||||
if (NOT "${actual_value}" STREQUAL "${expected_value}")
|
||||
fail_at("value" "${actual_value}" "${expected_value}" ${current_path} "${key}")
|
||||
bubble_error()
|
||||
set(${out} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
if(path_str STREQUAL "")
|
||||
string(APPEND path_str "${seg}")
|
||||
else()
|
||||
string(APPEND path_str ".${seg}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
set(${out_var} "${path_str}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
set(${out} TRUE PARENT_SCOPE)
|
||||
|
||||
macro(_json_fail_at type actual expected path_segments)
|
||||
_json_format_path(display_path ${path_segments})
|
||||
set(msg "JSON Mismatch at '${display_path}'\n")
|
||||
string(APPEND msg " Failure: ${type}\n")
|
||||
string(APPEND msg " Actual: ${actual}\n")
|
||||
string(APPEND msg " Expected: ${expected}")
|
||||
set(RunCMake_TEST_FAILED "${msg}" PARENT_SCOPE)
|
||||
endmacro()
|
||||
|
||||
function(_json_verify_subset out_success actual_node expected_node path_list)
|
||||
string(JSON expected_type ERROR_VARIABLE expected_is_primitive TYPE "${expected_node}")
|
||||
|
||||
if(expected_is_primitive OR NOT (expected_type STREQUAL "OBJECT" OR expected_type STREQUAL "ARRAY"))
|
||||
if("${actual_node}" STREQUAL "${expected_node}")
|
||||
set(${out_success} TRUE PARENT_SCOPE)
|
||||
else()
|
||||
_json_fail_at("Value Mismatch" "${actual_node}" "${expected_node}" "${path_list}")
|
||||
set(${out_success} FALSE PARENT_SCOPE)
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(JSON actual_type ERROR_VARIABLE actual_err TYPE "${actual_node}")
|
||||
if(actual_err)
|
||||
_json_fail_at("Invalid JSON" "${actual_node}" "Valid JSON Structure" "${path_list}")
|
||||
set(${out_success} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT actual_type STREQUAL expected_type)
|
||||
_json_fail_at("Type Mismatch" "${actual_type}" "${expected_type}" "${path_list}")
|
||||
set(${out_success} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(expected_type STREQUAL "OBJECT")
|
||||
string(JSON exp_len LENGTH "${expected_node}")
|
||||
math(EXPR exp_last "${exp_len}-1")
|
||||
|
||||
foreach(idx RANGE ${exp_last})
|
||||
string(JSON key MEMBER "${expected_node}" "${idx}")
|
||||
|
||||
string(JSON act_child ERROR_VARIABLE err GET "${actual_node}" "${key}")
|
||||
if(err)
|
||||
_json_fail_at("Missing Key" "<missing>" "${key}" "${path_list}")
|
||||
set(${out_success} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(JSON exp_child GET "${expected_node}" "${key}")
|
||||
set(next_path ${path_list})
|
||||
list(APPEND next_path "${key}")
|
||||
|
||||
_json_verify_subset(sub_ok "${act_child}" "${exp_child}" "${next_path}")
|
||||
if(NOT sub_ok)
|
||||
set(${out_success} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(${out_success} TRUE PARENT_SCOPE)
|
||||
return()
|
||||
|
||||
elseif (expected_type STREQUAL "ARRAY")
|
||||
string(JSON actual_length LENGTH "${actual_node}")
|
||||
string(JSON expected_length LENGTH "${expected_node}")
|
||||
if (actual_length LESS expected_length)
|
||||
fail_at("array length (subset requirement)" "${actual_length}" ">= ${expected_length}" ${current_path})
|
||||
bubble_error()
|
||||
set(${out} FALSE PARENT_SCOPE)
|
||||
elseif(expected_type STREQUAL "ARRAY")
|
||||
string(JSON exp_len LENGTH "${expected_node}")
|
||||
string(JSON act_len LENGTH "${actual_node}")
|
||||
|
||||
if(act_len LESS exp_len)
|
||||
_json_fail_at("Array Length" "${act_len}" ">= ${exp_len}" "${path_list}")
|
||||
set(${out_success} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
math(EXPR expected_last_index "${expected_length}-1")
|
||||
math(EXPR actual_last_index "${actual_length}-1")
|
||||
foreach(expected_index RANGE ${expected_last_index})
|
||||
set(is_matched FALSE)
|
||||
set(best_error "")
|
||||
set(best_error_set FALSE)
|
||||
math(EXPR exp_last "${exp_len}-1")
|
||||
math(EXPR act_last "${act_len}-1")
|
||||
set(used_indices "")
|
||||
|
||||
string(JSON expected_element_type TYPE "${expected_node}" "${expected_index}")
|
||||
foreach(exp_idx RANGE ${exp_last})
|
||||
string(JSON exp_item GET "${expected_node}" "${exp_idx}")
|
||||
set(found_match FALSE)
|
||||
|
||||
if (expected_element_type STREQUAL "OBJECT" OR expected_element_type STREQUAL "ARRAY")
|
||||
string(JSON expected_element GET "${expected_node}" "${expected_index}")
|
||||
foreach(actual_index RANGE ${actual_last_index})
|
||||
string(JSON actual_element_type TYPE "${actual_node}" "${actual_index}")
|
||||
if (NOT actual_element_type STREQUAL expected_element_type)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
string(JSON actual_element GET "${actual_node}" "${actual_index}")
|
||||
set(next_path ${current_path})
|
||||
list(APPEND next_path "${actual_index}")
|
||||
|
||||
json_matches(one_ok "${actual_element}" "${expected_element}" "${next_path}")
|
||||
if (one_ok)
|
||||
set(is_matched TRUE)
|
||||
break()
|
||||
else()
|
||||
if (NOT best_error_set)
|
||||
set(best_error "${RunCMake_TEST_FAILED}")
|
||||
set(best_error_set TRUE)
|
||||
endif()
|
||||
set(RunCMake_TEST_FAILED "")
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
string(JSON expected_value GET "${expected_node}" "${expected_index}")
|
||||
foreach(actual_index RANGE ${actual_last_index})
|
||||
string(JSON actual_element_type TYPE "${actual_node}" "${actual_index}")
|
||||
if (NOT actual_element_type STREQUAL expected_element_type)
|
||||
continue()
|
||||
endif()
|
||||
string(JSON actual_value GET "${actual_node}" "${actual_index}")
|
||||
if ("${actual_value}" STREQUAL "${expected_value}")
|
||||
set(is_matched TRUE)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
if (NOT is_matched AND NOT best_error_set)
|
||||
set(best_error "")
|
||||
set(best_error_set TRUE)
|
||||
foreach(act_idx RANGE ${act_last})
|
||||
if("${act_idx}" IN_LIST used_indices)
|
||||
continue()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT is_matched)
|
||||
if (best_error_set AND NOT "${best_error}" STREQUAL "")
|
||||
set(RunCMake_TEST_FAILED "${best_error}")
|
||||
else()
|
||||
fail_array_subset("${expected_index}" ${current_path})
|
||||
string(JSON act_item GET "${actual_node}" "${act_idx}")
|
||||
unset(RunCMake_TEST_FAILED)
|
||||
set(next_path ${path_list})
|
||||
list(APPEND next_path "${act_idx}")
|
||||
|
||||
_json_verify_subset(is_match "${act_item}" "${exp_item}" "${next_path}")
|
||||
|
||||
if(is_match)
|
||||
set(found_match TRUE)
|
||||
list(APPEND used_indices "${act_idx}")
|
||||
break()
|
||||
endif()
|
||||
bubble_error()
|
||||
set(${out} FALSE PARENT_SCOPE)
|
||||
endforeach()
|
||||
|
||||
if(NOT found_match)
|
||||
_json_fail_at("Array Element Missing" "<no match found>" "Element [${exp_idx}]" "${path_list}")
|
||||
set(${out_success} FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(${out} TRUE PARENT_SCOPE)
|
||||
set(${out_success} TRUE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(expect_value content expected)
|
||||
string(JSON actual ERROR_VARIABLE error GET "${content}" ${ARGN})
|
||||
if (error STREQUAL "NOT_FOUND")
|
||||
list(JOIN ARGN "." path_name)
|
||||
set(RunCMake_TEST_FAILED "Path '${path_name}' not found in JSON input" PARENT_SCOPE)
|
||||
return()
|
||||
|
||||
function(expect_object actual_json expected_var)
|
||||
if(NOT DEFINED "${expected_var}")
|
||||
message(FATAL_ERROR "Test Usage Error: Variable '${expected_var}' is not defined.")
|
||||
endif()
|
||||
if (NOT "${actual}" STREQUAL "${expected}")
|
||||
fail_at("value" "${actual}" "${expected}" ${ARGN})
|
||||
bubble_error()
|
||||
set(expected_node "${${expected_var}}")
|
||||
set(path_segments ${ARGN})
|
||||
if(path_segments)
|
||||
string(JSON actual_node ERROR_VARIABLE err GET "${actual_json}" ${path_segments})
|
||||
if(err)
|
||||
_json_fail_at("Path Not Found" "<missing>" "${path_segments}" "")
|
||||
return()
|
||||
endif()
|
||||
else()
|
||||
set(actual_node "${actual_json}")
|
||||
endif()
|
||||
|
||||
unset(RunCMake_TEST_FAILED)
|
||||
_json_verify_subset(success "${actual_node}" "${expected_node}" "${path_segments}")
|
||||
|
||||
if(NOT success)
|
||||
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(expect_array content expected_length)
|
||||
string(JSON value_type ERROR_VARIABLE error TYPE "${content}" ${ARGN})
|
||||
if (error STREQUAL "NOT_FOUND")
|
||||
list(JOIN ARGN "." path_name)
|
||||
set(RunCMake_TEST_FAILED "Path '${path_name}' not found in JSON input" PARENT_SCOPE)
|
||||
function(expect_value actual_json expected_val)
|
||||
set(path_segments ${ARGN})
|
||||
string(JSON actual_val ERROR_VARIABLE err GET "${actual_json}" ${path_segments})
|
||||
|
||||
if(err)
|
||||
_json_fail_at("Path Not Found" "<missing>" "${path_segments}" "")
|
||||
return()
|
||||
endif()
|
||||
if (NOT value_type STREQUAL "ARRAY")
|
||||
fail_at("type" "${value_type}" "ARRAY" ${ARGN})
|
||||
bubble_error()
|
||||
return()
|
||||
endif()
|
||||
string(JSON actual_length LENGTH "${content}" ${ARGN})
|
||||
if (NOT actual_length EQUAL "${expected_length}")
|
||||
fail_at("length" "${actual_length}" "${expected_length}" ${ARGN})
|
||||
bubble_error()
|
||||
|
||||
if(NOT "${actual_val}" STREQUAL "${expected_val}")
|
||||
_json_fail_at("Value Mismatch" "${actual_val}" "${expected_val}" "${path_segments}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(expect_object content expected_var)
|
||||
string(JSON actual_node ERROR_VARIABLE error GET "${content}" ${ARGN})
|
||||
if (error STREQUAL "NOT_FOUND")
|
||||
list(JOIN ARGN "." path_name)
|
||||
set(RunCMake_TEST_FAILED "Path '${path_name}' not found in JSON input" PARENT_SCOPE)
|
||||
function(expect_array actual_json expected_len)
|
||||
set(path_segments ${ARGN})
|
||||
|
||||
string(JSON actual_type ERROR_VARIABLE err TYPE "${actual_json}" ${path_segments})
|
||||
if(err)
|
||||
_json_fail_at("Path Not Found" "<missing>" "${path_segments}" "")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(expected_text "${${expected_var}}")
|
||||
set(display_path ${ARGN})
|
||||
|
||||
json_matches(is_ok "${actual_node}" "${expected_text}" "${display_path}")
|
||||
if (NOT is_ok)
|
||||
bubble_error()
|
||||
if(NOT actual_type STREQUAL "ARRAY")
|
||||
_json_fail_at("Type Mismatch" "${actual_type}" "ARRAY" "${path_segments}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(JSON actual_len LENGTH "${actual_json}" ${path_segments})
|
||||
if(NOT actual_len EQUAL expected_len)
|
||||
_json_fail_at("Array Length" "${actual_len}" "${expected_len}" "${path_segments}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -1,60 +1,44 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(CREATION_INFO [=[
|
||||
set(CREATION_INFO_EXPECTED [=[
|
||||
{
|
||||
"comment" : "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdUsing" :
|
||||
"@id": "_:Build#CreationInfo",
|
||||
"comment": "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdBy":
|
||||
[
|
||||
{
|
||||
"@id" : "CMake#Agent",
|
||||
"name" : "CMake",
|
||||
"type" : "Tool"
|
||||
}
|
||||
"https://gitlab.kitware.com/cmake/cmake"
|
||||
],
|
||||
"type" : "CreationInfo"
|
||||
"specVersion": "3.0.1",
|
||||
"type": "CreationInfo"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(ELEMENTS [=[
|
||||
[
|
||||
{
|
||||
"@id" : "bar:bar#Package",
|
||||
"name" : "bar:bar",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]
|
||||
]=])
|
||||
|
||||
set(SPDX_DOCUMENT [=[
|
||||
set(SPDX_DOCUMENT_EXPECTED [=[
|
||||
{
|
||||
"@id" : "interface_targets#SPDXDocument",
|
||||
"spdxId" : "urn:interface_targets#SPDXDocument",
|
||||
"name": "interface_targets",
|
||||
"profileConformance": ["core", "software"],
|
||||
"type": "SpdxDocument"
|
||||
"profileConformance" :
|
||||
[
|
||||
"core",
|
||||
"software"
|
||||
],
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"type" : "SpdxDocument"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(INTERFACE [=[
|
||||
set(APPLICATION_EXPECTED [=[
|
||||
{
|
||||
"@id" : "interface#Package",
|
||||
"externalRef" :
|
||||
[
|
||||
{
|
||||
"comment" : "Build System used for this target",
|
||||
"externalRefType" : "buildSystem",
|
||||
"locator" : "CMake#Agent",
|
||||
"type" : "ExternalRef"
|
||||
}
|
||||
],
|
||||
"spdxId" : "urn:interface#Package",
|
||||
"name" : "interface",
|
||||
"primaryPurpose" : "LIBRARY",
|
||||
"software_primaryPurpose" : "application",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(DEPENDENCY [=[
|
||||
set(DEPENDENCY_EXPECTED [=[
|
||||
{
|
||||
"@id" : "bar:bar#Package",
|
||||
"spdxId" : "urn:bar:bar#Package",
|
||||
"name" : "bar:bar",
|
||||
"originatedBy" :
|
||||
[
|
||||
@@ -63,19 +47,21 @@ set(DEPENDENCY [=[
|
||||
"type" : "Organization"
|
||||
}
|
||||
],
|
||||
"packageVersion" : "1.3.5",
|
||||
"software_packageVersion" : "1.3.5",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(BUILD_LINKED_LIBRARIES [=[
|
||||
set(BUILD_LINKED_LIBRARIES_EXPECTED [=[
|
||||
{
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"description" : "Linked Libraries",
|
||||
"from" : "interface#Package",
|
||||
"relationshipType" : "DEPENDS_ON",
|
||||
"from" : "urn:interface#Package",
|
||||
"relationshipType" : "dependsOn",
|
||||
"spdxId" : "urn:Static#Relationship",
|
||||
"to" :
|
||||
[
|
||||
"bar:bar#Package"
|
||||
"urn:bar:bar#Package"
|
||||
],
|
||||
"type" : "Relationship"
|
||||
}
|
||||
@@ -83,11 +69,12 @@ set(BUILD_LINKED_LIBRARIES [=[
|
||||
|
||||
|
||||
expect_value("${content}" "https://spdx.org/rdf/3.0.1/spdx-context.jsonld" "@context")
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT)
|
||||
expect_object("${SPDX_DOCUMENT}" CREATION_INFO "creationInfo")
|
||||
expect_object("${SPDX_DOCUMENT}" INTERFACE "rootElement" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" DEPENDENCY "element" "0")
|
||||
string(JSON CREATION_INFO GET "${content}" "@graph" "0")
|
||||
expect_object("${CREATION_INFO}" CREATION_INFO_EXPECTED)
|
||||
|
||||
string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "1")
|
||||
expect_object("${LINKED_LIBRARIES}" BUILD_LINKED_LIBRARIES)
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "1")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT_EXPECTED)
|
||||
expect_object("${SPDX_DOCUMENT}" APPLICATION_EXPECTED "rootElement" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" DEPENDENCY_EXPECTED "element" "0")
|
||||
string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "2")
|
||||
expect_object("${LINKED_LIBRARIES}" BUILD_LINKED_LIBRARIES_EXPECTED)
|
||||
|
||||
@@ -1,81 +1,67 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(CREATION_INFO [=[
|
||||
set(CREATION_INFO_EXPECTED [=[
|
||||
{
|
||||
"comment" : "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdUsing" :
|
||||
"@id": "_:Build#CreationInfo",
|
||||
"comment": "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdBy":
|
||||
[
|
||||
{
|
||||
"@id" : "CMake#Agent",
|
||||
"name" : "CMake",
|
||||
"type" : "Tool"
|
||||
}
|
||||
"https://gitlab.kitware.com/cmake/cmake"
|
||||
],
|
||||
"type" : "CreationInfo"
|
||||
"specVersion": "3.0.1",
|
||||
"type": "CreationInfo"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(ELEMENTS [=[
|
||||
[
|
||||
{
|
||||
"@id" : "bar:bar#Package",
|
||||
"name" : "bar:bar",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]
|
||||
]=])
|
||||
|
||||
set(SPDX_DOCUMENT [=[
|
||||
set(SPDX_DOCUMENT_EXPECTED [=[
|
||||
{
|
||||
"@id" : "test_targets#SPDXDocument",
|
||||
"name": "test_targets",
|
||||
"profileConformance": ["core", "software"],
|
||||
"type": "SpdxDocument"
|
||||
"name" : "test_targets",
|
||||
"profileConformance" :
|
||||
[
|
||||
"core",
|
||||
"software"
|
||||
],
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"spdxId" : "urn:test_targets#SPDXDocument",
|
||||
"type" : "SpdxDocument"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(TEST [=[
|
||||
set(APPLICATION_EXPECTED [=[
|
||||
{
|
||||
"@id" : "test#Package",
|
||||
"externalRef" :
|
||||
[
|
||||
{
|
||||
"comment" : "Build System used for this target",
|
||||
"externalRefType" : "buildSystem",
|
||||
"locator" : "CMake#Agent",
|
||||
"type" : "ExternalRef"
|
||||
}
|
||||
],
|
||||
"spdxId" : "urn:test#Package",
|
||||
"name" : "test",
|
||||
"primaryPurpose" : "APPLICATION",
|
||||
"software_primaryPurpose" : "application",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(DEPENDENCY [=[
|
||||
set(DEPENDENCY_EXPECTED [=[
|
||||
{
|
||||
"@id" : "baz:baz#Package",
|
||||
"name" : "baz:baz",
|
||||
"spdxId" : "urn:bar:bar#Package",
|
||||
"name" : "bar:bar",
|
||||
"originatedBy" :
|
||||
[
|
||||
{
|
||||
"name" : "baz",
|
||||
"name" : "bar",
|
||||
"type" : "Organization"
|
||||
}
|
||||
],
|
||||
"packageVersion" : "1.8.5",
|
||||
"software_packageVersion" : "1.3.5",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(BUILD_LINKED_LIBRARIES [=[
|
||||
set(BUILD_LINKED_LIBRARIES_EXPECTED [=[
|
||||
{
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"description" : "Linked Libraries",
|
||||
"from" : "test#Package",
|
||||
"relationshipType" : "DEPENDS_ON",
|
||||
"from" : "urn:test#Package",
|
||||
"relationshipType" : "dependsOn",
|
||||
"spdxId" : "urn:Static#Relationship",
|
||||
"to" :
|
||||
[
|
||||
"baz:baz#Package"
|
||||
"urn:bar:bar#Package"
|
||||
],
|
||||
"type" : "Relationship"
|
||||
}
|
||||
@@ -83,11 +69,12 @@ set(BUILD_LINKED_LIBRARIES [=[
|
||||
|
||||
|
||||
expect_value("${content}" "https://spdx.org/rdf/3.0.1/spdx-context.jsonld" "@context")
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT)
|
||||
expect_object("${SPDX_DOCUMENT}" CREATION_INFO "creationInfo")
|
||||
expect_object("${SPDX_DOCUMENT}" TEST "rootElement" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" DEPENDENCY "element" "0")
|
||||
string(JSON CREATION_INFO GET "${content}" "@graph" "0")
|
||||
expect_object("${CREATION_INFO}" CREATION_INFO_EXPECTED)
|
||||
|
||||
string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "1")
|
||||
expect_object("${LINKED_LIBRARIES}" BUILD_LINKED_LIBRARIES)
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "1")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT_EXPECTED)
|
||||
expect_object("${SPDX_DOCUMENT}" APPLICATION_EXPECTED "rootElement" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" DEPENDENCY_EXPECTED "element" "0")
|
||||
string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "2")
|
||||
expect_object("${LINKED_LIBRARIES}" BUILD_LINKED_LIBRARIES_EXPECTED)
|
||||
|
||||
@@ -1,51 +1,46 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(CREATION_INFO [=[
|
||||
set(CREATION_INFO_EXPECTED [=[
|
||||
{
|
||||
"comment" : "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdUsing" :
|
||||
"@id": "_:Build#CreationInfo",
|
||||
"comment": "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdBy":
|
||||
[
|
||||
{
|
||||
"@id" : "CMake#Agent",
|
||||
"name" : "CMake",
|
||||
"type" : "Tool"
|
||||
}
|
||||
"https://gitlab.kitware.com/cmake/cmake"
|
||||
],
|
||||
"type" : "CreationInfo"
|
||||
"specVersion": "3.0.1",
|
||||
"type": "CreationInfo"
|
||||
}
|
||||
]=])
|
||||
|
||||
|
||||
set(SPDX_DOCUMENT [=[
|
||||
set(SPDX_DOCUMENT_EXPECTED [=[
|
||||
{
|
||||
"@id" : "test_targets#SPDXDocument",
|
||||
"name": "test_targets",
|
||||
"profileConformance": ["core", "software"],
|
||||
"type": "SpdxDocument"
|
||||
"name" : "test_targets",
|
||||
"profileConformance" :
|
||||
[
|
||||
"core",
|
||||
"software"
|
||||
],
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"spdxId" : "urn:test_targets#SPDXDocument",
|
||||
"type" : "SpdxDocument"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(TEST [=[
|
||||
set(APPLICATION_EXPECTED [=[
|
||||
{
|
||||
"@id" : "test#Package",
|
||||
"externalRef" :
|
||||
[
|
||||
{
|
||||
"comment" : "Build System used for this target",
|
||||
"externalRefType" : "buildSystem",
|
||||
"locator" : "CMake#Agent",
|
||||
"type" : "ExternalRef"
|
||||
}
|
||||
],
|
||||
"spdxId" : "urn:test#Package",
|
||||
"name" : "test",
|
||||
"primaryPurpose" : "LIBRARY",
|
||||
"software_primaryPurpose" : "application",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
|
||||
expect_value("${content}" "https://spdx.org/rdf/3.0.1/spdx-context.jsonld" "@context")
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT)
|
||||
expect_object("${SPDX_DOCUMENT}" CREATION_INFO "creationInfo")
|
||||
expect_object("${SPDX_DOCUMENT}" TEST "rootElement" "0")
|
||||
string(JSON CREATION_INFO GET "${content}" "@graph" "0")
|
||||
expect_object("${CREATION_INFO}" CREATION_INFO_EXPECTED)
|
||||
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "1")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT_EXPECTED)
|
||||
expect_object("${SPDX_DOCUMENT}" APPLICATION_EXPECTED "rootElement" "0")
|
||||
|
||||
@@ -3,6 +3,12 @@ include(${CMAKE_CURRENT_LIST_DIR}/Setup.cmake)
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
project(test LANGUAGES C
|
||||
DESCRIPTION "Metadata Test Project"
|
||||
SPDX_LICENSE "BSD-3"
|
||||
HOMEPAGE_URL "www.example.com"
|
||||
VERSION 1.2.0)
|
||||
|
||||
add_library(test INTERFACE)
|
||||
|
||||
install(
|
||||
|
||||
@@ -1,74 +1,81 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(CREATION_INFO [=[
|
||||
set(CREATION_INFO_EXPECTED [=[
|
||||
{
|
||||
"@id" : "_:Build#CreationInfo",
|
||||
"comment" : "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdUsing" :
|
||||
"created" : "2026-02-17T10:34:34Z",
|
||||
"createdBy" :
|
||||
[
|
||||
{
|
||||
"@id" : "CMake#Agent",
|
||||
"name" : "CMake",
|
||||
"type" : "Tool"
|
||||
}
|
||||
"https://gitlab.kitware.com/cmake/cmake"
|
||||
],
|
||||
"specVersion" : "3.0.1",
|
||||
"type" : "CreationInfo"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(SPDX_DOCUMENT [=[
|
||||
set(SPDX_DOCUMENT_EXPECTED [=[
|
||||
{
|
||||
"@id": "_:dog#SPDXDocument",
|
||||
"name": "dog",
|
||||
"profileConformance": ["core", "software"],
|
||||
"type": "SpdxDocument"
|
||||
"name" : "application_targets",
|
||||
"profileConformance" :
|
||||
[
|
||||
"core",
|
||||
"software"
|
||||
],
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"spdxId" : "urn:application_targets#SPDXDocument",
|
||||
"type" : "SpdxDocument"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(CANINE [=[
|
||||
set(APPLICATION_EXPECTED [=[
|
||||
{
|
||||
"@id" : "canine#Package",
|
||||
"externalRef" :
|
||||
"spdxId" : "application#Package",
|
||||
"name" : "application",
|
||||
"software_primaryPurpose" : "application",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(DEPENDENCY_EXPECTED [=[
|
||||
{
|
||||
"spdxId" : "bar:bar#Package",
|
||||
"name" : "bar:bar",
|
||||
"originatedBy" :
|
||||
[
|
||||
{
|
||||
"comment" : "Build System used for this target",
|
||||
"externalRefType" : "buildSystem",
|
||||
"locator" : "CMake#Agent",
|
||||
"type" : "ExternalRef"
|
||||
"name" : "bar",
|
||||
"type" : "Organization"
|
||||
}
|
||||
],
|
||||
"name" : "canine",
|
||||
"primaryPurpose" : "LIBRARY",
|
||||
"software_packageVersion" : "1.3.5",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(DEPENDENCY [=[
|
||||
set(BUILD_LINKED_LIBRARIES_EXPECTED [=[
|
||||
{
|
||||
"@id" : "mammal#Package",
|
||||
"name" : "mammal",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(BUILD_LINK_LIBRARIES [=[
|
||||
{
|
||||
"description" : "Required Build-Time Libraries",
|
||||
"from" : "canine#Package",
|
||||
"relationshipType" : "DEPENDS_ON",
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"description" : "Linked Libraries",
|
||||
"from" : "urn:application#Package",
|
||||
"relationshipType" : "dependsOn",
|
||||
"spdxId" : "urn:Static#Relationship",
|
||||
"to" :
|
||||
[
|
||||
"mammal#Package"
|
||||
"urn:bar:bar#Package"
|
||||
],
|
||||
"type" : "Relationship"
|
||||
}
|
||||
]=])
|
||||
|
||||
expect_value("${content}" "https://spdx.org/rdf/3.0.1/spdx-context.jsonld" "@context")
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT)
|
||||
expect_object("${SPDX_DOCUMENT}" CREATION_INFO "creationInfo")
|
||||
expect_object("${SPDX_DOCUMENT}" CANINE "rootElement" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" DEPENDENCY "element" "0")
|
||||
|
||||
string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "1")
|
||||
expect_object("${LINKED_LIBRARIES}" BUILD_LINK_LIBRARIES)
|
||||
expect_value("${content}" "https://spdx.org/rdf/3.0.1/spdx-context.jsonld" "@context")
|
||||
string(JSON CREATION_INFO GET "${content}" "@graph" "0")
|
||||
expect_object("${CREATION_INFO}" CREATION_INFO_EXPECTED)
|
||||
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "1")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT_EXPECTED)
|
||||
expect_object("${SPDX_DOCUMENT}" APPLICATION_EXPECTED "rootElement" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" DEPENDENCY_EXPECTED "element" "0")
|
||||
string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "2")
|
||||
expect_object("${LINKED_LIBRARIES}" BUILD_LINKED_LIBRARIES_EXPECTED)
|
||||
|
||||
@@ -2,15 +2,14 @@ include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(CREATION_INFO [=[
|
||||
{
|
||||
"@id" : "_:Build#CreationInfo",
|
||||
"comment" : "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdUsing" :
|
||||
"created" : "2026-02-17T10:34:30Z",
|
||||
"createdBy" :
|
||||
[
|
||||
{
|
||||
"@id" : "CMake#Agent",
|
||||
"name" : "CMake",
|
||||
"type" : "Tool"
|
||||
}
|
||||
"https://gitlab.kitware.com/cmake/cmake"
|
||||
],
|
||||
"specVersion" : "3.0.1",
|
||||
"type" : "CreationInfo"
|
||||
}
|
||||
]=])
|
||||
@@ -18,88 +17,75 @@ set(CREATION_INFO [=[
|
||||
|
||||
set(BAR_SPDX_DOCUMENT [=[
|
||||
{
|
||||
"@id" : "bar#SPDXDocument",
|
||||
"name": "bar",
|
||||
"profileConformance": ["core", "software"],
|
||||
"type": "SpdxDocument"
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"name" : "bar",
|
||||
"profileConformance" :
|
||||
[
|
||||
"core",
|
||||
"software"
|
||||
],
|
||||
"spdxId" : "urn:bar#SPDXDocument",
|
||||
"type" : "SpdxDocument"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(FOO_SPDX_DOCUMENT [=[
|
||||
{
|
||||
"@id" : "foo#SPDXDocument",
|
||||
"name": "foo",
|
||||
"profileConformance": ["core", "software"],
|
||||
"type": "SpdxDocument"
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"name" : "foo",
|
||||
"profileConformance" :
|
||||
[
|
||||
"core",
|
||||
"software"
|
||||
],
|
||||
"spdxId" : "urn:foo#SPDXDocument",
|
||||
"type" : "SpdxDocument"
|
||||
}
|
||||
]=])
|
||||
|
||||
|
||||
set(FOO_LIBB [=[
|
||||
{
|
||||
"@id" : "libb#Package",
|
||||
"externalRef" :
|
||||
[
|
||||
{
|
||||
"comment" : "Build System used for this target",
|
||||
"externalRefType" : "buildSystem",
|
||||
"locator" : "CMake#Agent",
|
||||
"type" : "ExternalRef"
|
||||
}
|
||||
],
|
||||
"name" : "libb",
|
||||
"primaryPurpose" : "LIBRARY",
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"name" : "libd",
|
||||
"software_primaryPurpose" : "library",
|
||||
"spdxId" : "urn:libd#Package",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(BAR_LIBC [=[
|
||||
{
|
||||
"@id" : "libc#Package",
|
||||
"externalRef" :
|
||||
[
|
||||
{
|
||||
"comment" : "Build System used for this target",
|
||||
"externalRefType" : "buildSystem",
|
||||
"locator" : "CMake#Agent",
|
||||
"type" : "ExternalRef"
|
||||
}
|
||||
],
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"name" : "libc",
|
||||
"primaryPurpose" : "LIBRARY",
|
||||
"software_primaryPurpose" : "library",
|
||||
"spdxId" : "urn:libc#Package",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(BAR_LIBD [=[
|
||||
{
|
||||
"@id" : "libd#Package",
|
||||
"externalRef" :
|
||||
[
|
||||
{
|
||||
"comment" : "Build System used for this target",
|
||||
"externalRefType" : "buildSystem",
|
||||
"locator" : "CMake#Agent",
|
||||
"type" : "ExternalRef"
|
||||
}
|
||||
],
|
||||
"spdxId" : "urn:libd#Package",
|
||||
"name" : "libd",
|
||||
"primaryPurpose" : "LIBRARY",
|
||||
"software_primaryPurpose" : "LIBRARY",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(BAR_DEPENDENCY_TEST [=[
|
||||
{
|
||||
"@id" : "test:liba#Package",
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"name" : "test:liba",
|
||||
"originatedBy" :
|
||||
[
|
||||
{
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"name" : "test",
|
||||
"spdxId" : "urn:test#Organization",
|
||||
"type" : "Organization"
|
||||
}
|
||||
],
|
||||
"spdxId" : "urn:test:liba#Package",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
@@ -107,30 +93,46 @@ set(BAR_DEPENDENCY_TEST [=[
|
||||
|
||||
set(BAR_DEPENDENCY_FOO [=[
|
||||
{
|
||||
"@id" : "foo:libb#Package",
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"name" : "foo:libb",
|
||||
"originatedBy" :
|
||||
[
|
||||
{
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"name" : "foo",
|
||||
"spdxId" : "urn:foo#Organization",
|
||||
"type" : "Organization"
|
||||
}
|
||||
],
|
||||
"spdxId" : "urn:foo:libb#Package",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
|
||||
set(CREATION_INFO_EXPECTED [=[
|
||||
{
|
||||
"@id": "_:Build#CreationInfo",
|
||||
"comment": "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdBy":
|
||||
[
|
||||
"https://gitlab.kitware.com/cmake/cmake"
|
||||
],
|
||||
"specVersion": "3.0.1",
|
||||
"type": "CreationInfo"
|
||||
}
|
||||
]=])
|
||||
|
||||
expect_value("${FOO_CONTENT}" "https://spdx.org/rdf/3.0.1/spdx-context.jsonld" "@context")
|
||||
string(JSON FOO_SPDX_DOCUMENT GET "${FOO_CONTENT}" "@graph" "0")
|
||||
string(JSON FOO_CREATION_INFO GET "${FOO_CONTENT}" "@graph" "0")
|
||||
string(JSON FOO_SPDX_DOCUMENT GET "${FOO_CONTENT}" "@graph" "1")
|
||||
expect_object("${FOO_SPDX_DOCUMENT}" FOO_SPDX_DOCUMENT)
|
||||
expect_object("${FOO_SPDX_DOCUMENT}" CREATION_INFO "creationInfo")
|
||||
expect_object("${FOO_SPDX_DOCUMENT}" FOO_LIBB "rootElement" "0")
|
||||
|
||||
expect_value("${BAR_CONTENT}" "https://spdx.org/rdf/3.0.1/spdx-context.jsonld" "@context")
|
||||
string(JSON BAR_SPDX_DOCUMENT GET "${BAR_CONTENT}" "@graph" "0")
|
||||
string(JSON BAR_CREATION_INFO GET "${BAR_CONTENT}" "@graph" "0")
|
||||
string(JSON BAR_SPDX_DOCUMENT GET "${BAR_CONTENT}" "@graph" "1")
|
||||
expect_object("${BAR_SPDX_DOCUMENT}" BAR_SPDX_DOCUMENT)
|
||||
expect_object("${BAR_SPDX_DOCUMENT}" CREATION_INFO "creationInfo")
|
||||
expect_object("${BAR_SPDX_DOCUMENT}" BAR_LIBC "rootElement" "0")
|
||||
expect_object("${BAR_SPDX_DOCUMENT}" BAR_LIBD "rootElement" "1")
|
||||
expect_object("${BAR_SPDX_DOCUMENT}" BAR_DEPENDENCY_TEST "element" "0")
|
||||
|
||||
@@ -1,81 +1,67 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
|
||||
|
||||
set(CREATION_INFO [=[
|
||||
set(CREATION_INFO_EXPECTED [=[
|
||||
{
|
||||
"comment" : "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdUsing" :
|
||||
"@id": "_:Build#CreationInfo",
|
||||
"comment": "This SBOM was generated from the CMakeLists.txt File",
|
||||
"createdBy":
|
||||
[
|
||||
{
|
||||
"@id" : "CMake#Agent",
|
||||
"name" : "CMake",
|
||||
"type" : "Tool"
|
||||
}
|
||||
"https://gitlab.kitware.com/cmake/cmake"
|
||||
],
|
||||
"type" : "CreationInfo"
|
||||
"specVersion": "3.0.1",
|
||||
"type": "CreationInfo"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(ELEMENTS [=[
|
||||
[
|
||||
{
|
||||
"@id" : "foo:foo#Package",
|
||||
"name" : "foo:foo",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]
|
||||
]=])
|
||||
|
||||
set(SPDX_DOCUMENT [=[
|
||||
set(SPDX_DOCUMENT_EXPECTED [=[
|
||||
{
|
||||
"@id" : "shared_targets#SPDXDocument",
|
||||
"name": "shared_targets",
|
||||
"profileConformance": ["core", "software"],
|
||||
"type": "SpdxDocument"
|
||||
"name" : "application_targets",
|
||||
"profileConformance" :
|
||||
[
|
||||
"core",
|
||||
"software"
|
||||
],
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"spdxId" : "urn:application_targets#SPDXDocument",
|
||||
"type" : "SpdxDocument"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(SHARED [=[
|
||||
set(APPLICATION_EXPECTED [=[
|
||||
{
|
||||
"@id" : "shared#Package",
|
||||
"externalRef" :
|
||||
[
|
||||
{
|
||||
"comment" : "Build System used for this target",
|
||||
"externalRefType" : "buildSystem",
|
||||
"locator" : "CMake#Agent",
|
||||
"type" : "ExternalRef"
|
||||
}
|
||||
],
|
||||
"name" : "shared",
|
||||
"primaryPurpose" : "LIBRARY",
|
||||
"spdxId" : "application#Package",
|
||||
"name" : "application",
|
||||
"software_primaryPurpose" : "application",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(DEPENDENCY [=[
|
||||
set(DEPENDENCY_EXPECTED [=[
|
||||
{
|
||||
"@id" : "foo:foo#Package",
|
||||
"name" : "foo:foo",
|
||||
"spdxId" : "bar:bar#Package",
|
||||
"name" : "bar:bar",
|
||||
"originatedBy" :
|
||||
[
|
||||
{
|
||||
"name" : "foo",
|
||||
"name" : "bar",
|
||||
"type" : "Organization"
|
||||
}
|
||||
],
|
||||
"packageVersion" : "1.2.3",
|
||||
"software_packageVersion" : "1.3.5",
|
||||
"type" : "software_Package"
|
||||
}
|
||||
]=])
|
||||
|
||||
set(BUILD_LINKED_LIBRARIES [=[
|
||||
set(BUILD_LINKED_LIBRARIES_EXPECTED [=[
|
||||
{
|
||||
"creationInfo" : "_:Build#CreationInfo",
|
||||
"description" : "Linked Libraries",
|
||||
"from" : "shared#Package",
|
||||
"relationshipType" : "DEPENDS_ON",
|
||||
"from" : "urn:application#Package",
|
||||
"relationshipType" : "dependsOn",
|
||||
"spdxId" : "urn:Static#Relationship",
|
||||
"to" :
|
||||
[
|
||||
"foo:foo#Package"
|
||||
"urn:bar:bar#Package"
|
||||
],
|
||||
"type" : "Relationship"
|
||||
}
|
||||
@@ -83,11 +69,12 @@ set(BUILD_LINKED_LIBRARIES [=[
|
||||
|
||||
|
||||
expect_value("${content}" "https://spdx.org/rdf/3.0.1/spdx-context.jsonld" "@context")
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT)
|
||||
expect_object("${SPDX_DOCUMENT}" CREATION_INFO "creationInfo")
|
||||
expect_object("${SPDX_DOCUMENT}" SHARED "rootElement" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" DEPENDENCY "element" "0")
|
||||
string(JSON CREATION_INFO GET "${content}" "@graph" "0")
|
||||
expect_object("${CREATION_INFO}" CREATION_INFO_EXPECTED)
|
||||
|
||||
string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "1")
|
||||
expect_object("${LINKED_LIBRARIES}" BUILD_LINKED_LIBRARIES)
|
||||
string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "1")
|
||||
expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT_EXPECTED)
|
||||
expect_object("${SPDX_DOCUMENT}" APPLICATION_EXPECTED "rootElement" "0")
|
||||
expect_object("${SPDX_DOCUMENT}" DEPENDENCY_EXPECTED "element" "0")
|
||||
string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "2")
|
||||
expect_object("${LINKED_LIBRARIES}" BUILD_LINKED_LIBRARIES_EXPECTED)
|
||||
|
||||
Reference in New Issue
Block a user