From 52157acbfee52cebd1ac7969ce5238accdc56152 Mon Sep 17 00:00:00 2001
From: qu1ck <anlutsenko@gmail.com>
Date: Mon, 30 May 2022 16:26:24 -0700
Subject: [PATCH] PCM: fix kicad version restriction logic

The json schema for packages implies that kicad min/max version
restriction takes major.minor.patch string but actual logic
only checks major and minor.

This fixes the logic to work with full major.minor.patch tuple.
Additionally the version max logic will substitute missing portions
with 999 for a reasonable default so that say 7.1 is still considered
as >= 7.1.5 when checking for max version.

Reported here
https://forum.kicad.info/t/updating-already-installed-plugins-using-content-manager/35532/5?u=qu1ck

(cherry picked from commit 06028d50155f0f5b240a9748f6f06fb66269cd72)
---
 .../BuildSteps/WriteVersionHeader.cmake       |  4 +--
 kicad/pcm/pcm.cpp                             | 29 +++++++++++++------
 kicad/pcm/pcm.h                               |  2 +-
 3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/CMakeModules/BuildSteps/WriteVersionHeader.cmake b/CMakeModules/BuildSteps/WriteVersionHeader.cmake
index 2214bc6f2c5..9920445395b 100644
--- a/CMakeModules/BuildSteps/WriteVersionHeader.cmake
+++ b/CMakeModules/BuildSteps/WriteVersionHeader.cmake
@@ -36,9 +36,9 @@ string( REGEX MATCH
 if( CMAKE_MATCH_COUNT EQUAL 3 )
     # Match slot 0 is the full string, so we want slots 1 & 2
     set( KICAD_MAJOR_MINOR_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" )
-    set( KICAD_MAJOR_MINOR_VERSION_TUPLE "{ ${CMAKE_MATCH_1}, ${CMAKE_MATCH_2} }" )
 
     set( KICAD_MAJOR_MINOR_PATCH_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" )
+    set( KICAD_MAJOR_MINOR_PATCH_TUPLE "{ ${CMAKE_MATCH_1}, ${CMAKE_MATCH_2}, ${CMAKE_MATCH_3} }" )
 
     set( KICAD_MAJOR_VERSION "${CMAKE_MATCH_1}" )
     set( KICAD_MINOR_VERSION "${CMAKE_MATCH_2}" )
@@ -67,7 +67,7 @@ set( _wvh_new_version_text
 #define KICAD_MINOR_VERSION             \"${KICAD_MINOR_VERSION}\"
 #define KICAD_PATCH_VERSION             \"${KICAD_PATCH_VERSION}\"
 #define KICAD_MAJOR_MINOR_VERSION       \"${KICAD_MAJOR_MINOR_VERSION}\"
-#define KICAD_MAJOR_MINOR_VERSION_TUPLE ${KICAD_MAJOR_MINOR_VERSION_TUPLE}
+#define KICAD_MAJOR_MINOR_PATCH_TUPLE   ${KICAD_MAJOR_MINOR_PATCH_TUPLE}
 #define KICAD_WIN32_RC_PRODVER          ${KICAD_WIN32_RC_PRODVER}
 #define KICAD_WIN32_RC_PRODVER_STR      \"${KICAD_WIN32_RC_PRODVER_STR}\"
 #define KICAD_WIN32_RC_FILEVER          ${KICAD_WIN32_RC_FILEVER}
diff --git a/kicad/pcm/pcm.cpp b/kicad/pcm/pcm.cpp
index 7be455f3f18..5b0b5f09eda 100644
--- a/kicad/pcm/pcm.cpp
+++ b/kicad/pcm/pcm.cpp
@@ -45,8 +45,8 @@
 #include <wx/zipstrm.h>
 
 
-const std::tuple<int, int> PLUGIN_CONTENT_MANAGER::m_kicad_version =
-        KICAD_MAJOR_MINOR_VERSION_TUPLE;
+const std::tuple<int, int, int> PLUGIN_CONTENT_MANAGER::m_kicad_version =
+        KICAD_MAJOR_MINOR_PATCH_TUPLE;
 
 
 class THROWING_ERROR_HANDLER : public nlohmann::json_schema::error_handler
@@ -510,19 +510,30 @@ void PLUGIN_CONTENT_MANAGER::preparePackage( PCM_PACKAGE& aPackage )
         // Determine compatibility
         ver.compatible = true;
 
-        auto parse_major_minor = []( const wxString& version )
+        auto parse_version_tuple = []( const wxString& version, int deflt )
         {
-            wxStringTokenizer tokenizer( version, wxT( "." ) );
-            int               ver_major = wxAtoi( tokenizer.GetNextToken() );
-            int               ver_minor = wxAtoi( tokenizer.GetNextToken() );
-            return std::tuple<int, int>( ver_major, ver_minor );
+            int ver_major = deflt;
+            int ver_minor = deflt;
+            int ver_patch = deflt;
+
+            wxStringTokenizer tokenizer( version, "." );
+
+            ver_major = wxAtoi( tokenizer.GetNextToken() );
+
+            if( tokenizer.HasMoreTokens() )
+                ver_minor = wxAtoi( tokenizer.GetNextToken() );
+
+            if( tokenizer.HasMoreTokens() )
+                ver_patch = wxAtoi( tokenizer.GetNextToken() );
+
+            return std::tuple<int, int, int>( ver_major, ver_minor, ver_patch );
         };
 
-        if( parse_major_minor( ver.kicad_version ) > m_kicad_version )
+        if( parse_version_tuple( ver.kicad_version, 0 ) > m_kicad_version )
             ver.compatible = false;
 
         if( ver.kicad_version_max
-            && parse_major_minor( ver.kicad_version_max.get() ) < m_kicad_version )
+            && parse_version_tuple( ver.kicad_version_max.get(), 999 ) < m_kicad_version )
             ver.compatible = false;
 
 #ifdef __WXMSW__
diff --git a/kicad/pcm/pcm.h b/kicad/pcm/pcm.h
index 9c6c8d0458e..ef8829c0971 100644
--- a/kicad/pcm/pcm.h
+++ b/kicad/pcm/pcm.h
@@ -313,7 +313,7 @@ private:
     STRING_TUPLE_LIST                            m_repository_list; // (id, name, url) tuples
     // Using sorted map to keep order of entries in installed list stable
     std::map<wxString, PCM_INSTALLATION_ENTRY> m_installed;
-    const static std::tuple<int, int>          m_kicad_version;
+    const static std::tuple<int, int, int>     m_kicad_version;
 };
 
 #endif // PCM_H_
-- 
GitLab