5 DIRECTORIES_TO_BE_TESTED=()
6 DIRECTORIES_NOT_TO_BE_TESTED=()
7 CLANG_FORMAT_CANDIDATES=()
8 PATCH_FILE=format.patch
14 echo "Usage: $0 $(basename ${BASH_SOURCE[0]}) [OPTIONS] [<file|dir> ...]"
15 echo "If no arguments are specified, it formats all nnas codes"
16 echo "If <file>s are given, it reformats the files"
19 echo " --clang-format <TOOL> clang format bin (default: clang-format-3.9, clang-format)"
20 echo " --diff-only check diff files with master"
21 echo " --staged-only check git staged files"
33 CLANG_FORMAT_CANDIDATES=($2)
37 CLANG_FORMAT_CANDIDATES=(${1#*=})
50 DIRECTORIES_TO_BE_TESTED+=($1)
57 command pushd "$@" > /dev/null
61 command popd "$@" > /dev/null
64 function command_exists() {
65 command -v $1 > /dev/null 2>&1
68 function exclude_symbolic_links() {
69 # Check all files (CMakeLists.txt, *.cl, ... not only for C++, Python)
70 if [[ ${#FILES_TO_CHECK} -ne 0 ]]; then
71 FILES_EXCLUDE_SYMLINKS=$(file ${FILES_TO_CHECK} | grep -v "symbolic link" | cut -d':' -f1)
72 FILES_TO_CHECK=${FILES_EXCLUDE_SYMLINKS}
76 function check_newline() {
78 for f in ${FILES_TO_CHECK[@]}; do
79 # Manually ignore style checking
80 if [[ ${f} == !(*.svg|*.pdf|*.png) ]]; then
81 FILES_TO_CHECK_CR+=("${f}")
85 # Check all files (CMakeLists.txt, *.cl, ... not only for C++, Python)
86 if [[ ${#FILES_TO_CHECK_CR} -ne 0 ]]; then
87 CRCHECK=$(file ${FILES_TO_CHECK_CR} | grep 'with CR')
91 FILES_TO_FIX=($(echo "$CRCHECK" | grep "with CRLF line" | cut -d':' -f1))
92 for f in ${FILES_TO_FIX[@]}; do
93 tr -d '\r' < $f > $f.fixed && cat $f.fixed > $f && rm $f.fixed
95 FILES_TO_FIX=($(echo "${CRCHECK}" | grep "with CR line" | cut -d':' -f1))
96 for f in ${FILES_TO_FIX[@]}; do
97 tr '\r' '\n' < $f > $f.fixed && cat $f.fixed > $f && rm $f.fixed
99 # Check no new line at end of file
100 for f in ${FILES_TO_CHECK_CR[@]}; do
101 if diff /dev/null "$f" | tail -1 | grep '^\\ No newline' > /dev/null; then
107 function check_permission() {
108 # Check all files except script
109 FILES_TO_CHECK_PERMISSION=()
110 for f in ${FILES_TO_CHECK[@]}; do
111 # Manually ignore permission checking
112 if [[ ${f} == !(nnas|nnfw|nncc|*.sh|*.py|*/gradlew) ]] || [[ ${f} == tests/nnapi/specs/**/*.py ]]; then
113 FILES_TO_CHECK_PERMISSION+=("${f}")
117 if [[ ${#FILES_TO_CHECK_PERMISSION} -eq 0 ]]; then
120 for FILE_TO_CHECK in ${FILES_TO_CHECK_PERMISSION[@]}; do
121 RESULT=$(stat -c '%A' ${FILE_TO_CHECK} | grep 'x')
122 if [ "${RESULT}" != "" ]; then
123 chmod a-x ${FILE_TO_CHECK}
128 function check_cpp_files() {
129 if [[ ${__Check_CPP} -eq 0 ]]; then
130 echo "[SKIPPED] C/C++ check is skipped"
134 CLANG_FORMAT_CANDIDATES+=("clang-format-3.9")
135 CLANG_FORMAT_CANDIDATES+=("clang-format")
137 for CLANG_FORMAT_CANDIDATE in ${CLANG_FORMAT_CANDIDATES[@]}; do
138 if command_exists ${CLANG_FORMAT_CANDIDATE} ; then
139 CLANG_FORMAT="${CLANG_FORMAT_CANDIDATE}"
144 if [[ -z ${CLANG_FORMAT} ]]; then
145 echo "[ERROR] clang-format is unavailable"
147 echo "Please install clang-format before running format check"
152 FILES_TO_CHECK_CPP=()
153 for f in ${FILES_TO_CHECK[@]}; do
154 # Manually ignore style checking
155 if [[ ${f} == +(*/NeuralNetworks.h|*/NeuralNetworksExtensions.h) ]]; then
159 # File extension to check
160 if [[ ${f} == +(*.h|*.hpp|*.cpp|*.cc|*.c|*.cl) ]]; then
161 FILES_TO_CHECK_CPP+=("${f}")
165 # Skip by '.FORMATDENY' file
166 for s in ${DIRECTORIES_NOT_TO_BE_TESTED[@]}; do
167 FILES_TO_CHECK_CPP=(${FILES_TO_CHECK_CPP[*]/$s*/})
170 if [[ ${#FILES_TO_CHECK_CPP} -ne 0 ]]; then
171 ${CLANG_FORMAT} -i ${FILES_TO_CHECK_CPP[@]}
173 if [[ ${EXIT_CODE} -ne 0 ]]; then
174 INVALID_EXIT=${EXIT_CODE}
179 function check_python_files() {
180 if [[ ${__Check_PYTHON} -eq 0 ]]; then
181 echo "[SKIPPED] Python check is skipped"
185 if ! command_exists yapf; then
186 echo "[ERROR] yapf is unavailable"
187 echo " Please install yapf."
192 FILES_TO_CHECK_PYTHON=()
193 for f in ${FILES_TO_CHECK[@]}; do
194 # File extension to check
195 if [[ ${f} == *.py ]]; then
196 FILES_TO_CHECK_PYTHON+=("${f}")
199 for s in ${DIRECTORIES_NOT_TO_BE_TESTED[@]}; do
201 FILES_TO_CHECK_PYTHON=(${FILES_TO_CHECK_PYTHON[*]/$skip*/})
204 if [[ ${#FILES_TO_CHECK_PYTHON} -ne 0 ]]; then
205 yapf -i --style='{based_on_style: pep8, column_limit: 90}' ${FILES_TO_CHECK_PYTHON[@]}
207 if [[ ${EXIT_CODE} -ne 0 ]]; then
208 INVALID_EXIT=${EXIT_CODE}
213 pushd ${NNAS_PROJECT_PATH}
215 if [[ -n "$(git diff)" ]] && { [[ "${CHECK_DIFF_ONLY}" != "1" ]] || [[ "${CHECK_STAGED_ONLY}" != "1" ]]; }; then
216 echo "[WARNING] Commit all the changes before running format check"
217 echo " ${PATCH_FILE} file will contain unstaged files"
220 __Check_CPP=${CHECK_CPP:-"1"}
221 __Check_PYTHON=${CHECK_PYTHON:-"1"}
223 FILES_TO_CHECK=$(git ls-files -c --exclude-standard ${DIRECTORIES_TO_BE_TESTED[@]})
224 if [[ "${CHECK_DIFF_ONLY}" = "1" ]]; then
225 MASTER_EXIST=$(git rev-parse --verify master)
226 CURRENT_BRANCH=$(git branch | grep \* | cut -d ' ' -f2-)
227 DIFF_COMMITS=`git log --graph --oneline master..HEAD | wc -l`
228 if [[ -z "${MASTER_EXIST}" ]]; then
229 echo "Cannot found local master branch"
230 elif [[ "${CURRENT_BRANCH}" = "master" ]]; then
231 echo "Current branch is master"
233 if [[ "${CHECK_STAGED_ONLY}" = "1" ]]; then
234 FILES_TO_CHECK=$(git diff --staged --name-only --diff-filter=d)
236 FILES_TO_CHECK=$(git diff --name-only --diff-filter=d HEAD~${DIFF_COMMITS})
241 for DIR_NOT_TO_BE_TESTED in $(git ls-files -co --exclude-standard '*/.FORMATDENY'); do
242 DIRECTORIES_NOT_TO_BE_TESTED+=($(dirname "${DIR_NOT_TO_BE_TESTED}"))
245 exclude_symbolic_links
251 if [[ "${CHECK_DIFF_ONLY}" = "1" ]] && [[ "${CHECK_STAGED_ONLY}" = "1" ]]; then
252 if [[ ! -z "${FILES_TO_CHECK}" ]]; then
253 DIFF=$(git diff ${FILES_TO_CHECK} | tee ${PATCH_FILE})
256 DIFF=$(git diff | tee ${PATCH_FILE})
261 if [[ -z "${CRCHECK}" ]] && [[ ! -n "${DIFF}" ]] && [[ ${INVALID_EXIT} -eq 0 ]]; then
262 echo "[PASSED] Format checker succeed."
266 # Something went wrong
268 if [[ ! -z "${CRCHECK}" ]]; then
269 echo "[FAILED] Please use LF for newline for following files."
273 if [[ -s ${PATCH_FILE} ]]; then
274 echo "[FAILED] Format checker failed and update code to follow convention."
275 echo " You can find changes in ${PATCH_FILE}"
278 if [[ ${INVALID_EXIT} -ne 0 ]]; then
279 echo "[[FAILED] Invalid format checker exit."