Skip to content

subproject.py

Objects to interact with subprojects.

A subproject is a project that gets rendered and/or updated with Copier.

Subproject dataclass

Object that represents the subproject and its current state.

Attributes:

Name Type Description
local_abspath AbsolutePath

Absolute path on local disk pointing to the subproject root folder.

answers_relpath Path

Relative path to the answers file.

Source code in copier/subproject.py
class Subproject:
    """Object that represents the subproject and its current state.

    Attributes:
        local_abspath:
            Absolute path on local disk pointing to the subproject root folder.

        answers_relpath:
            Relative path to [the answers file][the-copier-answersyml-file].
    """

    local_abspath: AbsolutePath
    answers_relpath: Path = Path(".copier-answers.yml")

    def is_dirty(self) -> bool:
        """Indicates if the local template root is dirty.

        Only applicable for VCS-tracked templates.
        """
        if self.vcs == "git":
            with local.cwd(self.local_abspath):
                return bool(git("status", "--porcelain").strip())
        return False

    @property
    def _raw_answers(self) -> AnyByStrDict:
        """The last answers, loaded raw as yaml."""
        try:
            return yaml.safe_load(
                (self.local_abspath / self.answers_relpath).read_text()
            )
        except OSError:
            return {}

    @cached_property
    def last_answers(self) -> AnyByStrDict:
        """Last answers, excluding private ones (except _src_path and _commit)."""
        return {
            key: value
            for key, value in self._raw_answers.items()
            if key in {"_src_path", "_commit"} or not key.startswith("_")
        }

    @cached_property
    def template(self) -> Optional[Template]:
        """Template, as it was used the last time."""
        last_url = self.last_answers.get("_src_path")
        last_ref = self.last_answers.get("_commit")
        if last_url:
            return Template(url=last_url, ref=last_ref)

    @cached_property
    def vcs(self) -> Optional[VCSTypes]:
        """VCS type of the subproject."""
        if is_in_git_repo(self.local_abspath):
            return "git"

last_answers: Dict[str, Any] cached property writable

Last answers, excluding private ones (except _src_path and _commit).

template: Optional[copier.template.Template] cached property writable

Template, as it was used the last time.

vcs: Optional[Literal['git']] cached property writable

VCS type of the subproject.

is_dirty(self)

Indicates if the local template root is dirty.

Only applicable for VCS-tracked templates.

Source code in copier/subproject.py
def is_dirty(self) -> bool:
    """Indicates if the local template root is dirty.

    Only applicable for VCS-tracked templates.
    """
    if self.vcs == "git":
        with local.cwd(self.local_abspath):
            return bool(git("status", "--porcelain").strip())
    return False
Back to top