dfdsf
This commit is contained in:
65
pipeline.py
65
pipeline.py
@@ -20,11 +20,54 @@ from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import shlex
|
||||
from contextlib import contextmanager
|
||||
from typing import Any, Dict, List, Optional, Sequence
|
||||
|
||||
from models import PipelineStageContext
|
||||
from SYS.logger import log
|
||||
|
||||
# Live progress UI instance (optional). Set by the pipeline runner.
|
||||
_LIVE_PROGRESS: Any = None
|
||||
|
||||
|
||||
def set_live_progress(progress_ui: Any) -> None:
|
||||
"""Register the current Live progress UI so cmdlets can suspend it during prompts."""
|
||||
global _LIVE_PROGRESS
|
||||
_LIVE_PROGRESS = progress_ui
|
||||
|
||||
|
||||
def get_live_progress() -> Any:
|
||||
return _LIVE_PROGRESS
|
||||
|
||||
|
||||
@contextmanager
|
||||
def suspend_live_progress():
|
||||
"""Temporarily pause Live progress rendering.
|
||||
|
||||
This avoids Rich Live cursor control interfering with interactive tables/prompts
|
||||
emitted by cmdlets during preflight (e.g. URL-duplicate confirmation).
|
||||
"""
|
||||
ui = _LIVE_PROGRESS
|
||||
paused = False
|
||||
try:
|
||||
if ui is not None and hasattr(ui, "pause"):
|
||||
try:
|
||||
ui.pause()
|
||||
paused = True
|
||||
except Exception:
|
||||
paused = False
|
||||
yield
|
||||
finally:
|
||||
# If a stage requested the pipeline stop (e.g. user declined a preflight prompt),
|
||||
# do not resume Live rendering.
|
||||
if get_pipeline_stop() is not None:
|
||||
return
|
||||
if paused and ui is not None and hasattr(ui, "resume"):
|
||||
try:
|
||||
ui.resume()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _is_selectable_table(table: Any) -> bool:
|
||||
"""Return True when a table can be used for @ selection."""
|
||||
@@ -96,6 +139,28 @@ _PENDING_PIPELINE_SOURCE: Optional[str] = None
|
||||
_UI_LIBRARY_REFRESH_CALLBACK: Optional[Any] = None
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# PIPELINE STOP SIGNAL
|
||||
# ============================================================================
|
||||
|
||||
_PIPELINE_STOP: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
def request_pipeline_stop(*, reason: str = "", exit_code: int = 0) -> None:
|
||||
"""Request that the pipeline runner stop gracefully after the current stage."""
|
||||
global _PIPELINE_STOP
|
||||
_PIPELINE_STOP = {"reason": str(reason or "").strip(), "exit_code": int(exit_code)}
|
||||
|
||||
|
||||
def get_pipeline_stop() -> Optional[Dict[str, Any]]:
|
||||
return _PIPELINE_STOP
|
||||
|
||||
|
||||
def clear_pipeline_stop() -> None:
|
||||
global _PIPELINE_STOP
|
||||
_PIPELINE_STOP = None
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# PUBLIC API
|
||||
# ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user