core: root discovery + status
This commit is contained in:
@@ -3,6 +3,14 @@
|
|||||||
__version__ = "0.0.0"
|
__version__ = "0.0.0"
|
||||||
|
|
||||||
from .config import load_config, load_config_model
|
from .config import load_config, load_config_model
|
||||||
|
from .core import find_root, resolve_context_root
|
||||||
from .plugins import discover_plugins, load_plugins
|
from .plugins import discover_plugins, load_plugins
|
||||||
|
|
||||||
__all__ = ["load_config", "load_config_model", "discover_plugins", "load_plugins"]
|
__all__ = [
|
||||||
|
"load_config",
|
||||||
|
"load_config_model",
|
||||||
|
"discover_plugins",
|
||||||
|
"load_plugins",
|
||||||
|
"find_root",
|
||||||
|
"resolve_context_root",
|
||||||
|
]
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from pathlib import Path
|
|||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
from .config import load_config_model
|
from .config import load_config_model
|
||||||
|
from .core import find_root, resolve_context_root
|
||||||
from .plugins import discover_plugins, load_plugins
|
from .plugins import discover_plugins, load_plugins
|
||||||
from .schema import AFSConfig, GeneralConfig, WorkspaceDirectory
|
from .schema import AFSConfig, GeneralConfig, WorkspaceDirectory
|
||||||
|
|
||||||
@@ -128,6 +129,27 @@ def _plugins_command(args: argparse.Namespace) -> int:
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def _status_command(args: argparse.Namespace) -> int:
|
||||||
|
start_dir = Path(args.start_dir).expanduser().resolve() if args.start_dir else None
|
||||||
|
root = find_root(start_dir)
|
||||||
|
config = load_config_model()
|
||||||
|
context_root = resolve_context_root(config, root)
|
||||||
|
|
||||||
|
print(f"context_root: {context_root}")
|
||||||
|
print(f"linked_root: {root if root else '(none)'}")
|
||||||
|
|
||||||
|
missing = []
|
||||||
|
for name in AFS_DIRS:
|
||||||
|
if not (context_root / name).exists():
|
||||||
|
missing.append(name)
|
||||||
|
if missing:
|
||||||
|
print("missing_dirs: " + ", ".join(missing))
|
||||||
|
else:
|
||||||
|
print("missing_dirs: (none)")
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def build_parser() -> argparse.ArgumentParser:
|
def build_parser() -> argparse.ArgumentParser:
|
||||||
parser = argparse.ArgumentParser(prog="afs")
|
parser = argparse.ArgumentParser(prog="afs")
|
||||||
subparsers = parser.add_subparsers(dest="command")
|
subparsers = parser.add_subparsers(dest="command")
|
||||||
@@ -147,6 +169,10 @@ def build_parser() -> argparse.ArgumentParser:
|
|||||||
plugins_parser.add_argument("--load", action="store_true", help="Attempt to import plugins.")
|
plugins_parser.add_argument("--load", action="store_true", help="Attempt to import plugins.")
|
||||||
plugins_parser.set_defaults(func=_plugins_command)
|
plugins_parser.set_defaults(func=_plugins_command)
|
||||||
|
|
||||||
|
status_parser = subparsers.add_parser("status", help="Show context root status.")
|
||||||
|
status_parser.add_argument("--start-dir", help="Directory to search from.")
|
||||||
|
status_parser.set_defaults(func=_status_command)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
34
src/afs/core.py
Normal file
34
src/afs/core.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
"""Core AFS helpers."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from .schema import AFSConfig
|
||||||
|
|
||||||
|
|
||||||
|
def find_root(start_dir: Path | None = None) -> Path | None:
|
||||||
|
"""Find a .context directory by walking upward."""
|
||||||
|
if start_dir is None:
|
||||||
|
start_dir = Path.cwd()
|
||||||
|
current = start_dir.resolve()
|
||||||
|
for parent in [current, *current.parents]:
|
||||||
|
candidate = parent / ".context"
|
||||||
|
if candidate.exists() and candidate.is_dir():
|
||||||
|
return candidate
|
||||||
|
if (parent / "afs.toml").exists():
|
||||||
|
return parent / ".context"
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_context_root(config: AFSConfig | None, linked_root: Path | None) -> Path:
|
||||||
|
"""Resolve the active context root for this machine."""
|
||||||
|
env_root = os.environ.get("AFS_CONTEXT_ROOT")
|
||||||
|
if env_root:
|
||||||
|
return Path(env_root).expanduser().resolve()
|
||||||
|
if linked_root:
|
||||||
|
return linked_root.resolve()
|
||||||
|
if config:
|
||||||
|
return config.general.context_root
|
||||||
|
return (Path.home() / ".context").resolve()
|
||||||
Reference in New Issue
Block a user