From patchwork Thu Jan 16 18:26:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Dufresne X-Patchwork-Id: 2652 Return-Path: Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 46E1260705 for ; Thu, 16 Jan 2020 19:26:31 +0100 (CET) Received: from nicolas-tpx395.localdomain (unknown [IPv6:2610:98:8005::127]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: nicolas) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id C7048294522; Thu, 16 Jan 2020 18:26:30 +0000 (GMT) From: nicolas@ndufresne.ca To: libcamera-devel@lists.libcamera.org Cc: Nicolas Dufresne Date: Thu, 16 Jan 2020 13:26:03 -0500 Message-Id: <20200116182603.108966-3-nicolas@ndufresne.ca> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200116182603.108966-1-nicolas@ndufresne.ca> References: <20200116182603.108966-1-nicolas@ndufresne.ca> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/2] checkstyle: Add support for pre-commit hook X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Jan 2020 18:26:31 -0000 From: Nicolas Dufresne This adds support for pre-commit hook workflow. In pre-commit hook we check the style on the changes currently staged. Note that this patch also includes a bit of sugar to support --amend. Signed-off-by: Nicolas Dufresne --- utils/checkstyle.py | 55 +++++++++++++++++++++++++++++------------- utils/hooks/pre-commit | 16 ++++++++++++ 2 files changed, 54 insertions(+), 17 deletions(-) mode change 100644 => 100755 utils/checkstyle.py create mode 100755 utils/hooks/pre-commit diff --git a/utils/checkstyle.py b/utils/checkstyle.py old mode 100644 new mode 100755 index 7edea25..23eb3f6 --- a/utils/checkstyle.py +++ b/utils/checkstyle.py @@ -458,11 +458,16 @@ class StripTrailingSpaceFormatter(Formatter): # Style checking # -def check_file(top_level, commit, filename): +def check_file(top_level, commit, filename, staged): # Extract the line numbers touched by the commit. - diff = subprocess.run(['git', 'diff', '%s~..%s' % (commit, commit), '--', - '%s/%s' % (top_level, filename)], - stdout=subprocess.PIPE).stdout + if staged: + diff = subprocess.run(['git', 'diff', '--staged', commit, '--', + '%s/%s' % (top_level, filename)], + stdout=subprocess.PIPE).stdout + else: + diff = subprocess.run(['git', 'diff', '%s~..%s' % (commit, commit), '--', + '%s/%s' % (top_level, filename)], + stdout=subprocess.PIPE).stdout diff = diff.decode('utf-8').splitlines(True) commit_diff = parse_diff(diff) @@ -476,8 +481,12 @@ def check_file(top_level, commit, filename): # Format the file after the commit with all formatters and compute the diff # between the unformatted and formatted contents. - after = subprocess.run(['git', 'show', '%s:%s' % (commit, filename)], - stdout=subprocess.PIPE).stdout + if staged: + after = subprocess.run(['git', 'show', ':%s' % (filename)], + stdout=subprocess.PIPE).stdout + else: + after = subprocess.run(['git', 'show', '%s:%s' % (commit, filename)], + stdout=subprocess.PIPE).stdout after = after.decode('utf-8') formatted = after @@ -521,13 +530,20 @@ def check_file(top_level, commit, filename): return len(formatted_diff) + len(issues) -def check_style(top_level, commit): - # Get the commit title and list of files. - ret = subprocess.run(['git', 'show', '--pretty=oneline','--name-only', commit], - stdout=subprocess.PIPE) - files = ret.stdout.decode('utf-8').splitlines() - title = files[0] - files = files[1:] +def check_style(top_level, commit, staged): + if staged: + # Get list of staged changed files + ret = subprocess.run(['git', 'diff', '--staged', '--name-only', commit], + stdout=subprocess.PIPE) + files = ret.stdout.decode('utf-8').splitlines() + title = "Pre-commit" + else: + # Get the commit title and list of files. + ret = subprocess.run(['git', 'show', '--pretty=oneline', '--name-only', commit], + stdout=subprocess.PIPE) + files = ret.stdout.decode('utf-8').splitlines() + title = files[0] + files = files[1:] separator = '-' * len(title) print(separator) @@ -541,11 +557,11 @@ def check_style(top_level, commit): files = [f for f in files if len([p for p in patterns if fnmatch.fnmatch(os.path.basename(f), p)])] if len(files) == 0: print("Commit doesn't touch source files, skipping") - return + return 0 issues = 0 for f in files: - issues += check_file(top_level, commit, f) + issues += check_file(top_level, commit, f, staged) if issues == 0: print("No style issue detected") @@ -554,6 +570,8 @@ def check_style(top_level, commit): print("%u potential style %s detected, please review" % \ (issues, 'issue' if issues == 1 else 'issues')) + return issues + def extract_revlist(revs): """Extract a list of commits on which to operate from a revision or revision @@ -595,6 +613,8 @@ def main(argv): parser = argparse.ArgumentParser() parser.add_argument('--formatter', '-f', type=str, choices=['astyle', 'clang-format'], help='Code formatter. Default to clang-format if not specified.') + parser.add_argument('--staged', '-s', action='store_true', + help='Looks at the staged changes, used for pre-commit, defaults to False') parser.add_argument('revision_range', type=str, default='HEAD', nargs='?', help='Revision range (as defined by git rev-parse). Defaults to HEAD if not specified.') args = parser.parse_args(argv[1:]) @@ -632,11 +652,12 @@ def main(argv): revlist = extract_revlist(args.revision_range) + issues = 0 for commit in revlist: - check_style(top_level, commit) + issues += check_style(top_level, commit, args.staged) print('') - return 0 + return issues if __name__ == '__main__': diff --git a/utils/hooks/pre-commit b/utils/hooks/pre-commit new file mode 100755 index 0000000..57d23ef --- /dev/null +++ b/utils/hooks/pre-commit @@ -0,0 +1,16 @@ +#!/bin/sh + +# Execute the checkstyle script before committing any code, failing the commit +# if needed. With this workflow, false positive can be ignored using: +# git commit -n +# +# To utilise this hook, install this file with: +# cp utils/hooks/pre-commit .git/hooks/pre-commit + +commit= +if ps -ocommand= -p $PPID | grep -- "--amend" +then + commit="HEAD~" +fi + +./utils/checkstyle.py --staged $commit