Skip to content

Commit cb8c7fb

Browse files
author
PyCompiler ARK++
committed
feat: Add version metadata to engines and improve version parsing
- Add version, required_core_version, and required_sdk_version to all engines (cx_freeze, nuitka, pyinstaller) - Improve parse_version() to support '1.0.0+' format (+ means 'or higher') - Support multiple version formats: '1.0.0', '1.0.0+', '1.0.0-beta', '1.0.0+build123' - Update bcasl validator and Base.py with improved version parsing - Clarify version compatibility semantics (>= greater than or equal) - All compatibility checks now use consistent >= semantics across engines and plugins
1 parent 2743e8a commit cb8c7fb

6 files changed

Lines changed: 114 additions & 11 deletions

File tree

Core/engines_loader/validator.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,29 @@ class EngineCompatibilityCheckResult:
3939

4040

4141
def parse_version(version_string: str) -> Tuple[int, int, int]:
42-
"""Parse a version string into (major, minor, patch)."""
42+
"""
43+
Parse a version string into (major, minor, patch).
44+
45+
Supports formats:
46+
- "1.0.0" -> (1, 0, 0)
47+
- "1.0.0+" -> (1, 0, 0) [+ means "or higher"]
48+
- "1.0.0-beta" -> (1, 0, 0)
49+
- "1.0.0+build123" -> (1, 0, 0)
50+
"""
4351
try:
44-
parts = version_string.strip().split("+")[0].split("-")[0].split(".")
52+
# Remove leading/trailing whitespace
53+
s = version_string.strip()
54+
55+
# Handle "1.0.0+" format (+ at the end means "or higher")
56+
# We just strip it since our comparison logic already uses >= semantics
57+
if s.endswith("+"):
58+
s = s[:-1].strip()
59+
60+
# Remove build metadata and pre-release identifiers
61+
s = s.split("+")[0].split("-")[0]
62+
63+
# Parse major.minor.patch
64+
parts = s.split(".")
4565
major = int(parts[0]) if len(parts) > 0 else 0
4666
minor = int(parts[1]) if len(parts) > 1 else 0
4767
patch = int(parts[2]) if len(parts) > 2 else 0
@@ -57,6 +77,10 @@ def check_engine_compatibility(
5777
) -> EngineCompatibilityCheckResult:
5878
"""
5979
Check if an engine is compatible with the current system versions.
80+
81+
Compatibility check uses >= (greater than or equal) semantics:
82+
- If engine requires Core 1.0.0, it accepts Core 1.0.0, 1.0.1, 1.1.0, 2.0.0, etc.
83+
- If engine requires SDK 1.0.0, it accepts SDK 1.0.0, 1.0.1, 1.1.0, 2.0.0, etc.
6084
6185
Args:
6286
engine_class: CompilerEngine class
@@ -74,15 +98,15 @@ def check_engine_compatibility(
7498
required_core_version = getattr(engine_class, "required_core_version", "1.0.0")
7599
required_sdk_version = getattr(engine_class, "required_sdk_version", "1.0.0")
76100

77-
# Check Core compatibility
101+
# Check Core compatibility: current >= required (accept equal or higher versions)
78102
current_core = parse_version(core_version)
79103
required_core = parse_version(required_core_version)
80104
if current_core < required_core:
81105
missing_requirements.append(
82106
f"Core >= {required_core_version} (current: {core_version})"
83107
)
84108

85-
# Check Engine SDK compatibility
109+
# Check Engine SDK compatibility: current >= required (accept equal or higher versions)
86110
current_sdk = parse_version(engine_sdk_version)
87111
required_sdk = parse_version(required_sdk_version)
88112
if current_sdk < required_sdk:

ENGINES/cx_freeze/engine.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
class CxFreezeEngine(CompilerEngine):
3737
id = "cx_freeze"
3838
name = "cx_Freeze"
39+
version: str = "1.0.0"
40+
required_core_version: str = "1.0.0"
41+
required_sdk_version: str = "1.0.0"
3942

4043
def _resolve_venv_root(self, gui) -> Optional[str]:
4144
try:

ENGINES/nuitka/engine.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
class NuitkaEngine(CompilerEngine):
3636
id = "nuitka"
3737
name = "Nuitka"
38+
version: str = "1.0.0"
39+
required_core_version: str = "1.0.0"
40+
required_sdk_version: str = "1.0.0"
3841

3942
def preflight(self, gui, file: str) -> bool:
4043
# System deps (engine-owned)

ENGINES/pyinstaller/engine.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
class PyInstallerEngine(CompilerEngine):
3535
id = "pyinstaller"
3636
name = "PyInstaller"
37+
version: str = "1.0.0"
38+
required_core_version: str = "1.0.0"
39+
required_sdk_version: str = "1.0.0"
3740

3841
def _resolve_venv_root(self, gui) -> Optional[str]:
3942
try:

bcasl/Base.py

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ def get_compatibility_info(self) -> dict[str, str]:
171171
def is_compatible_with_bcasl(self, bcasl_version: str) -> bool:
172172
"""Check if plugin is compatible with given BCASL version.
173173
174+
Supports version formats:
175+
- "1.0.0" -> (1, 0, 0)
176+
- "1.0.0+" -> (1, 0, 0) [+ means "or higher"]
177+
- "1.0.0-beta" -> (1, 0, 0)
178+
- "1.0.0+build123" -> (1, 0, 0)
179+
174180
Args:
175181
bcasl_version: BCASL version string to check against
176182
@@ -179,7 +185,11 @@ def is_compatible_with_bcasl(self, bcasl_version: str) -> bool:
179185
"""
180186
def parse_version(v: str) -> tuple:
181187
try:
182-
parts = v.strip().split("+")[0].split("-")[0].split(".")
188+
s = v.strip()
189+
if s.endswith("+"):
190+
s = s[:-1].strip()
191+
s = s.split("+")[0].split("-")[0]
192+
parts = s.split(".")
183193
major = int(parts[0]) if len(parts) > 0 else 0
184194
minor = int(parts[1]) if len(parts) > 1 else 0
185195
patch = int(parts[2]) if len(parts) > 2 else 0
@@ -194,6 +204,12 @@ def parse_version(v: str) -> tuple:
194204
def is_compatible_with_core(self, core_version: str) -> bool:
195205
"""Check if plugin is compatible with given Core version.
196206
207+
Supports version formats:
208+
- "1.0.0" -> (1, 0, 0)
209+
- "1.0.0+" -> (1, 0, 0) [+ means "or higher"]
210+
- "1.0.0-beta" -> (1, 0, 0)
211+
- "1.0.0+build123" -> (1, 0, 0)
212+
197213
Args:
198214
core_version: Core version string to check against
199215
@@ -202,7 +218,11 @@ def is_compatible_with_core(self, core_version: str) -> bool:
202218
"""
203219
def parse_version(v: str) -> tuple:
204220
try:
205-
parts = v.strip().split("+")[0].split("-")[0].split(".")
221+
s = v.strip()
222+
if s.endswith("+"):
223+
s = s[:-1].strip()
224+
s = s.split("+")[0].split("-")[0]
225+
parts = s.split(".")
206226
major = int(parts[0]) if len(parts) > 0 else 0
207227
minor = int(parts[1]) if len(parts) > 1 else 0
208228
patch = int(parts[2]) if len(parts) > 2 else 0
@@ -217,6 +237,12 @@ def parse_version(v: str) -> tuple:
217237
def is_compatible_with_plugins_sdk(self, sdk_version: str) -> bool:
218238
"""Check if plugin is compatible with given Plugins SDK version.
219239
240+
Supports version formats:
241+
- "1.0.0" -> (1, 0, 0)
242+
- "1.0.0+" -> (1, 0, 0) [+ means "or higher"]
243+
- "1.0.0-beta" -> (1, 0, 0)
244+
- "1.0.0+build123" -> (1, 0, 0)
245+
220246
Args:
221247
sdk_version: Plugins SDK version string to check against
222248
@@ -225,7 +251,11 @@ def is_compatible_with_plugins_sdk(self, sdk_version: str) -> bool:
225251
"""
226252
def parse_version(v: str) -> tuple:
227253
try:
228-
parts = v.strip().split("+")[0].split("-")[0].split(".")
254+
s = v.strip()
255+
if s.endswith("+"):
256+
s = s[:-1].strip()
257+
s = s.split("+")[0].split("-")[0]
258+
parts = s.split(".")
229259
major = int(parts[0]) if len(parts) > 0 else 0
230260
minor = int(parts[1]) if len(parts) > 1 else 0
231261
patch = int(parts[2]) if len(parts) > 2 else 0
@@ -240,6 +270,12 @@ def parse_version(v: str) -> tuple:
240270
def is_compatible_with_bc_plugin_context(self, context_version: str) -> bool:
241271
"""Check if plugin is compatible with given BcPluginContext version.
242272
273+
Supports version formats:
274+
- "1.0.0" -> (1, 0, 0)
275+
- "1.0.0+" -> (1, 0, 0) [+ means "or higher"]
276+
- "1.0.0-beta" -> (1, 0, 0)
277+
- "1.0.0+build123" -> (1, 0, 0)
278+
243279
Args:
244280
context_version: BcPluginContext version string to check against
245281
@@ -248,7 +284,11 @@ def is_compatible_with_bc_plugin_context(self, context_version: str) -> bool:
248284
"""
249285
def parse_version(v: str) -> tuple:
250286
try:
251-
parts = v.strip().split("+")[0].split("-")[0].split(".")
287+
s = v.strip()
288+
if s.endswith("+"):
289+
s = s[:-1].strip()
290+
s = s.split("+")[0].split("-")[0]
291+
parts = s.split(".")
252292
major = int(parts[0]) if len(parts) > 0 else 0
253293
minor = int(parts[1]) if len(parts) > 1 else 0
254294
patch = int(parts[2]) if len(parts) > 2 else 0
@@ -263,6 +303,12 @@ def parse_version(v: str) -> tuple:
263303
def is_compatible_with_general_context(self, context_version: str) -> bool:
264304
"""Check if plugin is compatible with given GeneralContext version.
265305
306+
Supports version formats:
307+
- "1.0.0" -> (1, 0, 0)
308+
- "1.0.0+" -> (1, 0, 0) [+ means "or higher"]
309+
- "1.0.0-beta" -> (1, 0, 0)
310+
- "1.0.0+build123" -> (1, 0, 0)
311+
266312
Args:
267313
context_version: GeneralContext version string to check against
268314
@@ -271,7 +317,11 @@ def is_compatible_with_general_context(self, context_version: str) -> bool:
271317
"""
272318
def parse_version(v: str) -> tuple:
273319
try:
274-
parts = v.strip().split("+")[0].split("-")[0].split(".")
320+
s = v.strip()
321+
if s.endswith("+"):
322+
s = s[:-1].strip()
323+
s = s.split("+")[0].split("-")[0]
324+
parts = s.split(".")
275325
major = int(parts[0]) if len(parts) > 0 else 0
276326
minor = int(parts[1]) if len(parts) > 1 else 0
277327
patch = int(parts[2]) if len(parts) > 2 else 0

bcasl/validator.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,29 @@ class CompatibilityCheckResult:
4242

4343

4444
def parse_version(version_string: str) -> Tuple[int, int, int]:
45-
"""Parse a version string into (major, minor, patch)."""
45+
"""
46+
Parse a version string into (major, minor, patch).
47+
48+
Supports formats:
49+
- "1.0.0" -> (1, 0, 0)
50+
- "1.0.0+" -> (1, 0, 0) [+ means "or higher"]
51+
- "1.0.0-beta" -> (1, 0, 0)
52+
- "1.0.0+build123" -> (1, 0, 0)
53+
"""
4654
try:
47-
parts = version_string.strip().split("+")[0].split("-")[0].split(".")
55+
# Remove leading/trailing whitespace
56+
s = version_string.strip()
57+
58+
# Handle "1.0.0+" format (+ at the end means "or higher")
59+
# We just strip it since our comparison logic already uses >= semantics
60+
if s.endswith("+"):
61+
s = s[:-1].strip()
62+
63+
# Remove build metadata and pre-release identifiers
64+
s = s.split("+")[0].split("-")[0]
65+
66+
# Parse major.minor.patch
67+
parts = s.split(".")
4868
major = int(parts[0]) if len(parts) > 0 else 0
4969
minor = int(parts[1]) if len(parts) > 1 else 0
5070
patch = int(parts[2]) if len(parts) > 2 else 0

0 commit comments

Comments
 (0)