<# .SYNOPSIS Bootstrap the SimReady Pipeline Bot runtime dependencies. .DESCRIPTION Idempotent. Run once on a fresh machine, or re-run any time to fix a missing dependency. Creates a Python venv, clones the foundation + SDK repos, and pip-installs everything the /simready-report skill needs. The foundation specs are *not* editable-installed any more. validate.py now defaults to populating the OAV registries via the simready-validate CLI loader against on-disk paths under the foundations checkout. Avoids the `repo usd_profiles_codegen` codegen step (which depends on internal packman tooling not shipped in the public GitHub repo) and the Forced-include trap in nv_core/sr_specs/pyproject.toml. Layout produced (all under -DepsRoot, default $env:LOCALAPPDATA\simready): \ ├── venv\ # Python venv (created if missing) ├── simready_foundations\ # cloned from NVIDIA GitHub └── simready-oem-sdk-poc\ # cloned from NVIDIA-dev GitHub After a successful install the script writes three User-level environment variables so the /simready-report skill can locate everything from any shell: SIMREADY_PYTHON = \venv\Scripts\python.exe SIMREADY_FOUNDATIONS_PATH = \simready_foundations SIMREADY_SDK_PATH = \simready-oem-sdk-poc Override the location with -DepsRoot, e.g.: .\bootstrap.ps1 -DepsRoot D:\simready-deps Already have these repos checked out elsewhere? Skip this script and set the two env vars manually. Optional (not bootstrapped): a `usd_validation_dashboard_final\` clone — used only to copy Sphinx _static\ assets into rendered doc pages. If absent, the dashboard's doc pages fall back to minimal inline styling. .NOTES - Reversible: the dirs created here are safe to delete; rerun this script to re-create them. The two env vars can be cleared with `[Environment]::SetEnvironmentVariable("SIMREADY_FOUNDATIONS_PATH", $null, "User")`. - Requires: git, python (3.11+ recommended), and access to github.com/NVIDIA + github.com/NVIDIA-dev (creds via the user's existing git/gh auth). - Never elevates / never modifies system PATH. #> [CmdletBinding()] param( [switch]$Force, # re-clone even if dirs exist [string]$Python = "python", # python interpreter to seed the venv [string]$DepsRoot = (Join-Path $env:LOCALAPPDATA "simready"), [string]$FoundationsRepo = "https://github.com/NVIDIA/simready-foundation.git", [string]$SdkRepo = "https://github.com/NVIDIA-dev/simready-oem-sdk-poc.git" ) $ErrorActionPreference = "Stop" if (-not (Test-Path $DepsRoot)) { New-Item -ItemType Directory -Path $DepsRoot -Force | Out-Null } $DepsRoot = (Resolve-Path $DepsRoot).Path $VenvPath = Join-Path $DepsRoot "venv" $FoundationsPath = Join-Path $DepsRoot "simready_foundations" $SdkPath = Join-Path $DepsRoot "simready-oem-sdk-poc" function Step($msg) { Write-Host ""; Write-Host "==> $msg" -ForegroundColor Cyan } function Note($msg) { Write-Host " $msg" -ForegroundColor DarkGray } function Done($msg) { Write-Host " OK: $msg" -ForegroundColor Green } function Fail($msg) { Write-Host " FAIL: $msg" -ForegroundColor Red; exit 1 } Write-Host "DepsRoot: $DepsRoot" -ForegroundColor Yellow # ---- Pre-flight ---------------------------------------------------------- Step "Pre-flight" foreach ($cmd in @("git", $Python)) { $found = Get-Command $cmd -ErrorAction SilentlyContinue if (-not $found) { Fail "$cmd not on PATH" } Note "$cmd -> $($found.Source)" } # ---- Clone the repos ----------------------------------------------------- function Ensure-Repo($name, $url, $path) { if ((Test-Path $path) -and -not $Force) { if (Test-Path (Join-Path $path ".git")) { $existingUrl = $null Push-Location $path try { $existingUrl = (git remote get-url origin 2>$null) } finally { Pop-Location } if ($existingUrl -and ($existingUrl.Trim() -ne $url.Trim())) { Fail "$name at $path has origin '$($existingUrl.Trim())' but expected '$url'. Re-run with -Force to re-clone, or fix manually: git -C `"$path`" remote set-url origin `"$url`"" } Note "$name already cloned at $path (use -Force to re-clone)" return } else { Fail "$path exists but is not a git checkout. Move or delete it first." } } if ((Test-Path $path) -and $Force) { Note "Removing $path (-Force)" Remove-Item -Recurse -Force $path } Note "git clone $url $path" git clone $url $path if ($LASTEXITCODE -ne 0) { Fail "git clone $name failed" } Done "$name cloned" } Step "simready_foundations" Ensure-Repo "simready_foundations" $FoundationsRepo $FoundationsPath Step "simready-oem-sdk-poc" Ensure-Repo "simready-oem-sdk-poc" $SdkRepo $SdkPath # ---- Python venv --------------------------------------------------------- Step "Python venv at $VenvPath" if (-not (Test-Path (Join-Path $VenvPath "Scripts\python.exe"))) { & $Python -m venv $VenvPath if ($LASTEXITCODE -ne 0) { Fail "venv creation failed" } Done "venv created" } else { Note "venv already present" } $VenvPython = Join-Path $VenvPath "Scripts\python.exe" $VenvPip = Join-Path $VenvPath "Scripts\pip.exe" # ---- Pip installs -------------------------------------------------------- Step "Upgrade pip / install runtime deps" & $VenvPython -m pip install --upgrade pip wheel setuptools | Out-Null if ($LASTEXITCODE -ne 0) { Fail "pip self-upgrade failed" } $Pkgs = @( "usd-core==26.5", "omniverse-asset-validator==1.15.1", "omniverse-usd-profiles==1.11.0", "markdown-it-py>=3.0", "click>=8.0", "simready-validate>=2026.4.8" ) & $VenvPip install @Pkgs if ($LASTEXITCODE -ne 0) { Fail "pip install (runtime deps) failed" } Done "runtime deps installed (incl. simready-validate from PyPI — provides the CLI loader)" # Editable install of nv_core/sr_specs is no longer required. validate.py # now defaults to populating the OAV registries via # simready.validate.impl.loader.load_validation_implementation against # on-disk paths under the foundations checkout. The legacy editable # install + repo usd_profiles_codegen flow is reachable via the # --use-plugin opt-in flag if needed. Step "Editable install of simready-oem-sdk-poc (for auto-package step)" & $VenvPip install -e $SdkPath if ($LASTEXITCODE -ne 0) { Fail "pip install -e simready-oem-sdk-poc failed" } Done "SDK editable install complete" # ---- Smoke check --------------------------------------------------------- Step "Smoke check" & $VenvPython -c @" import omni.asset_validator as oav from pxr import Usd from markdown_it import MarkdownIt import simready_sdk from simready.validate.impl.loader import load_validation_implementation from pathlib import Path import os foundations = Path(os.environ.get('SIMREADY_FOUNDATIONS_PATH') or r'$FoundationsPath') load_validation_implementation( rules_and_requirements_paths=[foundations / 'nv_core/sr_specs/docs/capabilities'], features_paths=[foundations / 'nv_core/sr_specs/docs/features'], profiles_paths=[foundations / 'nv_core/sr_specs/docs/profiles/profiles.toml'], ) pr = oav.ProfileRegistry() profiles = list(pr.values()) print(f' asset-validator: {oav.__version__ if hasattr(oav,"__version__") else "(no version attr)"}') print(f' profiles loaded: {len(profiles)}') print(f' simready_sdk: {simready_sdk.__file__}') "@ if ($LASTEXITCODE -ne 0) { Fail "smoke check failed" } Done "imports + CLI-loader populated ProfileRegistry working" # ---- Persist env vars so validate.py finds the deps without args ------- Step "Persist locator env vars (User scope)" [Environment]::SetEnvironmentVariable("SIMREADY_PYTHON", $VenvPython, "User") [Environment]::SetEnvironmentVariable("SIMREADY_FOUNDATIONS_PATH", $FoundationsPath, "User") [Environment]::SetEnvironmentVariable("SIMREADY_SDK_PATH", $SdkPath, "User") $env:SIMREADY_PYTHON = $VenvPython $env:SIMREADY_FOUNDATIONS_PATH = $FoundationsPath $env:SIMREADY_SDK_PATH = $SdkPath Note "SIMREADY_PYTHON = $VenvPython" Note "SIMREADY_FOUNDATIONS_PATH = $FoundationsPath" Note "SIMREADY_SDK_PATH = $SdkPath" Done "env vars set for current user" # ---- Done --------------------------------------------------------------- Write-Host "" Write-Host "Bootstrap complete." -ForegroundColor Green Write-Host "DepsRoot: $DepsRoot" -ForegroundColor Green Write-Host "Next: invoke /simready-report against any asset directory." -ForegroundColor Green