Skip to content

project_lib — multi-layer config resolution and template rendering #68

@djdarcy

Description

@djdarcy

project_lib — multi-layer config resolution and template rendering

Problem

Several ghtraf commands need to resolve project configuration from multiple sources with a defined precedence order:

CLI flags  >  .ghtraf.json (per-project)  >  ~/.ghtraf/config.json (global)

Currently, config.py handles some of this, but the logic is ad-hoc and will be duplicated across commands:

  • ghtraf status needs to know which repos are tracked (from config)
  • ghtraf list needs to enumerate all configured repos across global + local configs
  • ghtraf verify needs config to know expected gist IDs
  • ghtraf init needs template paths from config
  • ghtraf create needs defaults for gist descriptions, org names, etc.

Without a shared config resolution library, each command will re-implement the same "read .ghtraf.json, fall back to global, merge with CLI flags" logic — creating the same kind of divergence risk that plan-execute was designed to prevent.

Proposed solution

A project_lib library in src/ghtraf/lib/project_lib/ that provides:

@dataclass
class ProjectConfig:
    """Resolved configuration for a single tracked project."""
    repo: str                    # "owner/repo"
    badge_gist_id: str | None
    archive_gist_id: str | None
    dashboard_path: str | None
    template_source: str         # "bundled" | path to custom templates
    # ... other per-project settings

@dataclass
class GlobalConfig:
    """User-wide ghtraf settings."""
    default_org: str | None
    github_token_source: str     # "env" | "gh-cli" | "keyring"
    tracked_repos: list[str]
    # ... other global settings

def resolve_config(
    cli_args: dict,
    project_path: Path | None = None,
    global_path: Path | None = None,
) -> ProjectConfig:
    """Three-layer merge: CLI > project > global."""
    ...

def discover_projects(
    global_config: GlobalConfig,
) -> list[ProjectConfig]:
    """Enumerate all tracked repos for status/list commands."""
    ...

Design considerations

Acceptance criteria

  • src/ghtraf/lib/project_lib/ exists with config resolution
  • Three-layer merge: CLI flags > .ghtraf.json > ~/.ghtraf/config.json
  • discover_projects() enumerates tracked repos from global config
  • Unit tests for merge precedence (CLI wins over project wins over global)
  • At least one command (status or list) uses project_lib for config resolution
  • Config dataclasses are serializable (JSON round-trip for future ghtraf config command)

Related issues

Analysis

See 2026-03-02__21-48-45__dev-workflow-process_missing-issues-and-plan-gaps.md for gap analysis (Gap 5).
See 2026-02-27__16-02-55__dev-workflow-process_cli-architecture-ordering-and-init-command.md for the three-layer config design origin.

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureStructural and architectural decisionsideasExploratory ideas needing further thought

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions