1*0119c894STomeu Vizoso#!/usr/bin/env python3 2*0119c894STomeu Vizoso# SPDX-License-Identifier: GPL-2.0-or-later 3*0119c894STomeu Vizoso# 4*0119c894STomeu Vizoso# check-patch.py: run checkpatch.pl across all commits in a branch 5*0119c894STomeu Vizoso# 6*0119c894STomeu Vizoso# Based on qemu/.gitlab-ci.d/check-patch.py 7*0119c894STomeu Vizoso# 8*0119c894STomeu Vizoso# Copyright (C) 2020 Red Hat, Inc. 9*0119c894STomeu Vizoso# Copyright (C) 2022 Collabora Ltd. 10*0119c894STomeu Vizoso 11*0119c894STomeu Vizosoimport os 12*0119c894STomeu Vizosoimport os.path 13*0119c894STomeu Vizosoimport sys 14*0119c894STomeu Vizosoimport subprocess 15*0119c894STomeu Vizoso 16*0119c894STomeu Vizosorepourl = "https://gitlab.freedesktop.org/%s.git" % os.environ["CI_MERGE_REQUEST_PROJECT_PATH"] 17*0119c894STomeu Vizoso 18*0119c894STomeu Vizoso# GitLab CI environment does not give us any direct info about the 19*0119c894STomeu Vizoso# base for the user's branch. We thus need to figure out a common 20*0119c894STomeu Vizoso# ancestor between the user's branch and current git master. 21*0119c894STomeu Vizosoos.environ["GIT_DEPTH"] = "1000" 22*0119c894STomeu Vizososubprocess.call(["git", "remote", "remove", "check-patch"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 23*0119c894STomeu Vizososubprocess.check_call(["git", "remote", "add", "check-patch", repourl]) 24*0119c894STomeu Vizososubprocess.check_call(["git", "fetch", "check-patch", os.environ["CI_MERGE_REQUEST_TARGET_BRANCH_NAME"]], 25*0119c894STomeu Vizoso stdout=subprocess.DEVNULL, 26*0119c894STomeu Vizoso stderr=subprocess.DEVNULL) 27*0119c894STomeu Vizoso 28*0119c894STomeu Vizosoancestor = subprocess.check_output(["git", "merge-base", 29*0119c894STomeu Vizoso "check-patch/%s" % os.environ["CI_MERGE_REQUEST_TARGET_BRANCH_NAME"], "HEAD"], 30*0119c894STomeu Vizoso universal_newlines=True) 31*0119c894STomeu Vizoso 32*0119c894STomeu Vizosoancestor = ancestor.strip() 33*0119c894STomeu Vizoso 34*0119c894STomeu Vizosolog = subprocess.check_output(["git", "log", "--format=%H %s", 35*0119c894STomeu Vizoso ancestor + "..."], 36*0119c894STomeu Vizoso universal_newlines=True) 37*0119c894STomeu Vizoso 38*0119c894STomeu Vizososubprocess.check_call(["git", "remote", "rm", "check-patch"]) 39*0119c894STomeu Vizoso 40*0119c894STomeu Vizosoif log == "": 41*0119c894STomeu Vizoso print("\nNo commits since %s, skipping checks\n" % ancestor) 42*0119c894STomeu Vizoso sys.exit(0) 43*0119c894STomeu Vizoso 44*0119c894STomeu Vizosoerrors = False 45*0119c894STomeu Vizoso 46*0119c894STomeu Vizosoprint("\nChecking all commits since %s...\n" % ancestor, flush=True) 47*0119c894STomeu Vizoso 48*0119c894STomeu Vizosoret = subprocess.run(["scripts/checkpatch.pl", 49*0119c894STomeu Vizoso "--terse", 50*0119c894STomeu Vizoso "--types", os.environ["CHECKPATCH_TYPES"], 51*0119c894STomeu Vizoso "--git", ancestor + "..."]) 52*0119c894STomeu Vizoso 53*0119c894STomeu Vizosoif ret.returncode != 0: 54*0119c894STomeu Vizoso print(" ❌ FAIL one or more commits failed scripts/checkpatch.pl") 55*0119c894STomeu Vizoso sys.exit(1) 56*0119c894STomeu Vizoso 57*0119c894STomeu Vizososys.exit(0) 58