11# SPDX-FileCopyrightText: Copyright (c) 2025 The Newton Developers
22# SPDX-License-Identifier: Apache-2.0
33import json
4+ import re
45from pathlib import Path
56
67import requests
7- import tomllib
88from hatchling .builders .hooks .plugin .interface import BuildHookInterface
99
1010
1111class MjcPhysicsSchemaBuildHook (BuildHookInterface ):
1212 PLUGIN_NAME = "mjc_physics_schema"
1313
14+ @staticmethod
15+ def __read_uv_lock_package_version (lock_path : Path , package_name : str ) -> str :
16+ """
17+ Extract a package version from uv's lockfile without requiring a TOML parser.
18+
19+ `uv.lock` is TOML, but for our purposes we only need to scan `[[package]]` blocks:
20+ [[package]]
21+ name = "mujoco"
22+ version = "3.4.0"
23+ """
24+ pkg_start_re = re .compile (r"^\s*\[\[package\]\]\s*$" )
25+ name_re = re .compile (r'^\s*name\s*=\s*"([^"]+)"\s*$' )
26+ version_re = re .compile (r'^\s*version\s*=\s*"([^"]+)"\s*$' )
27+
28+ current_name : str | None = None
29+ current_version : str | None = None
30+ in_pkg = False
31+
32+ with lock_path .open ("r" , encoding = "utf-8" ) as f :
33+ for raw_line in f :
34+ line = raw_line .rstrip ("\n " )
35+
36+ # Start of a new [[package]] block
37+ if pkg_start_re .match (line ):
38+ in_pkg = True
39+ current_name = None
40+ current_version = None
41+ continue
42+
43+ if not in_pkg :
44+ continue
45+
46+ m = name_re .match (line )
47+ if m :
48+ current_name = m .group (1 )
49+ if current_name == package_name and current_version is not None :
50+ return current_version
51+ continue
52+
53+ m = version_re .match (line )
54+ if m :
55+ current_version = m .group (1 )
56+ if current_name == package_name and current_version is not None :
57+ return current_version
58+ continue
59+
60+ raise RuntimeError (f"{ package_name } version not found in { lock_path } " )
61+
1462 def initialize (self , version , build_data ):
1563 """Called before the build starts"""
1664 self .target_dir = Path ("mujoco_usd_converter/plugins/mjcPhysics/resources" )
@@ -30,16 +78,7 @@ def download_schema_files(self):
3078 """Download the MJC schema files from GitHub"""
3179
3280 # Get the mujoco version from the uv.lock file
33- mujoco_version = None
34- with Path .open ("uv.lock" , "rb" ) as f :
35- uv_lock = tomllib .load (f )
36- packages = uv_lock ["package" ]
37- for package in packages :
38- if package ["name" ] == "mujoco" :
39- mujoco_version = package ["version" ]
40- break
41- if mujoco_version is None :
42- raise RuntimeError ("Mujoco version not found in uv.lock" )
81+ mujoco_version = self .__read_uv_lock_package_version (Path ("uv.lock" ), "mujoco" )
4382
4483 # Get the schema url from the mujoco version
4584 schema_url = f"https://raw.githubusercontent.com/google-deepmind/mujoco/refs/tags/{ mujoco_version } /src/experimental/usd/mjcPhysics"
0 commit comments