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