summaryrefslogtreecommitdiff
path: root/Tools/lint.sh
blob: 69cb5b27bb80a447c6fcb8d9074e32ec47ef32ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#! /bin/bash
#
# Linter script that checks for common style issues in Dolphin's codebase.

set -euo pipefail

# use Windows' git when working under path mounted from host on wsl2
# inspired by https://markentier.tech/posts/2020/10/faster-git-under-wsl2/#solution
GIT=git
if [ "$(uname -s)" == "Linux" ]; then
  if [ "$(stat --file-system --format=%T `pwd -P`)" == "v9fs" ]; then
    GIT=git.exe
  fi
fi

if ! [ -x "$(command -v $GIT)" ]; then
  echo >&2 "error: git is not installed"
  exit 1
fi

REQUIRED_CLANG_FORMAT_MAJOR=19
REQUIRED_CLANG_FORMAT_MINOR=1
CLANG_FORMAT=clang-format
CLANG_FORMAT_MAJOR=clang-format-${REQUIRED_CLANG_FORMAT_MAJOR}
CLANG_FORMAT_MAJOR_MINOR=${CLANG_FORMAT_MAJOR}.${REQUIRED_CLANG_FORMAT_MINOR}

if [ -x "$(command -v $CLANG_FORMAT_MAJOR)" ]; then CLANG_FORMAT=$CLANG_FORMAT_MAJOR; fi
if [ -x "$(command -v $CLANG_FORMAT_MAJOR_MINOR)" ]; then CLANG_FORMAT=$CLANG_FORMAT_MAJOR_MINOR; fi

if ! [ -x "$(command -v $CLANG_FORMAT)" ]; then
  echo >&2 "error: clang-format is not installed"
  echo >&2 "Install clang-format version ${REQUIRED_CLANG_FORMAT_MAJOR}.${REQUIRED_CLANG_FORMAT_MINOR}.*"
  exit 1
fi

FORCE=0

if [ $# -gt 0 ]; then
  case "$1" in
    -f|--force)
    FORCE=1
    shift
    ;;
  esac
fi

if [ $FORCE -eq 0 ]; then
  CLANG_FORMAT_VERSION=$($CLANG_FORMAT --version)
  clang_format_version_ok=false
  clang_format_version_re='version ([0-9]+).([0-9]+)'
  if [[ $CLANG_FORMAT_VERSION =~ $clang_format_version_re ]]; then
    CLANG_FORMAT_MAJOR="${BASH_REMATCH[1]}"
    CLANG_FORMAT_MINOR="${BASH_REMATCH[2]}"
    if [ $CLANG_FORMAT_MAJOR == $REQUIRED_CLANG_FORMAT_MAJOR ] && [ $CLANG_FORMAT_MINOR == $REQUIRED_CLANG_FORMAT_MINOR ]; then
      clang_format_version_ok=true
    fi
  fi

  if ! [ "$clang_format_version_ok" = true ]; then
    echo >&2 "error: clang-format is the wrong version (${CLANG_FORMAT_VERSION})"
    echo >&2 "Install clang-format version ${REQUIRED_CLANG_FORMAT_MAJOR}.${REQUIRED_CLANG_FORMAT_MINOR}.* or use --force to ignore"
    exit 1
  fi
fi

did_java_setup=0
JAVA_CODESTYLE_FILE="./$($GIT rev-parse --show-cdup)/Source/Android/code-style-java.xml"
java_temp_dir=""

function java_setup() {
  if [ "$did_java_setup" = 1 ]; then
    return
  fi
  if [ ! -x "${ANDROID_STUDIO_ROOT}/bin/format.sh" ]; then
    echo >&2 "error: must set ANDROID_STUDIO_ROOT environment variable to the IDE installation directory (current: ${ANDROID_STUDIO_ROOT})"
    exit 1
  fi
  java_temp_dir="$(mktemp -d)"
  trap "{ rm -r ${java_temp_dir}; }" EXIT
  did_java_setup=1
}

fail=0

# Default to staged files, unless a commit was passed.
COMMIT=${1:---cached}

# Get modified files (must be on own line for exit-code handling)
modified_files=$($GIT diff --name-only --diff-filter=ACMRTUXB $COMMIT)

function java_check() {
  "${ANDROID_STUDIO_ROOT}/bin/format.sh" -s "${JAVA_CODESTYLE_FILE}" -R "${java_temp_dir}" >/dev/null

  # ignore 'added'/'deleted' files, we copied only files of interest to the tmpdir
  d=$($GIT diff --diff-filter=ad . "${java_temp_dir}" || true)
  if ! [ -z "${d}" ]; then
    echo "!!! Java code is not compliant to coding style, here is the fix:"
    echo "${d}"
    fail=1
  fi
}

# Loop through each modified file.
for f in ${modified_files}; do
  # Filter them.
  if echo "${f}" | grep -E -q "[.]java$"; then
    # Copy Java files to a temporary directory
    java_setup
    mkdir -p $(dirname "${java_temp_dir}/${f}")
    cp "${f}" "${java_temp_dir}/${f}"
    continue
  fi
  if ! echo "${f}" | grep -E -q "[.](cpp|h|mm)$"; then
    continue
  fi
  if ! echo "${f}" | grep -E -q "^Source"; then
    continue
  fi

  # Check for clang-format issues.
  d=$($CLANG_FORMAT ${f} | (diff -u "${f}" - || true))
  if ! [ -z "${d}" ]; then
    echo "!!! ${f} not compliant to coding style, here is the fix:"
    echo "${d}"
    fail=1
  fi

  # Check for newline at EOF.
  last_line="$(tail -c 1 ${f})"
  if [ -n "${last_line}" ]; then
    echo "!!! ${f} not compliant to coding style:"
    echo "Missing newline at end of file"
    fail=1
  fi
done

if [ "${did_java_setup}" = 1 ]; then
  java_check
fi

exit ${fail}