@@ -4258,43 +4258,44 @@ def __init__(self, config_manager: ConfigManager, minimal_mode: bool = False):
42584258 if not self.config:
42594259 if len(sys.argv) > 1 and sys.argv[1] in ['reset-config', 'doctor']:
42604260 pass
4261- elif not minimal_mode:
4262- raise RuntimeError('OmnipkgCore cannot initialize: Configuration is missing or invalid.')
4261+ else:
4262+ raise RuntimeError('OmnipkgCore cannot initialize: Configuration is missing or invalid.')
4263+
4264+ # STEP 1: Handle the simple 'minimal_mode' case FIRST and exit immediately.
4265+ # This is the safe exit path that prevents the loop during re-initialization.
4266+ if minimal_mode:
4267+ self.env_id = self._get_env_id()
4268+ self.multiversion_base = Path(self.config['multiversion_base'])
4269+ self.interpreter_manager = InterpreterManager(self.config_manager)
4270+ safe_print(_('✅ Omnipkg core initialized (minimal mode).'))
4271+ return # EXIT EARLY - no cache, no migrations, no hooks
42634272
4264- # --- CORE ATTRIBUTES (Needed early) ---
4273+ # STEP 2: For a full run, perform the critical setup and healing process.
4274+ # This function handles the "first-time setup" in a controlled way.
4275+ self._self_heal_omnipkg_installation()
4276+
4277+ # STEP 3: Now that the environment is stable, initialize all other core attributes.
42654278 self.env_id = self._get_env_id()
42664279 self.multiversion_base = Path(self.config['multiversion_base'])
42674280 self.site_packages_root = Path(self.config['site_packages_path'])
4281+ self.cache_client = None
4282+ self._cache_connection_status = None
4283+ self.initialize_pypi_cache()
4284+ self._check_and_run_pending_rebuild()
42684285 self._info_cache = {}
42694286 self._installed_packages_cache = None
42704287 self.http_session = http_requests.Session()
4271- self.cache_client = None
4272- self._cache_connection_status = None
4273-
4274- # --- PHASE 1: INITIALIZE MANAGERS ---
4275- # These are needed by almost all commands, including minimal ones.
4276- self.interpreter_manager = InterpreterManager(self.config_manager)
4277-
4278- # Minimal mode exits here. Commands like 'swap' or 'list python' now have what they need.
4279- if minimal_mode:
4280- safe_print(_('✅ Omnipkg core initialized (minimal mode).'))
4281- return
4282-
4283- # --- PHASE 2: FULL INITIALIZATION FOR HEAVY COMMANDS ---
4284- # Connect to the cache (Redis or SQLite)
4288+ self.multiversion_base.mkdir(parents=True, exist_ok=True)
4289+
42854290 if not self._connect_cache():
4286- sys.exit(1)
4287-
4288- # Now that we have a cache, initialize other managers that depend on it.
4291+ safe_print(_('⚠️ Proceeding without cache connection.'))
4292+
4293+ # Initialize managers that depend on a stable environment and cache.
4294+ self.interpreter_manager = InterpreterManager(self.config_manager)
42894295 self.hook_manager = ImportHookManager(str(self.config.get('multiversion_base')), config=self.config, cache_client=self.cache_client)
4290- self.bubble_manager = BubbleIsolationManager(self.config, self) # <-- CRITICAL: Now exists before rebuild
4291-
4292- # --- PHASE 3: POST-INITIALIZATION AND SELF-HEALING ---
4293- # These tasks may depend on the fully initialized managers.
4294- self._self_heal_omnipkg_installation()
4295- self.initialize_pypi_cache()
4296+ self.bubble_manager = BubbleIsolationManager(self.config, self)
42964297
4297- # Run database migrations
4298+ # Run database migrations if needed.
42984299 migration_flag_key = f'omnipkg:env_{self.env_id}:migration_v2_env_aware_keys_complete'
42994300 if not self.cache_client.get(migration_flag_key):
43004301 old_keys_iterator = self.cache_client.scan_iter('omnipkg:pkg:*', count=1)
@@ -4303,17 +4304,10 @@ def __init__(self, config_manager: ConfigManager, minimal_mode: bool = False):
43034304 else:
43044305 self.cache_client.set(migration_flag_key, 'true')
43054306
4306- migration_v3_flag_key = f'{self.redis_env_prefix}migration_v3_install_type_complete'
4307- if not self.cache_client.get(migration_v3_flag_key):
4308- self._perform_v3_metadata_migration(migration_v3_flag_key)
4309-
4310- # Proactively build the loader cache if needed.
4307+ # Proactively build the loader cache.
43114308 self._prime_loader_cache()
43124309
4313- # CRITICAL: Run the pending rebuild check LAST, after everything is initialized.
4314- self._check_and_run_pending_rebuild()
4315-
4316- # Finally, load the import hooks.
4310+ # Load the import hooks.
43174311 self.hook_manager.load_version_map()
43184312 self.hook_manager.install_import_hook()
43194313 safe_print(_('✅ Omnipkg core initialized successfully.'))
0 commit comments