# The purpose of this script is to check all the maintenance branches of the
# given repository, and find which pull requests are included in which
# branches. The output is a JSON file that contains for each pull request the
# list of all branches in which it is included. We look specifically for the
# message "Merge pull request #xxxx " in commit messages, so this is not
# completely foolproof, but seems to work for now.

import os
import sys
import json
import re
import subprocess
import tempfile
from collections import defaultdict

from astropy.utils.console import color_print

from common import get_branches

if sys.argv[1:]:
    REPOSITORY_NAME = sys.argv[1]
else:
    REPOSITORY_NAME = 'astropy/astropy'

print("The repository this script currently works with is '{}'.\n"
      .format(REPOSITORY_NAME))


REPOSITORY = f'git://github.com/{REPOSITORY_NAME}.git'
NAME = os.path.basename(REPOSITORY_NAME)

DIRTOCLONEIN = tempfile.mkdtemp()  # set this to a non-temp directory to retain the clone between runs
ORIGIN = 'origin'  # set this to None to not fetch anything but rather use the directory as-is.

STARTDIR = os.path.abspath('.')

# The branches we are interested in
BRANCHES = get_branches(REPOSITORY_NAME)

# Read in a list of all the PRs
with open(f'merged_pull_requests_{NAME}.json') as merged:
    merged_prs = json.load(merged)

# Set up a dictionary where each key will be a PR and each value will be a list
# of branches in which the PR is present
pr_branches = defaultdict(list)


try:
    # Set up repository
    color_print(f'Cloning {REPOSITORY}', 'green')
    os.chdir(DIRTOCLONEIN)
    if os.path.isdir(NAME):
        # already exists... assume its the right thing
        color_print('"{}" directory already exists - assuming it is an already '
                    'existing clone'.format(NAME), 'yellow')
        os.chdir(NAME)
        if ORIGIN:
            subprocess.call(f'git fetch {ORIGIN}', shell=True)
    else:
        subprocess.call(f'git clone {REPOSITORY}', shell=True)
        os.chdir(NAME)

    # Loop over branches and find all PRs in the branch
    for branch in BRANCHES:

        # Change branch
        color_print(f'Switching to branch {branch}', 'green')
        subprocess.call('git reset --hard', shell=True)
        subprocess.call('git clean -fxd', shell=True)
        subprocess.call(f'git checkout {branch}', shell=True)
        if ORIGIN:
            subprocess.call(f'git reset --hard {ORIGIN}/{branch}', shell=True)

        # Extract log:
        log = subprocess.check_output('git log', shell=True).decode('utf-8')

        # Check for the presence of the PR in the log
        for pr in (re.findall(r'Merge pull request #(\d+) ', log) +
                   re.findall(r'Backport PR #(\d+):', log)):
            pr_branches[pr].append(branch)

finally:
    os.chdir(STARTDIR)

with open(f'pull_requests_branches_{NAME}.json', 'w') as f:
    json.dump(pr_branches, f, sort_keys=True, indent=2)

[((30, 7, 30, 40), 'os.path.basename', 'os.path.basename', ({(30, 24, 30, 39): 'REPOSITORY_NAME'}, {}), '(REPOSITORY_NAME)', False, 'import os\n'), ((32, 15, 32, 33), 'tempfile.mkdtemp', 'tempfile.mkdtemp', ({}, {}), '()', False, 'import tempfile\n'), ((35, 11, 35, 31), 'os.path.abspath', 'os.path.abspath', ({(35, 27, 35, 30): '"""."""'}, {}), "('.')", False, 'import os\n'), ((38, 11, 38, 40), 'common.get_branches', 'get_branches', ({(38, 24, 38, 39): 'REPOSITORY_NAME'}, {}), '(REPOSITORY_NAME)', False, 'from common import get_branches\n'), ((46, 14, 46, 31), 'collections.defaultdict', 'defaultdict', ({(46, 26, 46, 30): 'list'}, {}), '(list)', False, 'from collections import defaultdict\n'), ((42, 17, 42, 34), 'json.load', 'json.load', ({(42, 27, 42, 33): 'merged'}, {}), '(merged)', False, 'import json\n'), ((51, 4, 51, 49), 'astropy.utils.console.color_print', 'color_print', ({(51, 16, 51, 39): 'f"""Cloning {REPOSITORY}"""', (51, 41, 51, 48): '"""green"""'}, {}), "(f'Cloning {REPOSITORY}', 'green')", False, 'from astropy.utils.console import color_print\n'), ((52, 4, 52, 26), 'os.chdir', 'os.chdir', ({(52, 13, 52, 25): 'DIRTOCLONEIN'}, {}), '(DIRTOCLONEIN)', False, 'import os\n'), ((53, 7, 53, 26), 'os.path.isdir', 'os.path.isdir', ({(53, 21, 53, 25): 'NAME'}, {}), '(NAME)', False, 'import os\n'), ((84, 4, 84, 22), 'os.chdir', 'os.chdir', ({(84, 13, 84, 21): 'STARTDIR'}, {}), '(STARTDIR)', False, 'import os\n'), ((87, 4, 87, 55), 'json.dump', 'json.dump', (), '', False, 'import json\n'), ((57, 8, 57, 22), 'os.chdir', 'os.chdir', ({(57, 17, 57, 21): 'NAME'}, {}), '(NAME)', False, 'import os\n'), ((61, 8, 61, 62), 'subprocess.call', 'subprocess.call', (), '', False, 'import subprocess\n'), ((62, 8, 62, 22), 'os.chdir', 'os.chdir', ({(62, 17, 62, 21): 'NAME'}, {}), '(NAME)', False, 'import os\n'), ((68, 8, 68, 61), 'astropy.utils.console.color_print', 'color_print', ({(68, 20, 68, 51): 'f"""Switching to branch {branch}"""', (68, 53, 68, 60): '"""green"""'}, {}), "(f'Switching to branch {branch}', 'green')", False, 'from astropy.utils.console import color_print\n'), ((69, 8, 69, 55), 'subprocess.call', 'subprocess.call', (), '', False, 'import subprocess\n'), ((70, 8, 70, 53), 'subprocess.call', 'subprocess.call', (), '', False, 'import subprocess\n'), ((71, 8, 71, 61), 'subprocess.call', 'subprocess.call', (), '', False, 'import subprocess\n'), ((59, 12, 59, 62), 'subprocess.call', 'subprocess.call', (), '', False, 'import subprocess\n'), ((73, 12, 73, 78), 'subprocess.call', 'subprocess.call', (), '', False, 'import subprocess\n'), ((79, 19, 79, 65), 're.findall', 're.findall', ({(79, 30, 79, 59): '"""Merge pull request #(\\\\d+) """', (79, 61, 79, 64): 'log'}, {}), "('Merge pull request #(\\\\d+) ', log)", False, 'import re\n'), ((80, 19, 80, 58), 're.findall', 're.findall', ({(80, 30, 80, 52): '"""Backport PR #(\\\\d+):"""', (80, 54, 80, 57): 'log'}, {}), "('Backport PR #(\\\\d+):', log)", False, 'import re\n'), ((76, 14, 76, 60), 'subprocess.check_output', 'subprocess.check_output', (), '', False, 'import subprocess\n')]