#!/usr/bin/env python3
"""
Small wrapper script for jenkins to see if a regex pattern matches any of the
paths generated by diffing between two commits.
"""
import argparse
import os
import re
import subprocess
import sys

debug = "DEBUG" in os.environ


def check_paths_for_matches(pattern, git_commit, git_previous_commit):
    """Check if any paths between GIT_PREVIOUS_COMMIT and GIT_COMMIT match our pattern.

    For merge commits only actual path changes are included rather than changes
    from all parents. If GIT_PREVIOUS_COMMIT is not populated, use just the
    paths that GIT_COMMIT represents. If GIT_PREVIOUS_COMMIT is not populated
    and GIT_COMMIT is a merge commit, use all path changes from each parent. If
    GIT_PREVIOUS_COMMIT is the same as GIT_COMMIT, that should generate no path
    changes.
    """
    # Handle case where GIT_PREVIOUS_COMMIT isn't set (e.g. the first build),
    if not git_previous_commit:
        command = [
            "git",
            "diff-tree",
            "-m",
            "--no-commit-id",
            "--name-only",
            "-r",
            git_commit,
        ]
    else:
        command = ["git", "diff", "--name-only", git_previous_commit, git_commit]

    # Run the command and populate paths.
    completed_process = subprocess.run(
        command, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
    )
    paths = completed_process.stdout.decode().strip().split("\n")

    # Look for any matches of pattern -> path.
    possible_matches = [(path, pattern.match(path)) for path in paths]
    if any([match for path, match in possible_matches]):
        if debug:
            print("matching change(s) found for {}".format(git_commit))
            for path, match in possible_matches:
                if match:
                    print(path)
        sys.stdout.write("match")
        sys.stdout.flush()
        exit(0)
    else:
        if debug:
            print("no matching change(s) found for {}".format(git_commit))
        exit(1)


if __name__ == "__main__":
    # Change our working directory so we're in $WORKSPACE.
    os.chdir(os.path.dirname(os.path.abspath(__file__)))

    # Define and parse arguments.
    parser = argparse.ArgumentParser()
    parser.add_argument("--pattern", help="A regular expression pattern.")
    parser.add_argument(
        "--git-commit", help="The contents of the GIT_COMMIT environmental variable."
    )
    parser.add_argument(
        "--git-previous-commit",
        nargs="?",
        help="The contents of the GIT_PREVIOUS_COMMIT environmental variable.",
    )
    args = parser.parse_args()

    compiled_pattern = re.compile(args.pattern)
    check_paths_for_matches(compiled_pattern, args.git_commit, args.git_previous_commit)
