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