# 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)

[((883, 916), 'os.path.basename', 'os.path.basename', (['REPOSITORY_NAME'], {}), '(REPOSITORY_NAME)\n', (899, 916), False, 'import os\n'), ((933, 951), 'tempfile.mkdtemp', 'tempfile.mkdtemp', ([], {}), '()\n', (949, 951), False, 'import tempfile\n'), ((1129, 1149), 'os.path.abspath', 'os.path.abspath', (['"""."""'], {}), "('.')\n", (1144, 1149), False, 'import os\n'), ((1198, 1227), 'common.get_branches', 'get_branches', (['REPOSITORY_NAME'], {}), '(REPOSITORY_NAME)\n', (1210, 1227), False, 'from common import get_branches\n'), ((1490, 1507), 'collections.defaultdict', 'defaultdict', (['list'], {}), '(list)\n', (1501, 1507), False, 'from collections import defaultdict\n'), ((1336, 1353), 'json.load', 'json.load', (['merged'], {}), '(merged)\n', (1345, 1353), False, 'import json\n'), ((1543, 1588), 'astropy.utils.console.color_print', 'color_print', (['f"""Cloning {REPOSITORY}"""', '"""green"""'], {}), "(f'Cloning {REPOSITORY}', 'green')\n", (1554, 1588), False, 'from astropy.utils.console import color_print\n'), ((1593, 1615), 'os.chdir', 'os.chdir', (['DIRTOCLONEIN'], {}), '(DIRTOCLONEIN)\n', (1601, 1615), False, 'import os\n'), ((1623, 1642), 'os.path.isdir', 'os.path.isdir', (['NAME'], {}), '(NAME)\n', (1636, 1642), False, 'import os\n'), ((2826, 2844), 'os.chdir', 'os.chdir', (['STARTDIR'], {}), '(STARTDIR)\n', (2834, 2844), False, 'import os\n'), ((2910, 2961), 'json.dump', 'json.dump', (['pr_branches', 'f'], {'sort_keys': '(True)', 'indent': '(2)'}), '(pr_branches, f, sort_keys=True, indent=2)\n', (2919, 2961), False, 'import json\n'), ((1849, 1863), 'os.chdir', 'os.chdir', (['NAME'], {}), '(NAME)\n', (1857, 1863), False, 'import os\n'), ((1964, 2018), 'subprocess.call', 'subprocess.call', (['f"""git clone {REPOSITORY}"""'], {'shell': '(True)'}), "(f'git clone {REPOSITORY}', shell=True)\n", (1979, 2018), False, 'import subprocess\n'), ((2027, 2041), 'os.chdir', 'os.chdir', (['NAME'], {}), '(NAME)\n', (2035, 2041), False, 'import os\n'), ((2160, 2213), 'astropy.utils.console.color_print', 'color_print', (['f"""Switching to branch {branch}"""', '"""green"""'], {}), "(f'Switching to branch {branch}', 'green')\n", (2171, 2213), False, 'from astropy.utils.console import color_print\n'), ((2222, 2269), 'subprocess.call', 'subprocess.call', (['"""git reset --hard"""'], {'shell': '(True)'}), "('git reset --hard', shell=True)\n", (2237, 2269), False, 'import subprocess\n'), ((2278, 2323), 'subprocess.call', 'subprocess.call', (['"""git clean -fxd"""'], {'shell': '(True)'}), "('git clean -fxd', shell=True)\n", (2293, 2323), False, 'import subprocess\n'), ((2332, 2385), 'subprocess.call', 'subprocess.call', (['f"""git checkout {branch}"""'], {'shell': '(True)'}), "(f'git checkout {branch}', shell=True)\n", (2347, 2385), False, 'import subprocess\n'), ((1895, 1945), 'subprocess.call', 'subprocess.call', (['f"""git fetch {ORIGIN}"""'], {'shell': '(True)'}), "(f'git fetch {ORIGIN}', shell=True)\n", (1910, 1945), False, 'import subprocess\n'), ((2417, 2483), 'subprocess.call', 'subprocess.call', (['f"""git reset --hard {ORIGIN}/{branch}"""'], {'shell': '(True)'}), "(f'git reset --hard {ORIGIN}/{branch}', shell=True)\n", (2432, 2483), False, 'import subprocess\n'), ((2659, 2705), 're.findall', 're.findall', (['"""Merge pull request #(\\\\d+) """', 'log'], {}), "('Merge pull request #(\\\\d+) ', log)\n", (2669, 2705), False, 'import re\n'), ((2727, 2766), 're.findall', 're.findall', (['"""Backport PR #(\\\\d+):"""', 'log'], {}), "('Backport PR #(\\\\d+):', log)\n", (2737, 2766), False, 'import re\n'), ((2522, 2568), 'subprocess.check_output', 'subprocess.check_output', (['"""git log"""'], {'shell': '(True)'}), "('git log', shell=True)\n", (2545, 2568), False, 'import subprocess\n')]