Skip to content

Instantly share code, notes, and snippets.

@perryd01
Created September 30, 2024 10:46
Show Gist options
  • Save perryd01/3ed3512809a2779425e1ceffe2108165 to your computer and use it in GitHub Desktop.
Save perryd01/3ed3512809a2779425e1ceffe2108165 to your computer and use it in GitHub Desktop.
Omniverse repo_tool for setting modules in Pycharm from VsCode config
import argparse
import pathlib
import re
import xml.etree.ElementTree as ET
def setup_repo_tool(parser: argparse.ArgumentParser, config: dict):
parser.prog = "pycharm_config_gen"
parser.formatter_class = argparse.RawDescriptionHelpFormatter
parser.description = "Generate config for Pycharm"
repo_root: str | None = config.get("repo", {}).get("folders", {}).get("root", None)
def run_repo_tool(options, config):
paths = get_paths_from_vscode(repo_root)
swap_paths_in_pycharm(repo_root=repo_root, paths=paths)
pass
return run_repo_tool
def get_paths_from_vscode(repo_root):
"""Get the python.analysis.extraPaths part of the settings.json
This json file is slightly malformed, so some string magic has to be done.
"""
pattern = r'"python\.analysis\.extraPaths"\s*:\s*\[\s*((?:\n\s*".*?",?)*)\s*\],'
config = pathlib.Path(repo_root, ".vscode", "settings.json")
config_text = config.read_text()
if not config_text:
raise Exception("empty file")
regex = re.compile(pattern=pattern)
matches = regex.search(config_text)
if not matches:
raise Exception("block not found")
paths = matches.group(1).split("\n") or []
def process_one_path(p: str) -> str | None:
t = p
t = t.replace('"', "").replace(",", "").strip()
if t == "":
return None
return t
processed_paths = []
for p in paths:
processed = process_one_path(p)
if not processed:
continue
processed_paths.append(processed)
return processed_paths
def swap_paths_in_pycharm(repo_root: str, paths: list[str]):
idea_folder = pathlib.Path(repo_root, ".idea")
idea_config = next(idea_folder.glob("*.iml"), None)
if not idea_config or not idea_config.is_file():
raise Exception("idea config not found")
tree = ET.parse(idea_config)
root = tree.getroot()
content_element = root.find(".//content")
# Remove all existing 'sourceFolder' elements
for source_folder in content_element.findall("sourceFolder"):
content_element.remove(source_folder)
# Add new 'sourceFolder' elements from the given list
for folder in paths:
new_folder = ET.Element(
"sourceFolder", attrib={"url": f"file://$MODULE_DIR$/{folder}", "isTestSource": "false"}
)
content_element.append(new_folder)
# output_path = pathlib.Path(idea_folder, "dummy.iml")
tree.write(idea_config, encoding="UTF-8", xml_declaration=True)
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment