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
13WORKSPACE=$PWD
14WORKSPACE_CONFIG="${WORKSPACE}/openbmc-build-scripts/config"
15
16set -e
17
18echo "Running spelling check on Commit Message"
19
20# Run the codespell with openbmc spcific spellings on the patchset
21echo "openbmc-dictionary - misspelling count >> "
22sed "s/Signed-off-by.*//" "${DIR}/.git/COMMIT_EDITMSG" | \
23    codespell -D "${WORKSPACE_CONFIG}/openbmc-spelling.txt" -d --count -
24
25# Run the codespell with generic dictionary on the patchset
26echo "generic-dictionary - misspelling count >> "
27sed "s/Signed-off-by.*//" "${DIR}/.git/COMMIT_EDITMSG" | \
28    codespell --builtin clear,rare,en-GB_to_en-US -d --count -
29
30# Check for commit message issues
31gitlint \
32  --target "${DIR}" \
33  --extra-path "${WORKSPACE_CONFIG}/gitlint/" \
34  --config "${WORKSPACE_CONFIG}/.gitlint"
35
36cd "${DIR}"
37
38echo "Formatting code under $DIR/"
39
40if [[ -f ".eslintignore" ]]; then
41  ESLINT_IGNORE="--ignore-path .eslintignore"
42elif [[ -f ".gitignore" ]]; then
43  ESLINT_IGNORE="--ignore-path .gitignore"
44fi
45
46# Get the eslint configuration from the repository
47if [[ -f ".eslintrc.json" ]]; then
48    echo "Running the json validator on the repo using it's config > "
49    ESLINT_RC="-c .eslintrc.json"
50else
51    echo "Running the json validator on the repo using the global config"
52    ESLINT_RC="--no-eslintrc -c ${WORKSPACE_CONFIG}/eslint-global-config.json"
53fi
54
55ESLINT_COMMAND="eslint . ${ESLINT_IGNORE} ${ESLINT_RC} \
56               --ext .json --format=stylish \
57               --resolve-plugins-relative-to /usr/local/lib/node_modules \
58               --no-error-on-unmatched-pattern"
59
60# Print eslint command
61echo "$ESLINT_COMMAND"
62# Run eslint
63$ESLINT_COMMAND
64
65if [[ -f "setup.cfg" ]]; then
66  pycodestyle --show-source --exclude=subprojects .
67  rc=$?
68  if [[ ${rc} -ne 0 ]]; then
69    exit ${rc}
70  fi
71fi
72
73# If .shellcheck exists, stop on error.  Otherwise, allow pass.
74if [[ -f ".shellcheck" ]]; then
75  shellcheck_allowfail="false"
76else
77  shellcheck_allowfail="true"
78fi
79
80# Run shellcheck on any shell-script.
81shell_scripts="$(git ls-files | xargs -n1 file -0 | \
82                 grep -a "shell script" | cut -d '' -f 1)"
83for script in ${shell_scripts}; do
84  shellcheck --color=never -x "${script}" || ${shellcheck_allowfail}
85done
86
87# Allow called scripts to know which clang format we are using
88export CLANG_FORMAT="clang-format"
89IGNORE_FILE=".clang-ignore"
90declare -a IGNORE_LIST
91
92if [[ -f "${IGNORE_FILE}" ]]; then
93  readarray -t IGNORE_LIST < "${IGNORE_FILE}"
94fi
95
96ignorepaths=""
97ignorefiles=""
98
99for path in "${IGNORE_LIST[@]}"; do
100  # Check for comment, line starting with space, or zero-length string.
101  # Checking for [[:space:]] checks all options.
102  if [[ -z "${path}" ]] || [[ "${path}" =~ ^(#|[[:space:]]).*$ ]]; then
103    continue
104  fi
105
106  # All paths must start with ./ for find's path prune expectation.
107  if [[ "${path}" =~ ^\.\/.+$ ]]; then
108    ignorepaths+=" ${path}"
109  else
110    ignorefiles+=" ${path}"
111  fi
112done
113
114searchfiles=""
115while read -r path; do
116  # skip ignorefiles
117  if [[ $ignorefiles == *"$(basename "${path}")"* ]]; then
118    continue
119  fi
120
121  skip=false
122  #skip paths in ingorepaths
123  for pathname in $ignorepaths; do
124    if [[ "./${path}" == "${pathname}"* ]]; then
125       skip=true
126       break
127    fi
128  done
129
130  if [ "$skip" = true ]; then
131   continue
132  fi
133  # shellcheck disable=2089
134  searchfiles+="\"./${path}\" "
135
136# Get C and C++ files managed by git and skip the mako files
137done <<<"$(git ls-files | grep -e '\.[ch]pp$' -e '\.[ch]$' | grep -v '\.mako\.')"
138
139if [[ -f ".clang-format" ]]; then
140  # shellcheck disable=SC2090 disable=SC2086
141  echo ${searchfiles} | xargs "${CLANG_FORMAT}" -i
142  git --no-pager diff --exit-code
143fi
144
145# Sometimes your situation is terrible enough that you need the flexibility.
146# For example, phosphor-mboxd.
147if [[ -f "format-code.sh" ]]; then
148  ./format-code.sh
149  git --no-pager diff --exit-code
150fi
151