Skip to content

Commit

Permalink
Add tools to lint the code
Browse files Browse the repository at this point in the history
  • Loading branch information
aajain-com committed Jan 14, 2020
1 parent eaf788d commit 5568824
Show file tree
Hide file tree
Showing 5 changed files with 298 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ IndentPPDirectives: None
IndentWidth: 4
TabWidth: 4
UseTab: Never
TypenameMacros:
- HAP_ENUM_BEGIN
- HAP_ENUM_END

AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveMacros: true
Expand Down
12 changes: 12 additions & 0 deletions Documentation/developing_with_adk.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
## Code Style
Please use the following tools to auto-format your code before submitting a Pull Request.

## Linting source code
This project uses `clang-format` tool to lint and format the code.
```
./Tools/linters/clint.sh -h
```

## Linting shell scripts
```
./Tools/linters/shlint.sh
```

## Guidelines
#### Sample Application
Expand Down
89 changes: 89 additions & 0 deletions Tools/download.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
########################################################################################################################
# This is a helper function to download a file from a given URL
#
# Globals:
# None
# Arguments:
# $1: file
# $2: url
# $3: SHA-256 hash (Optional)
# Returns:
# None
########################################################################################################################
download() {
if [ "$#" -lt 2 ]; then
echo "Usage: $0 <file_path> <url> <sha>"
exit 1
fi

# Install uuidgen if not installed already
# uuidgen is pre-installed on OSX
if [[ "$(uname)" == "Linux" ]]; then
if ! uuidgen --version > /dev/null 2>&1; then
apt-get update
apt-get install uuid-runtime
fi
fi

DIR=$(dirname "$1")
mkdir -p "${DIR}"
local FILE="$1"
(
local lockFile="${FILE}.lock"
local uuid
uuid="$(uuidgen)"
trap '[ "$(cat "'"${lockFile}"'")" == "'"${uuid}"'" ] && rm -f "'"${lockFile}"'"' ERR EXIT
while ! ( set -C; echo "${uuid}" > "${lockFile}" ) 2>/dev/null; do echo -n "." && sleep 0.5; done

if [[ -f "${FILE}" && -n $3 ]]; then
(echo "$3 *${FILE}" | shasum -a 256 -cw) || rm "${FILE}"
fi
if [ ! -f "${FILE}" ]; then
# URL encode: http://stackoverflow.com/a/7506695
local url=$2

# Download & check hash.
# This is known to abort with `curl: (56) LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 54`
# when multiple downloads are started in quick succession. Therefore, retry loop.
local retryBackoff=0
local i=0
while :; do
if (( ++i > 10 )); then
echo "${1} download failed too often."
false
fi
if (( !retryBackoff )); then
retryBackoff=1
else
echo "Retrying ${1} download in ${retryBackoff}s."
sleep "${retryBackoff}"
retryBackoff=$(( retryBackoff * 2 ))
maximumBackoff=1800
if (( retryBackoff >= maximumBackoff )); then
retryBackoff=${maximumBackoff}
fi
fi

if command -v curl > /dev/null; then
local command=(
"curl" "-L" "${url}" "-o" "${FILE}")
if command -v caffeinate >/dev/null; then
caffeinate -ims "${command[@]}" || continue
else
"${command[@]}" || continue
fi
elif command -v wget > /dev/null; then
wget -O "${FILE}" "${url}" || continue
else
echo -e "\x1B[31m/!\ No download tool installed. Please install curl or wget.\x1B[0m"
false
fi
break
done

if [[ -n "$3" ]]; then
echo "$3 *${FILE}" | shasum -a 256 -cw
fi
fi
)
}
145 changes: 145 additions & 0 deletions Tools/linters/clint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#!/bin/bash -e

ADK_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../../"

# shellcheck source=Tools/
source "$ADK_ROOT/Tools/download.sh"

usage()
{
echo "A tool to check and fix code style"
echo ""
echo "Usage: $0 [options]"
echo ""
echo "OPTIONS:"
echo "-f - Lint the provided file. If no option is provided all files will be linted."
echo "-d - Lint the files in the specified directory."
echo "-c - Correct the style issues in the specified files or directories."
echo ""
echo "EXAMPLES: "
echo "$0 -f <file_name> # Lint the specified file"
echo "$0 -f <file_name> -c # Lint and fix the specified file"
echo "$0 -d <dir_name> # Lint files in the specified directory"
echo "$0 -d <dir_name> -c # Lint and fix all files in the specified directory"
echo "$0 # Lint all files in this repository"
echo "$0 -c # Fix all files in this repository"
exit 1
}

CLANG_FORMAT=clang-format
CORRECT=false
SEARCH_PATH=$ADK_ROOT

while getopts "hcf:d:" opt; do
case ${opt} in
f ) FILE=$OPTARG
;;
d ) SEARCH_PATH="$ADK_ROOT/$OPTARG"
;;
c ) CORRECT=true
;;
h ) usage
;;
\? ) usage
;;
esac
done

# Install clang-format
CLANG_FORMAT_VERSION="9.0.0"
if ! "$CLANG_FORMAT" --version | grep -q $CLANG_FORMAT_VERSION; then
echo "clang-format not installed or the version is incorrect. Installing..."

CLANG_BIN_FILE=
DEST=
case "$(uname)" in
"Darwin")
CLANG_BIN_FILE="clang+llvm-9.0.0-x86_64-darwin-apple"
DEST="/usr/local/bin"
;;
"Linux")
CLANG_BIN_FILE="clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-18.04"
DEST="/usr/bin"
;;
*)
echo "Unsupported system"
exit 1
;;
esac

download "$CLANG_BIN_FILE.tar.xz" http://releases.llvm.org/9.0.0/"$CLANG_BIN_FILE.tar.xz" \
&& tar --xz -xvf "$CLANG_BIN_FILE.tar.xz" \
&& cp -f "$CLANG_BIN_FILE/bin/clang-format" "$DEST/clang-format" \
&& rm -rf "$CLANG_BIN_FILE" "$CLANG_BIN_FILE.tar.xz"
fi

FILES=()
if [[ -n "$FILE" ]]; then
if [[ ! -f "$FILE" ]]; then
echo "Invalid file $FILE"
exit 1
fi
FILES=("$FILE")
else
echo "Looking for files in $SEARCH_PATH directory..."
while IFS= read -r -d $'\0'; do
FILES+=("$REPLY")
done < <(find "$SEARCH_PATH" \
\( \
-name "*.h" \
-o -name "*.c" \
-o -name "*.cpp" \
-o -name "*.hpp" \
-o -name "*.cc" \
-o -name "*.hh" \
-o -name "*.cxx" \
-o -name "*.m" \
-o -name "*.mm" \
\) \
-not -path "*Output*" \
! -type l \
-print0
)
fi

if [[ ${#FILES[@]} -eq 0 ]]; then
echo "No files available to lint"
usage
fi

# Create a random filename to store our generated patch
prefix="static-check-clang-format"
suffix="$(date +%s)"
PATCH="/tmp/$prefix-$suffix.patch"

for file in "${FILES[@]}"; do
if $CORRECT; then
echo "Fixing file: $file"
"$CLANG_FORMAT" -style=file "$file" -i
else
echo "Checking file: $file"
"$CLANG_FORMAT" -style=file "$file" | \
diff -u "$file" - | \
sed -e "1s|--- |--- a/|" -e "2s|+++ -|+++ b/$file|" >> "$PATCH"
fi
done

# If user asked to fix the style issues then we are done
if $CORRECT; then
exit 0
fi

# If no patch has been generated, clean up the file stub and exit
if [ ! -s "$PATCH" ] ; then
echo "No code style issues found"
rm -f "$PATCH"
exit 0
fi

# A patch has been created, notify the user and exit
echo "****************************************************************************"
echo "Code doesn't comply with style rules. Run the following command to fix them."
echo "****************************************************************************"
echo "$0 -c"
rm -f "$PATCH"
exit 1
49 changes: 49 additions & 0 deletions Tools/linters/shlint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash -e

ADK_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../../"

# shellcheck source=Tools/
source "$ADK_ROOT/Tools/download.sh"

# Install shellcheck
SHELLCHECK_VERSION="0.7.0"
if ! shellcheck --version | grep -q $SHELLCHECK_VERSION; then
echo "Shellcheck version incorrect. Installing..."

SHELLCHECK_BIN_FILE=
DEST=
case "$(uname)" in
"Darwin")
SHELLCHECK_BIN_FILE="shellcheck-stable.darwin.x86_64"
DEST="/usr/local/bin"
;;
"Linux")
SHELLCHECK_BIN_FILE="shellcheck-stable.linux.x86_64"
DEST="/usr/bin"
;;
*)
echo "Unsupported system"
exit 1
;;
esac

download shellcheck.tar.xz "https://shellcheck.storage.googleapis.com/$SHELLCHECK_BIN_FILE.tar.xz" \
&& tar -xvf "shellcheck.tar.xz" \
&& chmod 755 shellcheck-stable/shellcheck \
&& cp -f shellcheck-stable/shellcheck "$DEST/shellcheck" \
&& rm -rf shellcheck*
fi

find "$ADK_ROOT" -type f \
\( -perm -u=x -o -perm -g=x -o -perm -o=x \) \
-not -path "*\.tmp*" \
-exec bash -c 'grep -r "^#!.*\/bin\/bash" $1 1> /dev/null' _ {} \; \
-print0 \
-o -name "*.sh" \
-not -path "*\.tmp*" \
-print0 \
| xargs -0 \
shellcheck \
--external-sources \
--exclude=SC1091 \
--shell=bash \

0 comments on commit 5568824

Please sign in to comment.