Source code for datalad_next.constraints.git

"""Constraints for Git-related concepts and parameters"""

from datalad_next.runners import (
    CommandError,
    GitRunner,
    StdOutCapture,
)

from .base import Constraint


[docs]class EnsureGitRefName(Constraint): """Ensures that a reference name is well formed Validation is performed by calling `git check-ref-format`. """ def __init__(self, allow_onelevel: bool = True, normalize: bool = True, refspec_pattern: bool = False): """ Parameters ---------- allow_onelevel: Flag whether one-level refnames are accepted, e.g. just 'main' instead of 'refs/heads/main'. normalize: Flag whether a normalized refname is validated and return. This includes removing any leading slash (/) characters and collapsing runs of adjacent slashes between name components into a single slash. refspec_pattern: Flag whether to interpret a value as a reference name pattern for a refspec (allowed to contain a single '*'). """ super().__init__() self._allow_onelevel = allow_onelevel self._normalize = normalize self._refspec_pattern = refspec_pattern def __call__(self, value: str) -> str: if not value: # simple, do here self.raise_for(value, 'refname must not be empty') runner = GitRunner() cmd = ['git', 'check-ref-format'] cmd.append('--allow-onelevel' if self._allow_onelevel else '--no-allow-onelevel') if self._refspec_pattern: cmd.append('--refspec-pattern') if self._normalize: cmd.append('--normalize') cmd.append(value) try: out = runner.run(cmd, protocol=StdOutCapture) except CommandError as e: self.raise_for( value, 'is not a valid refname', __caused_by__=e, ) if self._normalize: return out['stdout'].strip() else: return value
[docs] def short_description(self): return '{}Git refname{}'.format( '(single-level) ' if self._allow_onelevel else '', ' or refspec pattern' if self._refspec_pattern else '', )