Skip to content

Instantly share code, notes, and snippets.

@virtuald
Created June 4, 2025 01:10
Show Gist options
  • Save virtuald/c03266665b1748227889f3259eecb21b to your computer and use it in GitHub Desktop.
Save virtuald/c03266665b1748227889f3259eecb21b to your computer and use it in GitHub Desktop.
Upgrade robotpy-build YAML files to semiwrap
#!/usr/bin/env python3
import os
import sys
from pathlib import Path
from ruyaml import YAML
def build_namespace_map(file_path):
"""
Build a mapping from simple class names to namespaced class names from a single YAML file.
"""
yaml = YAML()
ns_map = {}
data = yaml.load(file_path)
classes = data.get('classes', {}) or {}
for full_name in classes.keys():
parts = full_name.split('::')
for i in range(1, len(parts)+1):
partial = '::'.join(parts[-i:])
ns_map[partial] = full_name
return ns_map
def update_old_file(old_file_path, new_file_path):
"""
Update a single YAML file by replacing simple class keys with namespaced keys using the new file.
Creates a .bak backup by default.
"""
yaml = YAML()
yaml.preserve_quotes = True
# yaml.indent(mapping=2, sequence=4, offset=2)
ns_map = build_namespace_map(new_file_path)
old_data = yaml.load(old_file_path)
classes = old_data.get('classes')
if not isinstance(classes, dict):
print(f"Skipping {old_file_path}: 'classes' section missing or not a dict.")
return
# build new classes dict
new_classes = {}
for simple, value in classes.items():
if "shared_ptr" in value:
del value["shared_ptr"]
if simple in ns_map:
new_key = ns_map[simple]
else:
print(f"Warning: No namespace mapping for class '{simple}' in {old_file_path}")
new_key = simple
new_classes[new_key] = value
# replace classes section
old_data['classes'] = new_classes
# write updated file
with open(old_file_path, 'w') as f:
yaml.dump(old_data, f)
print(f"Updated {old_file_path}")
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(
description="Update old YAML files by adding namespaces to class names from new YAML files."
)
parser.add_argument('old_dir', help="Directory containing old YAML files")
parser.add_argument('new_dir', help="Directory containing new YAML files with namespaced classes")
args = parser.parse_args()
old_dir = Path(args.old_dir)
new_dir = Path(args.new_dir)
for old_path in old_dir.glob('*.yml'):
new_path = new_dir / old_path.name
if new_path.exists():
update_old_file(old_path, new_path)
else:
print(f"Warning: No matching new file for {old_path.name}, deleting.")
old_path.unlink()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment