huge refactor of the entire codebase, with the goal of improving maintainability, readability, and extensibility. This commit includes changes to almost every file in the project, including:

This commit is contained in:
2026-04-19 00:41:09 -07:00
parent d9e736172a
commit bafd37fdfb
50 changed files with 3258 additions and 4177 deletions
+23 -29
View File
@@ -1,10 +1,4 @@
"""Provider registry for ResultTable API (breaking, strict API).
Providers register themselves here with an adapter and optional column factory
and selection function. Consumers (cmdlets) can look up providers by name and
obtain the columns and selection behavior for building tables and for selection
args used by subsequent cmdlets.
"""
"""Plugin registry for the strict ResultTable API."""
from __future__ import annotations
from dataclasses import dataclass
@@ -18,7 +12,7 @@ SelectionFn = Callable[[ResultModel], List[str]]
@dataclass
class Provider:
class Plugin:
name: str
adapter: ProviderAdapter
# columns can be a static list or a factory that derives columns from sample rows
@@ -28,7 +22,7 @@ class Provider:
def get_columns(self, rows: Optional[Iterable[ResultModel]] = None) -> List[ColumnSpec]:
if self.columns is None:
raise ValueError(f"provider '{self.name}' must define columns")
raise ValueError(f"plugin '{self.name}' must define columns")
if callable(self.columns):
rows_list = list(rows) if rows is not None else []
@@ -37,13 +31,13 @@ class Provider:
cols = list(self.columns)
if not cols:
raise ValueError(f"provider '{self.name}' produced no columns")
raise ValueError(f"plugin '{self.name}' produced no columns")
return cols
def selection_args(self, row: ResultModel) -> List[str]:
if not callable(self.selection_fn):
raise ValueError(f"provider '{self.name}' must define a selection function")
raise ValueError(f"plugin '{self.name}' must define a selection function")
sel = list(self.selection_fn(ensure_result_model(row)))
return sel
@@ -54,7 +48,7 @@ class Provider:
try:
rows = [ensure_result_model(r) for r in self.adapter(items)]
except Exception as exc:
raise RuntimeError(f"provider '{self.name}' adapter failed") from exc
raise RuntimeError(f"plugin '{self.name}' adapter failed") from exc
cols = self.get_columns(rows)
return ResultTable(provider=self.name, rows=rows, columns=cols, meta=self.metadata or {})
@@ -82,37 +76,37 @@ class Provider:
return [self.serialize_row(r) for r in rows]
_PROVIDERS: Dict[str, Provider] = {}
_PLUGINS: Dict[str, Plugin] = {}
def register_provider(
def register_plugin(
name: str,
adapter: ProviderAdapter,
*,
columns: Union[List[ColumnSpec], ColumnFactory],
selection_fn: SelectionFn,
metadata: Optional[Dict[str, Any]] = None,
) -> Provider:
) -> Plugin:
name = str(name or "").strip().lower()
if not name:
raise ValueError("provider name required")
if name in _PROVIDERS:
raise ValueError(f"provider already registered: {name}")
raise ValueError("plugin name required")
if name in _PLUGINS:
raise ValueError(f"plugin already registered: {name}")
if columns is None:
raise ValueError("provider registration requires columns")
raise ValueError("plugin registration requires columns")
if selection_fn is None:
raise ValueError("provider registration requires selection_fn")
p = Provider(name=name, adapter=adapter, columns=columns, selection_fn=selection_fn, metadata=metadata)
_PROVIDERS[name] = p
return p
raise ValueError("plugin registration requires selection_fn")
plugin = Plugin(name=name, adapter=adapter, columns=columns, selection_fn=selection_fn, metadata=metadata)
_PLUGINS[name] = plugin
return plugin
def get_provider(name: str) -> Provider:
def get_plugin(name: str) -> Plugin:
normalized = str(name or "").lower()
if normalized not in _PROVIDERS:
raise KeyError(f"provider not registered: {name}")
return _PROVIDERS[normalized]
if normalized not in _PLUGINS:
raise KeyError(f"plugin not registered: {name}")
return _PLUGINS[normalized]
def list_providers() -> List[str]:
return list(_PROVIDERS.keys())
def list_plugins() -> List[str]:
return list(_PLUGINS.keys())