Merge topic 'cps-validate-version'

cc508826b4 CPS: Validate package version
fb66a14da2 cmExportFileGenerator: Allow other message types

Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !11458
This commit is contained in:
Brad King
2025-12-02 20:43:27 +00:00
committed by Kitware Robot
25 changed files with 250 additions and 18 deletions

View File

@@ -16,7 +16,6 @@
#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmTarget.h"
@@ -242,12 +241,11 @@ void cmExportBuildFileGenerator::ComplainAboutDuplicateTarget(
this->ReportError(e.str());
}
void cmExportBuildFileGenerator::ReportError(
std::string const& errorMessage) const
void cmExportBuildFileGenerator::IssueMessage(MessageType type,
std::string const& message) const
{
this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR, errorMessage,
this->LG->GetMakefile()->GetBacktrace());
type, message, this->LG->GetMakefile()->GetBacktrace());
}
std::string cmExportBuildFileGenerator::InstallNameDir(

View File

@@ -86,7 +86,8 @@ protected:
void ComplainAboutDuplicateTarget(
std::string const& targetName) const override;
void ReportError(std::string const& errorMessage) const override;
void IssueMessage(MessageType type,
std::string const& message) const override;
/** Fill in properties indicating built file locations. */
void SetImportLocationProperty(std::string const& config,

View File

@@ -32,7 +32,7 @@ bool cmExportBuildPackageInfoGenerator::GenerateMainFile(std::ostream& os)
return false;
}
if (!this->CheckDefaultTargets()) {
if (!this->CheckPackage()) {
return false;
}

View File

@@ -13,6 +13,7 @@
#include <cm/string_view>
#include "cmGeneratorExpression.h"
#include "cmMessageType.h"
class cmExportSet;
class cmGeneratorTarget;
@@ -120,7 +121,13 @@ protected:
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties);
virtual void ReportError(std::string const& errorMessage) const = 0;
virtual void IssueMessage(MessageType type,
std::string const& message) const = 0;
void ReportError(std::string const& errorMessage) const
{
this->IssueMessage(MessageType::FATAL_ERROR, errorMessage);
}
struct ExportInfo
{

View File

@@ -335,11 +335,11 @@ void cmExportInstallFileGenerator::ComplainAboutDuplicateTarget(
this->ReportError(e.str());
}
void cmExportInstallFileGenerator::ReportError(
std::string const& errorMessage) const
void cmExportInstallFileGenerator::IssueMessage(
MessageType type, std::string const& message) const
{
this->IEGen->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR, errorMessage,
type, message,
this->IEGen->GetLocalGenerator()->GetMakefile()->GetBacktrace());
}

View File

@@ -94,7 +94,8 @@ protected:
ExportInfo FindExportInfo(cmGeneratorTarget const* target) const override;
void ReportError(std::string const& errorMessage) const override;
void IssueMessage(MessageType type,
std::string const& message) const override;
/** Generate a per-configuration file for the targets. */
virtual bool GenerateImportFileConfig(std::string const& config);

View File

@@ -66,7 +66,7 @@ bool cmExportInstallPackageInfoGenerator::GenerateMainFile(std::ostream& os)
}
}
if (!this->CheckDefaultTargets()) {
if (!this->CheckPackage()) {
return false;
}

View File

@@ -16,6 +16,8 @@
#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>
#include "cmsys/RegularExpression.hxx"
#include "cmArgumentParserTypes.h"
#include "cmExportSet.h"
#include "cmFindPackageStack.h"
@@ -88,6 +90,63 @@ void BuildArray(Json::Value& object, std::string const& property,
}
}
}
bool CheckSimpleVersion(std::string const& version)
{
cmsys::RegularExpression regex("^[0-9]+([.][0-9]+)*([-+].*)?$");
return regex.find(version);
}
}
bool cmExportPackageInfoGenerator::CheckVersion() const
{
if (!this->PackageVersion.empty()) {
std::string const& schema = [&] {
if (this->PackageVersionSchema.empty()) {
return std::string{ "simple" };
}
return cmSystemTools::LowerCase(this->PackageVersionSchema);
}();
bool (*validator)(std::string const&) = nullptr;
bool result = true;
if (schema == "simple"_s) {
validator = &CheckSimpleVersion;
} else if (schema == "dpkg"_s || schema == "rpm"_s ||
schema == "pep440"_s) {
// TODO
// We don't validate these at this time. Eventually, we would like to do
// so, but will probably need to introduce a policy whether to treat
// invalid versions as an error.
} else if (schema != "custom"_s) {
this->IssueMessage(MessageType::AUTHOR_WARNING,
cmStrCat("Package \""_s, this->GetPackageName(),
"\" uses unrecognized version schema \""_s,
this->PackageVersionSchema, "\"."_s));
}
if (validator) {
if (!(*validator)(this->PackageVersion)) {
this->ReportError(cmStrCat("Package \""_s, this->GetPackageName(),
"\" version \""_s, this->PackageVersion,
"\" does not conform to the \""_s, schema,
"\" schema."_s));
result = false;
}
if (!this->PackageVersionCompat.empty() &&
!(*validator)(this->PackageVersionCompat)) {
this->ReportError(
cmStrCat("Package \""_s, this->GetPackageName(),
"\" compatibility version \""_s, this->PackageVersionCompat,
"\" does not conform to the \""_s, schema, "\" schema."_s));
result = false;
}
}
return result;
}
return true;
}
bool cmExportPackageInfoGenerator::CheckDefaultTargets() const

View File

@@ -47,7 +47,10 @@ protected:
// Methods to implement export file code generation.
bool GenerateImportFile(std::ostream& os) override;
bool CheckDefaultTargets() const;
bool CheckPackage() const
{
return this->CheckVersion() && this->CheckDefaultTargets();
}
Json::Value GeneratePackageInfo() const;
Json::Value* GenerateImportTarget(Json::Value& components,
@@ -82,6 +85,9 @@ protected:
cmGeneratorTarget const* linkedTarget) override;
private:
bool CheckVersion() const;
bool CheckDefaultTargets() const;
void GenerateInterfaceLinkProperties(
bool& result, Json::Value& component, cmGeneratorTarget const* target,
ImportPropertyMap const& properties) const;

View File

@@ -6,6 +6,7 @@
#include <utility>
#include <cm/memory>
#include <cmext/string_view>
#include "cmFileSet.h"
#include "cmGenExContext.h"
@@ -16,6 +17,7 @@
#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -31,10 +33,25 @@ cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator(
gg->CreateImportedGenerationObjects(mf, targets, this->Exports);
}
void cmExportTryCompileFileGenerator::ReportError(
std::string const& errorMessage) const
void cmExportTryCompileFileGenerator::IssueMessage(
MessageType type, std::string const& message) const
{
cmSystemTools::Error(errorMessage);
switch (type) {
case MessageType::FATAL_ERROR:
case MessageType::AUTHOR_ERROR:
case MessageType::INTERNAL_ERROR:
case MessageType::DEPRECATION_ERROR:
cmSystemTools::Error(message);
break;
case MessageType::WARNING:
case MessageType::AUTHOR_WARNING:
case MessageType::DEPRECATION_WARNING:
cmSystemTools::Message(cmStrCat("CMake Warning: "_s, message),
"Warning");
break;
default:
cmSystemTools::Message(message);
}
}
bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)

View File

@@ -30,7 +30,8 @@ protected:
// Implement virtual methods from the superclass.
void ComplainAboutDuplicateTarget(
std::string const& /*targetName*/) const override {};
void ReportError(std::string const& errorMessage) const override;
void IssueMessage(MessageType type,
std::string const& message) const override;
bool GenerateMainFile(std::ostream& os) override;

View File

@@ -4,6 +4,10 @@ include(RunCMake)
run_cmake(ExperimentalGate)
run_cmake(ExperimentalWarning)
# Test version check author warning
# TODO Move to be with other tests when experimental gate is removed.
run_cmake(VersionCheckWarning)
# Enable experimental feature and suppress warnings
set(RunCMake_TEST_OPTIONS
-Wno-dev
@@ -49,3 +53,6 @@ run_cmake(FileSetHeaders)
run_cmake(DependencyVersionCMake)
run_cmake(DependencyVersionCps)
run_cmake(TransitiveSymbolicComponent)
run_cmake(VersionCheck)
# run_cmake(VersionCheckWarning)
run_cmake(VersionCheckError)

View File

@@ -0,0 +1,38 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
# Try exporting a 'properly' simple version.
export(EXPORT foo PACKAGE_INFO foo1 VERSION 1.2.3)
# Try exporting a version with many components.
export(EXPORT foo PACKAGE_INFO foo2 VERSION 1.21.23.33.37.42.9.0.12)
# Try exporting a version with a label.
export(EXPORT foo PACKAGE_INFO foo3 VERSION "1.2.3+git1234abcd")
# Try exporting a version with a different label.
export(EXPORT foo PACKAGE_INFO foo4 VERSION "1.2.3-0.example")
# Try exporting with the schema explicitly specified.
export(
EXPORT foo
PACKAGE_INFO foo5
VERSION "1.2.3-0.example"
VERSION_SCHEMA "simple"
)
# Try exporting with a custom-schema version.
export(
EXPORT foo
PACKAGE_INFO foo6
VERSION "foo!test"
VERSION_SCHEMA "custom"
)
# Try exporting with a recognized but not-checked schema.
export(
EXPORT foo
PACKAGE_INFO foo7
VERSION "invalid"
VERSION_SCHEMA "pep440"
)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,2 @@
CMake Error in CMakeLists\.txt:
Package "foo" version "1.2.3rc1" does not conform to the "simple" schema\.

View File

@@ -0,0 +1,5 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
# Try exporting a non-conforming version.
export(EXPORT foo PACKAGE_INFO foo VERSION "1.2.3rc1")

View File

@@ -0,0 +1,3 @@
CMake Warning \(dev\) in CMakeLists\.txt:
Package "foo" uses unrecognized version schema "unrecognized"\.
This warning is for project developers\. Use -Wno-dev to suppress it\.

View File

@@ -0,0 +1,15 @@
set(
CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
"b80be207-778e-46ba-8080-b23bba22639e"
)
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
# Try exporting with an unrecognized schema.
export(
EXPORT foo
PACKAGE_INFO foo
VERSION "irrelevant"
VERSION_SCHEMA "unrecognized"
)

View File

@@ -4,6 +4,10 @@ include(RunCMake)
run_cmake(ExperimentalGate)
run_cmake(ExperimentalWarning)
# Test version check author warning
# TODO Move to be with other tests when experimental gate is removed.
run_cmake(VersionCheckWarning)
# Enable experimental feature and suppress warnings
set(RunCMake_TEST_OPTIONS
-Wno-dev
@@ -58,4 +62,7 @@ run_cmake(DependencyVersionCMake)
run_cmake(DependencyVersionCps)
run_cmake(TransitiveSymbolicComponent)
run_cmake(InstallSymbolicComponent)
run_cmake(VersionCheck)
# run_cmake(VersionCheckWarning)
run_cmake(VersionCheckError)
run_cmake_install(Destination)

View File

@@ -0,0 +1,38 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
# Try exporting a 'properly' simple version.
install(PACKAGE_INFO foo1 EXPORT foo VERSION 1.2.3)
# Try exporting a version with many components.
install(PACKAGE_INFO foo2 EXPORT foo VERSION 1.21.23.33.37.42.9.0.12)
# Try exporting a version with a label.
install(PACKAGE_INFO foo3 EXPORT foo VERSION "1.2.3+git1234abcd")
# Try exporting a version with a different label.
install(PACKAGE_INFO foo4 EXPORT foo VERSION "1.2.3-0.example")
# Try exporting with the schema explicitly specified.
install(
PACKAGE_INFO foo5
EXPORT foo
VERSION "1.2.3-0.example"
VERSION_SCHEMA "simple"
)
# Try exporting with a custom-schema version.
install(
PACKAGE_INFO foo6
EXPORT foo
VERSION "foo!test"
VERSION_SCHEMA "custom"
)
# Try exporting with a recognized but not-checked schema.
install(
PACKAGE_INFO foo7
EXPORT foo
VERSION "invalid"
VERSION_SCHEMA "pep440"
)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,2 @@
CMake Error in CMakeLists\.txt:
Package "foo" version "1.2.3rc1" does not conform to the "simple" schema\.

View File

@@ -0,0 +1,5 @@
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
# Try exporting a non-conforming version.
install(PACKAGE_INFO foo EXPORT foo VERSION "1.2.3rc1")

View File

@@ -0,0 +1,3 @@
CMake Warning \(dev\) in CMakeLists\.txt:
Package "foo" uses unrecognized version schema "unrecognized"\.
This warning is for project developers\. Use -Wno-dev to suppress it\.

View File

@@ -0,0 +1,15 @@
set(
CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
"b80be207-778e-46ba-8080-b23bba22639e"
)
add_library(foo INTERFACE)
install(TARGETS foo EXPORT foo DESTINATION .)
# Try exporting with an unrecognized schema.
install(
PACKAGE_INFO foo
EXPORT foo
VERSION "irrelevant"
VERSION_SCHEMA "unrecognized"
)