Skip to content
Merged

Dev #190

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/ducpdf/src/duc2pdf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ To ensure smooth releases with semantic-release, please follow [these guidelines

---

*The duc format and libraries are constantly evolving, aiming to set new standards in the 2D CAD industry. Be a part of this transformation and help shape the future of design technology!*
*The duc format and libraries are constantly evolving, aiming to set new standards in the 2D CAD industry. Be a part of this transformation and help shape the future of design technology!*
2 changes: 1 addition & 1 deletion packages/ducpdf/src/duc2pdf/release.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports = {
// 2. Set the crate version
// 3. Build the project
prepareCmd:
"node ../../../../scripts/cargo-set-duc-dep-version.js . 2 && cargo set-version ${nextRelease.version} && cargo build --release",
"node ../../../../scripts/cargo-set-duc-dep-version.js . 3 && cargo set-version ${nextRelease.version} && cargo build --release",

// Publish step: Publish the crate to crates.io
publishCmd:
Expand Down
42 changes: 41 additions & 1 deletion packages/ducpy/src/ducpy/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,56 @@
from __future__ import annotations

import logging
import re
from dataclasses import asdict, is_dataclass
from pathlib import Path
from typing import Any, Dict, List, Optional, Union

import ducpy_native
from ducpy._version import DUC_SCHEMA_VERSION
from ducpy.utils.convert import (deep_snake_to_camel, snake_to_camel,
to_serializable)

logger = logging.getLogger(__name__)


def _decode_user_version_to_semver(user_version: int) -> str:
"""Decode sqlite-style schema user_version to semver.

Encoding convention:
major * 1_000_000 + minor * 1_000 + patch
"""
if user_version < 0:
return "0.0.0"

major = user_version // 1_000_000
minor = (user_version % 1_000_000) // 1_000
patch = user_version % 1_000
return f"{major}.{minor}.{patch}"


def _read_schema_version_fallback() -> str:
"""Resolve schema version directly from repository `schema/duc.sql`.

This is used when `ducpy._version` isn't available (for example, in clean
CI environments before setup-time generation has run).
"""
try:
schema_path = Path(__file__).resolve().parents[4] / "schema" / "duc.sql"
content = schema_path.read_text(encoding="utf-8")
match = re.search(r"PRAGMA\s+user_version\s*=\s*(\d+)\s*;", content)
if match:
return _decode_user_version_to_semver(int(match.group(1)))
except Exception as exc: # pragma: no cover - defensive fallback for CI/runtime variance
logger.warning("Failed to resolve schema version fallback from duc.sql: %s", exc)

return "0.0.0"


try:
from ducpy._version import DUC_SCHEMA_VERSION
except ModuleNotFoundError:
DUC_SCHEMA_VERSION = _read_schema_version_fallback()

# Map Python element class names → Rust serde type tag strings.
_ELEMENT_CLASS_TO_TYPE: Dict[str, str] = {
"DucRectangleElement": "rectangle",
Expand Down
Loading