diff --git a/meson.build b/meson.build index 89318c9..7c5aef2 100644 --- a/meson.build +++ b/meson.build @@ -14,6 +14,19 @@ dep_cli11 = dependency('CLI11', version: '>=2.1') dep_expected = dependency('tl-expected', version : '>= 1.0', modules : ['tl::expected']) dep_json = dependency('nlohmann_json', version : '>= 3.7') dep_fmt = dependency('fmt', version : '>= 8') +dep_rpm_version = dependency( + 'rpm-version-c++', + version : '>= 0.3.0', + required : false, + allow_fallback : true, + default_options : ['default_library=static'], +) +if dep_rpm_version.found() + dep_rpm_version = declare_dependency( + dependencies : dep_rpm_version, + compile_args : '-DCPS_HAVE_RPM_VERSION', + ) +endif cpp = meson.get_compiler('cpp') diff --git a/src/cps/version.cpp b/src/cps/version.cpp index 7a2c52f..0b2cb7c 100644 --- a/src/cps/version.cpp +++ b/src/cps/version.cpp @@ -8,6 +8,9 @@ #include "cps/utils.hpp" #include +#ifdef CPS_HAVE_RPM_VERSION +#include +#endif #include @@ -97,16 +100,52 @@ namespace cps::version { return (op == Operator::eq || op == Operator::le || op == Operator::ge); } +#ifdef CPS_HAVE_RPM_VERSION + RPMVersion::Operator to_rpm_op(const Operator op) { + switch (op) { + case Operator::eq: + return RPMVersion::Operator::eq; + case Operator::ne: + return RPMVersion::Operator::ne; + case Operator::ge: + return RPMVersion::Operator::ge; + case Operator::gt: + return RPMVersion::Operator::gt; + case Operator::le: + return RPMVersion::Operator::le; + case Operator::lt: + return RPMVersion::Operator::lt; + default: + throw std::runtime_error{"This should not be possible"}; + } + } +#endif + } // namespace tl::expected compare(std::string_view left, Operator op, std::string_view right, Schema schema) { + std::string msg{}; + switch (schema) { case Schema::simple: return simple_compare(left, op, right); + case Schema::rpm: +#ifdef CPS_HAVE_RPM_VERSION + return RPMVersion::compare(left, to_rpm_op(op), right); +#else + msg = "RPM Compatible version comparison is not enabled"; + break; +#endif + case Schema::dpkg: + msg = "DPKG Compatible version comparison is not implemented"; + break; default: - fmt::print(stderr, "Only the simple schema is implemented"); - return "Only the simple schema is implemented."; + msg = "The requested version comparison method is not implemented"; + break; } + + fmt::print(stderr, msg); + return tl::unexpected{msg}; } } // namespace cps::version diff --git a/src/meson.build b/src/meson.build index bc25d20..1dba8bf 100644 --- a/src/meson.build +++ b/src/meson.build @@ -15,7 +15,7 @@ libcps = static_library( 'cps/utils.cpp', 'cps/version.cpp', conf_h, - dependencies : [dep_json, dep_expected, dep_fmt], + dependencies : [dep_json, dep_expected, dep_fmt, dep_rpm_version], cpp_args : warn_args, include_directories: [cps_include_dir, conf_include_dir], ) diff --git a/subprojects/rpm-version.wrap b/subprojects/rpm-version.wrap new file mode 100644 index 0000000..92c32bb --- /dev/null +++ b/subprojects/rpm-version.wrap @@ -0,0 +1,10 @@ +[wrap-file] +directory = rpm-version-0.3.0 + +source_url = https://github.com/dcbaker/rpm-version/archive/refs/tags/0.3.0.tar.gz +source_filename = rpm-version-0.3.0.tar.gz +source_hash = a5b7ae1a1e69fbe3ee529af719ef8a7e46a97a2cfc94c470834b83a346750623 + +[provide] +rpm-version-c = dep_rpm_ver_c +rpm-version-c++ = dep_rpm_ver_cpp diff --git a/tests/cases/rpm-version.toml b/tests/cases/rpm-version.toml new file mode 100644 index 0000000..267a8d9 --- /dev/null +++ b/tests/cases/rpm-version.toml @@ -0,0 +1,5 @@ +[[case]] +name = "version" +cps = "rpm-version-compare" +args = ["--version"] +expected = "0.0.1"