Source code for pjkm.core.defaults

"""User defaults: loads config from ~/.pjkmrc.yaml or ./.pjkmrc.yaml."""

from __future__ import annotations

from pathlib import Path
from typing import Any

import yaml
from pydantic import BaseModel, Field


[docs] class GitHubDefaults(BaseModel): """GitHub/remote repository defaults."""
[docs] org: str = ""
[docs] visibility: str = "private" # "private", "public", "internal"
[docs] remote: str = "" # e.g. "github.com", "github.mycompany.com"
[docs] create_repo: bool = False # auto-create repo via gh CLI
[docs] default_branch: str = "main"
[docs] class GroupSource(BaseModel): """A remote git repo containing package group YAML definitions."""
[docs] url: str # git URL: https://... or git@...:...
[docs] name: str = "" # short name (derived from URL if empty)
[docs] path: str = "" # subdirectory within the repo (default: root)
[docs] ref: str = "" # branch/tag/commit (default: HEAD)
[docs] class UserDefaults(BaseModel): """User-configurable defaults loaded from .pjkmrc.yaml files."""
[docs] author_name: str = ""
[docs] author_email: str = ""
[docs] license: str = "MIT"
[docs] python_version: str = "3.13"
[docs] archetype: str = "single_package"
[docs] groups: list[str] = Field(default_factory=list)
[docs] target_dir: str = "."
[docs] github: GitHubDefaults = Field(default_factory=GitHubDefaults)
[docs] group_sources: list[GroupSource] = Field(default_factory=list)
@classmethod
[docs] def load(cls) -> UserDefaults: """Load defaults from config files. Searches in order (later files override earlier): 1. ~/.pjkmrc.yaml (global defaults) 2. ./.pjkmrc.yaml (project/workspace defaults) """ merged: dict[str, Any] = {} paths = [ Path.home() / ".pjkmrc.yaml", Path.cwd() / ".pjkmrc.yaml", ] for path in paths: if path.is_file(): try: data = yaml.safe_load(path.read_text()) or {} if isinstance(data, dict): merged.update(data) except Exception: pass # Silently skip malformed config return cls.model_validate(merged)