mirror of
https://github.com/openssl/openssl.git
synced 2026-01-18 17:11:31 +01:00
add clang-format as a pre-commit hook
Reviewed-by: Neil Horman <nhorman@openssl.org> Reviewed-by: Saša Nedvědický <sashan@openssl.org> (Merged from https://github.com/openssl/openssl/pull/29282)
This commit is contained in:
committed by
Neil Horman
parent
d54932c9fa
commit
d6f3733f94
53
.github/workflows/style-checks.yml
vendored
53
.github/workflows/style-checks.yml
vendored
@@ -9,45 +9,22 @@ name: Coding style validation
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.number }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-style:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
path: openssl
|
||||
persist-credentials: false
|
||||
- name: check style for each commit
|
||||
working-directory: openssl
|
||||
shell: bash
|
||||
run: |
|
||||
ERRORS_FOUND=0
|
||||
git fetch origin $GITHUB_BASE_REF:$GITHUB_BASE_REF
|
||||
REFSTART=$(git rev-parse $GITHUB_BASE_REF)
|
||||
REFEND=$(git rev-parse HEAD)
|
||||
echo "Checking from $REFSTART to $REFEND"
|
||||
echo "::group::Style report for commits $REFSTART..$REFEND"
|
||||
set +e
|
||||
./util/check-format-commit.sh $REFSTART..$REFEND
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
ERRORS_FOUND=1
|
||||
fi
|
||||
set -e
|
||||
echo "::endgroup::"
|
||||
SKIP_TEST=$(gh pr view $PR_NUMBER --json labels --jq '.labels[] | select(.name == "style: waived") | .name')
|
||||
if [ -z "$SKIP_TEST" ]
|
||||
then
|
||||
exit $ERRORS_FOUND
|
||||
else
|
||||
echo "PR $PR_NUMBER is marked with style: waived, waiving style check errors"
|
||||
exit 0
|
||||
fi
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
- name: "Get changed files"
|
||||
env:
|
||||
NUMBER: ${{ github.event.pull_request.number }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
{
|
||||
echo 'CHANGED_FILES<<EOF'
|
||||
gh pr view $NUMBER --json files --jq '.files.[].path'
|
||||
echo EOF
|
||||
} >> "$GITHUB_ENV"
|
||||
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd #v3.0.1
|
||||
with:
|
||||
extra_args: "--files $CHANGED_FILES"
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
ci:
|
||||
autofix_prs: false
|
||||
repos:
|
||||
- repo: "https://github.com/codespell-project/codespell"
|
||||
rev: "v2.4.1"
|
||||
hooks:
|
||||
- id: "codespell"
|
||||
args: ["--config=.codespellrc", "."]
|
||||
pass_filenames: false
|
||||
- repo: "https://github.com/pre-commit/mirrors-clang-format"
|
||||
rev: "v21.1.6"
|
||||
hooks:
|
||||
- id: "clang-format"
|
||||
types_or: []
|
||||
files: '\.c\.in$|\.h\.in$|\.c$|\.h$'
|
||||
args: ["--style=file"]
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License 2.0 (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
# You can obtain a copy in the file LICENSE in the source distribution
|
||||
# or at https://www.openssl.org/source/license.html
|
||||
#
|
||||
# This script is a wrapper around check-format.pl.
|
||||
# It accepts the same commit revision range as 'git diff' as arguments,
|
||||
# or just a single commit id, and uses it to identify the files and line ranges
|
||||
# that were changed in that commit range, filtering check-format.pl output
|
||||
# only to lines that fall into the change ranges of the changed files.
|
||||
# examples:
|
||||
# check-format-commit.sh # check unstaged changes
|
||||
# check-format-commit.sh HEAD
|
||||
# check-format-commit.sh @~3..
|
||||
# check-format-commit.sh f5981c9629667a5a5d6
|
||||
# check-format-commit.sh f5981c9629667a5a5d6..ee0bf38e8709bf71888
|
||||
|
||||
# Allowlist of files to scan
|
||||
# Currently this is any .c or .h file (with an optional .in suffix)
|
||||
FILE_NAME_END_ALLOWLIST=("\.[ch]\(.in\)\?")
|
||||
|
||||
# Global vars
|
||||
|
||||
# TEMPDIR is used to hold any files this script creates
|
||||
# And is cleaned on EXIT with a trap function
|
||||
TEMPDIR=$(mktemp -d /tmp/checkformat.XXXXXX)
|
||||
|
||||
# TOPDIR always points to the root of the git tree we are working in
|
||||
# used to locate the check-format.pl script
|
||||
TOPDIR=$(git rev-parse --show-toplevel)
|
||||
|
||||
|
||||
# cleanup handler function, returns us to the root of the git tree
|
||||
# and erases our temp directory
|
||||
cleanup() {
|
||||
rm -rf $TEMPDIR
|
||||
cd $TOPDIR
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
# Get the list of ids of the commits we are checking,
|
||||
# or empty for unstaged changes.
|
||||
# This lets us pass in symbolic ref names like master/etc and
|
||||
# resolve them to commit ids easily
|
||||
COMMIT_RANGE="$@"
|
||||
[ -n $COMMIT_RANGE ] && COMMIT_LAST=$(git rev-parse $COMMIT_RANGE)
|
||||
|
||||
# Fail gracefully if git rev-parse doesn't produce a valid commit
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "$1 is not a valid commit range or commit id"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If the commit range is exactly one revision,
|
||||
# git rev-parse will output just the commit id of that one alone.
|
||||
# In that case, we must manipulate a little to get a desirable result,
|
||||
# as 'git diff' has a slightly different interpretation of a single commit id:
|
||||
# it takes that to mean all commits up to HEAD, plus any unstaged changes.
|
||||
if [ $(echo -n "$COMMIT_LAST" | wc -w) -ne 1 ]; then
|
||||
COMMIT_LAST=$(echo "$COMMIT_LAST" | head -1)
|
||||
else
|
||||
# $COMMIT_RANGE is just one commit, make it an actual range
|
||||
COMMIT_RANGE=$COMMIT_RANGE^..$COMMIT_RANGE
|
||||
fi
|
||||
|
||||
# Create an iterable list of files to check formatting on,
|
||||
# including the line ranges that are changed by the commits
|
||||
# It produces output of this format:
|
||||
# <file name> <change start line>, <change line count>
|
||||
git diff -U0 $COMMIT_RANGE | awk '
|
||||
BEGIN {myfile=""}
|
||||
/^\+\+\+/ { sub(/^b./,"",$2); file=$2 }
|
||||
/^@@/ { sub(/^\+/,"",$3); range=$3; printf file " " range "\n" }
|
||||
' > $TEMPDIR/ranges.txt
|
||||
|
||||
# filter in anything that matches on a filter regex
|
||||
for i in ${FILE_NAME_END_ALLOWLIST[@]}
|
||||
do
|
||||
# Note the space after the $i below. This is done because we want
|
||||
# to match on file name suffixes, but the input file is of the form
|
||||
# <commit> <file path> <range start>, <range length>
|
||||
# So we can't just match on end of line. The additional space
|
||||
# here lets us match on suffixes followed by the expected space
|
||||
# in the input file
|
||||
grep "$i " $TEMPDIR/ranges.txt >> $TEMPDIR/ranges.filter || true
|
||||
done
|
||||
|
||||
REMAINING_FILES=$(wc -l <$TEMPDIR/ranges.filter)
|
||||
if [ $REMAINING_FILES -eq 0 ]
|
||||
then
|
||||
echo "The given commit range has no C source file changes that require checking"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# unless checking the format of unstaged changes,
|
||||
# check out the files from the commit range.
|
||||
if [ -n "$COMMIT_RANGE" ]
|
||||
then
|
||||
# For each file name in ranges, we show that file at the commit range
|
||||
# we are checking, and redirect it to the same path,
|
||||
# relative to $TEMPDIR/check-format.
|
||||
# This give us the full file path to run check-format.pl on
|
||||
# with line numbers matching the ranges in the $TEMPDIR/ranges.filter file
|
||||
for j in $(awk '{print $1}' $TEMPDIR/ranges.filter | sort -u)
|
||||
do
|
||||
FDIR=$(dirname $j)
|
||||
mkdir -p $TEMPDIR/check-format/$FDIR
|
||||
git show $COMMIT_LAST:$j > $TEMPDIR/check-format/$j
|
||||
done
|
||||
fi
|
||||
|
||||
# Now for each file in $TEMPDIR/ranges.filter, run check-format.pl
|
||||
for j in $(awk '{print $1}' $TEMPDIR/ranges.filter | sort -u)
|
||||
do
|
||||
range_start=()
|
||||
range_end=()
|
||||
|
||||
# Get the ranges for this file. Create 2 arrays. range_start contains
|
||||
# the start lines for valid ranges from the commit. the range_end array
|
||||
# contains the corresponding end line. Note, since diff output gives us
|
||||
# a line count for a change, the range_end[k] entry is actually
|
||||
# range_start[k]+line count
|
||||
for k in $(grep ^$j $TEMPDIR/ranges.filter | awk '{print $2}')
|
||||
do
|
||||
RSTART=$(echo $k | awk -F',' '{print $1}')
|
||||
RLEN=$(echo $k | awk -F',' '{print $2}')
|
||||
# when the hunk is just one line, its length is implied
|
||||
if [ -z "$RLEN" ]; then RLEN=1; fi
|
||||
let REND=$RSTART+$RLEN
|
||||
range_start+=($RSTART)
|
||||
range_end+=($REND)
|
||||
done
|
||||
|
||||
# Go to our checked out tree, unless checking unstaged changes
|
||||
[ -n "$COMMIT_RANGE" ] && cd $TEMPDIR/check-format
|
||||
|
||||
# Actually run check-format.pl on the file, capturing the output
|
||||
# in a temporary file. Note the format of check-format.pl output is
|
||||
# <file path>:<line number>:<error text>:<offending line contents>
|
||||
$TOPDIR/util/check-format.pl $j > $TEMPDIR/results.txt
|
||||
|
||||
# Now we filter the check-format.pl output based on the changed lines
|
||||
# captured in the range_start/end arrays
|
||||
let maxidx=${#range_start[@]}-1
|
||||
for k in $(seq 0 1 $maxidx)
|
||||
do
|
||||
RSTART=${range_start[$k]}
|
||||
REND=${range_end[$k]}
|
||||
|
||||
# field 2 of check-format.pl output is the offending line number
|
||||
# Check here if any line in that output falls between any of the
|
||||
# start/end ranges defined in the range_start/range_end array.
|
||||
# If it does fall in that range, print the entire line to stdout
|
||||
awk -v rstart=$RSTART -v rend=$REND -F':' '
|
||||
/:/ { if (rstart <= $2 && $2 <= rend) print $0 }
|
||||
' $TEMPDIR/results.txt >>$TEMPDIR/results-filtered.txt
|
||||
done
|
||||
done
|
||||
cat $TEMPDIR/results-filtered.txt
|
||||
|
||||
# If any findings were in range, exit with a different error code
|
||||
if [ -s $TEMPDIR/results-filtered.txt ]
|
||||
then
|
||||
exit 2
|
||||
fi
|
||||
1282
util/check-format.pl
1282
util/check-format.pl
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user