xref: /openbmc/openbmc-build-scripts/scripts/format-code.sh (revision 01ced284a3f1a139220c21898b05c4c933369420)
1#!/bin/bash
2
3# This script reformats source files using the clang-format utility.
4#
5# Files are changed in-place, so make sure you don't have anything open in an
6# editor, and you may want to commit before formatting in case of awryness.
7#
8# This must be run on a clean repository to succeed
9#
10# Input parmameter must be full path to git repo to scan
11
12DIR=$1
13cd ${DIR}
14
15set -e
16
17echo "Formatting code under $DIR/"
18
19if [[ -f "setup.cfg" ]]; then
20  pycodestyle --show-source .
21  rc=$?
22  if [[ ${rc} -ne 0 ]]; then
23    exit ${rc}
24  fi
25fi
26
27# If .shellcheck exists, stop on error.  Otherwise, allow pass.
28if [[ -f ".shellcheck" ]]; then
29  shellcheck_allowfail="false"
30else
31  shellcheck_allowfail="true"
32fi
33
34# Run shellcheck on any shell-script.
35shell_scripts="$(git ls-files | xargs -n1 file -0 | \
36                 grep -a "shell script" | cut -d '' -f 1)"
37for script in ${shell_scripts}; do
38  shellcheck -x "${script}" || ${shellcheck_allowfail}
39done
40
41# Allow called scripts to know which clang format we are using
42export CLANG_FORMAT="clang-format-10"
43IGNORE_FILE=".clang-ignore"
44declare -a IGNORE_LIST
45
46if [[ -f "${IGNORE_FILE}" ]]; then
47  readarray -t IGNORE_LIST < "${IGNORE_FILE}"
48fi
49
50ignorepaths=""
51ignorefiles=""
52
53for path in "${IGNORE_LIST[@]}"; do
54  # Check for comment, line starting with space, or zero-length string.
55  # Checking for [[:space:]] checks all options.
56  if [[ -z "${path}" ]] || [[ "${path}" =~ ^(#|[[:space:]]).*$ ]]; then
57    continue
58  fi
59
60  # All paths must start with ./ for find's path prune expectation.
61  if [[ "${path}" =~ ^\.\/.+$ ]]; then
62    ignorepaths+=" ${path}"
63  else
64    ignorefiles+=" ${path}"
65  fi
66done
67
68searchfiles=""
69while read path; do
70  # skip ignorefiles
71  if [[ $ignorefiles == *"$(basename "${path}")"* ]]; then
72    continue
73  fi
74
75  skip=false
76  #skip paths in ingorepaths
77  for pathname in $ignorepaths; do
78    if [[ "./${path}" == "${pathname}"* ]]; then
79       skip=true
80       break
81    fi
82  done
83
84  if [ "$skip" = true ]; then
85   continue
86  fi
87  searchfiles+="\"./${path}\" "
88
89# Get C and C++ files managed by git and skip the mako files
90done <<<$(git ls-files | grep -e '\.[ch]pp$' -e '\.[ch]$' | grep -v '\.mako\.')
91
92if [[ -f ".clang-format" ]]; then
93  echo ${searchfiles} | xargs "${CLANG_FORMAT}" -i
94  git --no-pager diff --exit-code
95fi
96
97# Sometimes your situation is terrible enough that you need the flexibility.
98# For example, phosphor-mboxd.
99if [[ -f "format-code.sh" ]]; then
100  ./format-code.sh
101  git --no-pager diff --exit-code
102fi
103