src/App/Bootstrap.ps1
|
# Bootstrap — Carga constantes globales del v3 (ADR-003). # # **No dot-source-ea clases.** Las clases en PowerShell sólo viven en el scope del # archivo que las dot-source-ea **directamente** — si las cargás vía Import-RNFile, # el resto de los archivos no las "ven" como tipos. Por eso las clases se cargan # directamente desde el entry repo-nav.ps1 en orden bottom-up. # # Este Bootstrap sólo carga: # - Constantes (`$global:RNTokens`, `$global:RNThemes`, etc.) # - Funciones que NO usan clases en su cuerpo $script:RNRoot = Split-Path $PSScriptRoot -Parent # Helper que VALIDA + DEVUELVE el path. NO dot-sourcea — el dot-source pasa # afuera, en el scope del caller (este mismo archivo). Esto es CRÍTICO para # las funciones definidas en I18nCatalog.ps1: si las dot-sourceáramos adentro # de una función helper, quedarían en el scope local de esa función y # I18nService.T no las podría llamar (TypeError 'Get-RepoNavI18nCatalog not # recognized'). Al hacer el dot-source en este nivel, las funciones quedan # en el scope de Bootstrap.ps1 → que es el scope del caller (repo-nav.ps1 # o repo-nav.psm1) → visible para todo lo cargado después. function Resolve-RNConfig { param([Parameter(Mandatory)] [string] $RelativePath) $full = Join-Path $script:RNRoot $RelativePath if (-not (Test-Path $full)) { throw "Bootstrap: archivo no existe: $full" } return $full } # Config (sólo constantes y funciones standalone, sin classes). # Dot-source DIRECTO (no via función helper) para que las funciones definidas # acá queden visibles desde I18nService.T y similares. . (Resolve-RNConfig 'Config/Tokens.ps1') . (Resolve-RNConfig 'Config/Themes.ps1') . (Resolve-RNConfig 'Config/I18nCatalog.ps1') # Orden explícito de carga de archivos con `class`. El entry repo-nav.ps1 # itera sobre este array y los dot-sourcea uno a uno **desde el scope del entry**, # así los tipos quedan visibles para cualquier otro archivo cargado después. # Bottom-up: Models → Services → UI → App. $global:RNLoadOrder = @( # Models (data classes, sin dependencias entre sí salvo Commit ← Repo) 'Models/Commit.ps1' 'Models/Repo.ps1' 'Models/Branch.ps1' 'Models/FileChange.ps1' 'Models/Settings.ps1' 'Models/IntegrationFlow.ps1' # Util — funciones standalone reusables (no clases). Cargado antes de # Services porque RepoDiscoveryService.DiscoverParallel necesita # Get-RepoStateData visible al parsearse el archivo. 'Util/GitParse.ps1' # Services 'Services/AnsiService.ps1' 'Services/ThemeService.ps1' 'Services/I18nService.ps1' 'Services/GitService.ps1' 'Services/RepoDiscoveryService.ps1' 'Services/SettingsService.ps1' 'Services/SetupService.ps1' # UI 'UI/Renderer.ps1' 'UI/Primitives.ps1' 'UI/Frame.ps1' 'UI/AppHeader.ps1' 'UI/StatusBar.ps1' 'UI/Viewport.ps1' 'UI/BreadcrumbBuilder.ps1' 'UI/NavStack.ps1' 'UI/Components/FilteredListPicker.ps1' # IntegrateScreen va ANTES que BranchManagerScreen porque éste lo instancia # cuando el user selecciona el chip Integrate. 'UI/Screens/IntegrateScreen.ps1' 'UI/Screens/QuickChangeScreen.ps1' 'UI/Screens/ReleaseScreen.ps1' 'UI/Screens/GraphScreen.ps1' 'UI/Screens/CherryPickScreen.ps1' 'UI/Screens/CompareScreen.ps1' # BranchManagerScreen va ANTES que MainScreen porque MainScreen lo instancia # via `[BranchManagerScreen]::new(...)` y PS classes resuelven tipos at parse time. 'UI/Screens/BranchManagerScreen.ps1' 'UI/Screens/SetupScreen.ps1' # PreferencesScreen instancia SetupScreen (chip 'Setup & Status'). 'UI/Screens/PreferencesScreen.ps1' # ConfigScreen es la nueva pantalla de configuración global (alias + deps # + AutoLoadMode). Independiente del PreferencesScreen viejo, accesible # via `rnav config` desde la CLI. 'UI/Screens/ConfigScreen.ps1' 'UI/Screens/BrowseScreen.ps1' 'UI/Screens/MainScreen.ps1' # App (funciones top-level) 'App/Startup.ps1' ) |