| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- import logging
- import subprocess
- import sys
- from pathlib import Path
- from typing import NoReturn
- logger = logging.getLogger(__name__)
- GIT_PATH = None
- try:
- GIT_PATH = subprocess.check_output(["/usr/bin/which", "git"], text=True).strip()
- except subprocess.CalledProcessError:
- # no git found in the system.
- # stop everything and exit. print a user-facing
- # message asking to install git.
- logger.error(
- "search_file_content error => git is not installed",
- )
- sys.exit(1)
- def is_git_repo(repo: str) -> bool:
- """Spawn a shell and use git binary to test if current path is under git."""
- def check_if_valid_repo(repo: str) -> bool:
- is_repo = subprocess.check_output(
- [GIT_PATH, "rev-parse", "--is-inside-work-tree"], text=True, cwd=repo
- )
- is_repo = is_repo.strip()
- if is_repo == "true":
- return True
- elif is_repo == "false":
- return False
- else:
- logger.error(f"is-git-repo error => {is_repo} not a valid path")
- return False
- repo = Path(repo)
- if repo.exists():
- if repo.is_dir():
- return check_if_valid_repo(repo)
- else:
- logger.error(f"is-git-repo error => {repo} is not a directory")
- repo = repo.parent
- return check_if_valid_repo(repo)
- else:
- logger.error(f"is-git-repo error => {repo} is an invalid path")
- return False
- def git_ls_files(
- repo: str, pattern_matching: list[str], fullpath: bool = True
- ) -> list[Path]:
- """Return list of git-tracked filepaths from given repository path."""
- filepaths = subprocess.check_output(
- [GIT_PATH, "ls-files", "--", *pattern_matching], text=True, cwd=repo
- )
- filepaths = filepaths.strip().splitlines()
- if fullpath:
- filepaths = [Path(repo / filepath) for filepath in filepaths]
- return filepaths
- def git_is_file_tracked(repo: str, filepath: str) -> bool:
- """Check if given filepath is found by git ls-files -- <filepath> command."""
- matched = subprocess.check_output(
- [GIT_PATH, "ls-files", "--", filepath], text=True, cwd=repo
- )
- is_tracked = True if matched.strip() == filepath else False
- return is_tracked
- def git_add_commit(repo: str, filepath: str, msg: str) -> NoReturn:
- """Spawn a shell and use git binary to perform `git add` and `git commit`
- on given <filepath>, and with specificed commit <msg>.
- """
- logger.info(f"git-add-commit... {repo, filepath, msg}")
- r = subprocess.run(
- f"{GIT_PATH} add '{filepath}' && {GIT_PATH} commit '{filepath}' -m '{msg}'",
- shell=True,
- cwd=repo,
- )
- logger.info(f"git-add-commit result => {r.returncode, r.stdout, r.stderr}")
- def git_log_last_commit(repo: str):
- """Spawn a shell and run git binary to get the last commit from the
- git log of the given <repo>.
- """
- filepaths = subprocess.check_output(
- [GIT_PATH, "log", "-1", "--pretty=format:%cd"], text=True, cwd=repo
- )
- filepaths = filepaths.strip().splitlines()
- filepaths = [Path(repo / filepath) for filepath in filepaths]
- return filepaths
- def git_get_list_of_changed_filepaths_in_last_commit(
- repo: str, oldrev: str, newrev: str, pattern: list[str]
- ) -> tuple[str, str]:
- """Return list of git modified filepaths, filtered by image type.
- git diff --name-only <oldrev>..<newrev>
- """
- filepaths = subprocess.check_output(
- [
- GIT_PATH,
- "diff",
- "--name-only",
- oldrev,
- newrev,
- ],
- text=True,
- cwd=repo,
- )
- filepaths = filepaths.strip().splitlines()
- filepaths = [filepath for filepath in filepaths if Path(filepath).suffix in pattern]
- return filepaths
|