| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | """Contains utilities to manage Git credentials.""" |
| |
|
| | import re |
| | import subprocess |
| | from typing import List, Optional |
| |
|
| | from ..constants import ENDPOINT |
| | from ._subprocess import run_interactive_subprocess, run_subprocess |
| |
|
| |
|
| | GIT_CREDENTIAL_REGEX = re.compile( |
| | r""" |
| | ^\s* # start of line |
| | credential\.helper # credential.helper value |
| | \s*=\s* # separator |
| | (\w+) # the helper name (group 1) |
| | (\s|$) # whitespace or end of line |
| | """, |
| | flags=re.MULTILINE | re.IGNORECASE | re.VERBOSE, |
| | ) |
| |
|
| |
|
| | def list_credential_helpers(folder: Optional[str] = None) -> List[str]: |
| | """Return the list of git credential helpers configured. |
| | |
| | See https://git-scm.com/docs/gitcredentials. |
| | |
| | Credentials are saved in all configured helpers (store, cache, macOS keychain,...). |
| | Calls "`git credential approve`" internally. See https://git-scm.com/docs/git-credential. |
| | |
| | Args: |
| | folder (`str`, *optional*): |
| | The folder in which to check the configured helpers. |
| | """ |
| | try: |
| | output = run_subprocess("git config --list", folder=folder).stdout |
| | parsed = _parse_credential_output(output) |
| | return parsed |
| | except subprocess.CalledProcessError as exc: |
| | raise EnvironmentError(exc.stderr) |
| |
|
| |
|
| | def set_git_credential(token: str, username: str = "hf_user", folder: Optional[str] = None) -> None: |
| | """Save a username/token pair in git credential for HF Hub registry. |
| | |
| | Credentials are saved in all configured helpers (store, cache, macOS keychain,...). |
| | Calls "`git credential approve`" internally. See https://git-scm.com/docs/git-credential. |
| | |
| | Args: |
| | username (`str`, defaults to `"hf_user"`): |
| | A git username. Defaults to `"hf_user"`, the default user used in the Hub. |
| | token (`str`, defaults to `"hf_user"`): |
| | A git password. In practice, the User Access Token for the Hub. |
| | See https://huggingface.co/settings/tokens. |
| | folder (`str`, *optional*): |
| | The folder in which to check the configured helpers. |
| | """ |
| | with run_interactive_subprocess("git credential approve", folder=folder) as ( |
| | stdin, |
| | _, |
| | ): |
| | stdin.write(f"url={ENDPOINT}\nusername={username.lower()}\npassword={token}\n\n") |
| | stdin.flush() |
| |
|
| |
|
| | def unset_git_credential(username: str = "hf_user", folder: Optional[str] = None) -> None: |
| | """Erase credentials from git credential for HF Hub registry. |
| | |
| | Credentials are erased from the configured helpers (store, cache, macOS |
| | keychain,...), if any. If `username` is not provided, any credential configured for |
| | HF Hub endpoint is erased. |
| | Calls "`git credential erase`" internally. See https://git-scm.com/docs/git-credential. |
| | |
| | Args: |
| | username (`str`, defaults to `"hf_user"`): |
| | A git username. Defaults to `"hf_user"`, the default user used in the Hub. |
| | folder (`str`, *optional*): |
| | The folder in which to check the configured helpers. |
| | """ |
| | with run_interactive_subprocess("git credential reject", folder=folder) as ( |
| | stdin, |
| | _, |
| | ): |
| | standard_input = f"url={ENDPOINT}\n" |
| | if username is not None: |
| | standard_input += f"username={username.lower()}\n" |
| | standard_input += "\n" |
| |
|
| | stdin.write(standard_input) |
| | stdin.flush() |
| |
|
| |
|
| | def _parse_credential_output(output: str) -> List[str]: |
| | """Parse the output of `git credential fill` to extract the password. |
| | |
| | Args: |
| | output (`str`): |
| | The output of `git credential fill`. |
| | """ |
| | |
| | |
| | |
| | return sorted( |
| | set( |
| | match[0] for match in GIT_CREDENTIAL_REGEX.findall(output) |
| | ) |
| | ) |
| |
|