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