Skip to content

Commit 2f38625

Browse files
authored
bpo-29656: Handle PR branches in 'make patchcheck' (#302) (#626)
(cherry picked from commit 482f7a2)
1 parent 7c6d6e0 commit 2f38625

File tree

1 file changed

+52
-6
lines changed

1 file changed

+52
-6
lines changed

Tools/scripts/patchcheck.py

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
SRCDIR = sysconfig.get_config_var('srcdir')
1414

15-
1615
def n_files_str(count):
1716
"""Return 'N file(s)' with the proper plurality on 'file'."""
1817
return "{} file{}".format(count, "s" if count != 1 else "")
@@ -46,27 +45,73 @@ def mq_patches_applied():
4645
return st.returncode == 0 and bstdout
4746

4847

48+
def get_git_branch():
49+
"""Get the symbolic name for the current git branch"""
50+
cmd = "git rev-parse --abbrev-ref HEAD".split()
51+
try:
52+
return subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
53+
except subprocess.CalledProcessError:
54+
return None
55+
56+
57+
def get_git_upstream_remote():
58+
"""Get the remote name to use for upstream branches
59+
60+
Uses "upstream" if it exists, "origin" otherwise
61+
"""
62+
cmd = "git remote get-url upstream".split()
63+
try:
64+
subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
65+
except subprocess.CalledProcessError:
66+
return "origin"
67+
return "upstream"
68+
69+
70+
@status("Getting base branch for PR",
71+
info=lambda x: x if x is not None else "not a PR branch")
72+
def get_base_branch():
73+
if not os.path.isdir(os.path.join(SRCDIR, '.git')):
74+
# Not a git checkout, so there's no base branch
75+
return None
76+
version = sys.version_info
77+
if version.releaselevel == 'alpha':
78+
base_branch = "master"
79+
else:
80+
base_branch = "{0.major}.{0.minor}".format(version)
81+
this_branch = get_git_branch()
82+
if this_branch is None or this_branch == base_branch:
83+
# Not on a git PR branch, so there's no base branch
84+
return None
85+
upstream_remote = get_git_upstream_remote()
86+
return upstream_remote + "/" + base_branch
87+
88+
4989
@status("Getting the list of files that have been added/changed",
5090
info=lambda x: n_files_str(len(x)))
51-
def changed_files():
91+
def changed_files(base_branch=None):
5292
"""Get the list of changed or added files from Mercurial or git."""
5393
if os.path.isdir(os.path.join(SRCDIR, '.hg')):
94+
if base_branch is not None:
95+
sys.exit('need a git checkout to check PR status')
5496
cmd = 'hg status --added --modified --no-status'
5597
if mq_patches_applied():
5698
cmd += ' --rev qparent'
5799
with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) as st:
58100
return [x.decode().rstrip() for x in st.stdout]
59101
elif os.path.isdir(os.path.join(SRCDIR, '.git')):
60-
cmd = 'git status --porcelain'
102+
if base_branch:
103+
cmd = 'git diff --name-status ' + base_branch
104+
else:
105+
cmd = 'git status --porcelain'
61106
filenames = []
62107
with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) as st:
63108
for line in st.stdout:
64109
line = line.decode().rstrip()
65-
status = set(line[:2])
110+
status_text, filename = line.split(maxsplit=1)
111+
status = set(status_text)
66112
# modified, added or unmerged files
67113
if not status.intersection('MAU'):
68114
continue
69-
filename = line[3:]
70115
if ' -> ' in filename:
71116
# file is renamed
72117
filename = filename.split(' -> ', 2)[1].strip()
@@ -165,7 +210,8 @@ def regenerated_pyconfig_h_in(file_paths):
165210
return "not needed"
166211

167212
def main():
168-
file_paths = changed_files()
213+
base_branch = get_base_branch()
214+
file_paths = changed_files(base_branch)
169215
python_files = [fn for fn in file_paths if fn.endswith('.py')]
170216
c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))]
171217
doc_files = [fn for fn in file_paths if fn.startswith('Doc') and

0 commit comments

Comments
 (0)