Skip to content

project_model

project_model

Project and preset data models — DDD Value Objects.

Pure data types with no filesystem or subprocess I/O. These are the value objects in the domain model: they carry configuration data but have no behavior beyond computed paths.

:class:ProjectConfig is loaded from project.yml by the companion :mod:~terok.lib.core.projects module and wrapped by the rich :class:~terok.lib.domain.project.Project aggregate to provide behavior.

ProjectConfig

Bases: BaseModel

Resolved project configuration loaded from project.yml.

Pure value object — holds configuration fields with no behavior beyond computed paths. The rich domain object :class:~terok.lib.domain.project.Project wraps this and provides behavior.

presets_dir property

Directory for preset config files for this project.

PresetInfo(name, source, path) dataclass

Metadata about a discovered preset.

effective_ssh_key_name(project, key_type='ed25519')

Return the SSH key filename that should be used for this project.

Precedence
  1. Explicit ssh.key_name from project.yml (project.ssh_key_name)
  2. Derived default: id__, e.g. id_ed25519_myproj

This helper centralizes the default so ssh-init, container env (SSH_KEY_NAME) and host-side git helpers all agree even when project.yml omits ssh.key_name.

Source code in src/terok/lib/core/project_model.py
def effective_ssh_key_name(project: ProjectConfig, key_type: str = "ed25519") -> str:
    """Return the SSH key filename that should be used for this project.

    Precedence:
      1. Explicit `ssh.key_name` from project.yml (project.ssh_key_name)
      2. Derived default: id_<type>_<project_id>, e.g. id_ed25519_myproj

    This helper centralizes the default so ssh-init, container env (SSH_KEY_NAME)
    and host-side git helpers all agree even when project.yml omits ssh.key_name.
    """

    if project.ssh_key_name:
        return project.ssh_key_name
    algo = "ed25519" if key_type == "ed25519" else "rsa"
    return f"id_{algo}_{project.id}"

validate_project_id(project_id)

Ensure a project ID is safe for use as a directory and OCI image name.

Raises SystemExit if the ID is empty, contains uppercase letters, path separators or traversal sequences, or uses characters outside [a-z0-9_-].

Source code in src/terok/lib/core/project_model.py
def validate_project_id(project_id: str) -> None:
    """Ensure a project ID is safe for use as a directory and OCI image name.

    Raises SystemExit if the ID is empty, contains uppercase letters, path
    separators or traversal sequences, or uses characters outside
    ``[a-z0-9_-]``.
    """
    if not project_id:
        raise SystemExit("Project ID must not be empty")
    if not re.fullmatch(r"[a-z0-9][a-z0-9_-]*", project_id):
        raise SystemExit(
            f"Invalid project ID '{project_id}': "
            "must start with a lowercase letter or digit, followed by lowercase letters, "
            "digits, hyphens, or underscores"
        )