/usr/lib/python3/dist-packages/mypy/git.py is in python3-mypy 0.560-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | """Utilities for verifying git integrity."""
# Used also from setup.py, so don't pull in anything additional here (like mypy or typing):
import os
import pipes
import subprocess
import sys
MYPY = False
if MYPY:
from typing import Iterator
def is_git_repo(dir: str) -> bool:
"""Is the given directory version-controlled with git?"""
return os.path.exists(os.path.join(dir, ".git"))
def have_git() -> bool:
"""Can we run the git executable?"""
try:
subprocess.check_output(["git", "--help"])
return True
except subprocess.CalledProcessError:
return False
except OSError:
return False
def get_submodules(dir: str) -> "Iterator[str]":
"""Return a list of all git top-level submodules in a given directory."""
# It would be nicer to do
# "git submodule foreach 'echo MODULE $name $path $sha1 $toplevel'"
# but that wouldn't work on Windows.
output = subprocess.check_output(["git", "submodule", "status"], cwd=dir)
# "<status><sha1> name desc"
# status='-': not initialized
# status='+': changed
# status='u': merge conflicts
# status=' ': up-to-date
for line in output.splitlines():
# Skip the status indicator, as it could be a space can confuse the split.
line = line[1:]
name = line.split(b" ")[1]
yield name.decode(sys.getfilesystemencoding())
def git_revision(dir: str) -> bytes:
"""Get the SHA-1 of the HEAD of a git repository."""
return subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=dir).strip()
def submodule_revision(dir: str, submodule: str) -> bytes:
"""Get the SHA-1 a submodule is supposed to have."""
output = subprocess.check_output(["git", "ls-files", "-s", submodule], cwd=dir).strip()
# E.g.: "160000 e4a7edb949e0b920b16f61aeeb19fc3d328f3012 0 typeshed"
return output.split()[1]
def is_dirty(dir: str) -> bool:
"""Check whether a git repository has uncommitted changes."""
output = subprocess.check_output(["git", "status", "-uno", "--porcelain"], cwd=dir)
return output.strip() != b""
def has_extra_files(dir: str) -> bool:
"""Check whether a git repository has untracked files."""
output = subprocess.check_output(["git", "clean", "--dry-run", "-d"], cwd=dir)
return output.strip() != b""
def warn_no_git_executable() -> None:
print("Warning: Couldn't check git integrity. "
"git executable not in path.", file=sys.stderr)
def warn_dirty(dir: str) -> None:
print("Warning: git module '{}' has uncommitted changes.".format(dir),
file=sys.stderr)
print("Go to the directory", file=sys.stderr)
print(" {}".format(dir), file=sys.stderr)
print("and commit or reset your changes", file=sys.stderr)
def warn_extra_files(dir: str) -> None:
print("Warning: git module '{}' has untracked files.".format(dir),
file=sys.stderr)
print("Go to the directory", file=sys.stderr)
print(" {}".format(dir), file=sys.stderr)
print("and add & commit your new files.", file=sys.stderr)
def chdir_prefix(dir: str) -> str:
"""Return the command to change to the target directory, plus '&&'."""
if os.path.relpath(dir) != ".":
return "cd " + pipes.quote(dir) + " && "
else:
return ""
def error_submodule_not_initialized(name: str, dir: str) -> None:
print("Submodule '{}' not initialized.".format(name), file=sys.stderr)
print("Please run:", file=sys.stderr)
print(" {}git submodule update --init {}".format(
chdir_prefix(dir), name), file=sys.stderr)
def error_submodule_not_updated(name: str, dir: str) -> None:
print("Submodule '{}' not updated.".format(name), file=sys.stderr)
print("Please run:", file=sys.stderr)
print(" {}git submodule update {}".format(
chdir_prefix(dir), name), file=sys.stderr)
print("(If you got this message because you updated {} yourself".format(name), file=sys.stderr)
print(" then run \"git add {}\" to silence this check)".format(name), file=sys.stderr)
def verify_git_integrity_or_abort(datadir: str) -> None:
"""Verify the (submodule) integrity of a git repository.
Potentially output warnings/errors (to stderr), and exit with status 1
if we detected a severe problem.
"""
datadir = datadir or '.'
if not is_git_repo(datadir):
return
if not have_git():
warn_no_git_executable()
return
for submodule in get_submodules(datadir):
submodule_path = os.path.join(datadir, submodule)
if not is_git_repo(submodule_path):
error_submodule_not_initialized(submodule, datadir)
sys.exit(1)
elif submodule_revision(datadir, submodule) != git_revision(submodule_path):
error_submodule_not_updated(submodule, datadir)
sys.exit(1)
elif is_dirty(submodule_path):
warn_dirty(submodule)
elif has_extra_files(submodule_path):
warn_extra_files(submodule)
|