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