• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2#
3# Copyright (C) 2022 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17# Declare a map of relative paths from the libcore directory to checkstyle
18# configuration files to apply.
19declare -A PATH_TO_CONFIG=(
20    [benchmarks]=tools/checkstyle/not-gpl.xml
21    [dalvik]=tools/checkstyle/aosp-copyright.xml
22    [dom]=tools/checkstyle/w3c-copyright.xml
23    [harmony-tests]=tools/checkstyle/not-gpl.xml
24    [json]=tools/checkstyle/aosp-copyright.xml
25    [jsr166-tests]=tools/checkstyle/jsr166-public-domain.xml
26    [libart]=tools/checkstyle/aosp-copyright.xml
27    [luni/annotations]=tools/checkstyle/not-gpl.xml
28    [luni/src/main/java]=tools/checkstyle/not-gpl.xml
29    [luni/src/module]=tools/checkstyle/aosp-copyright.xml
30    [luni/src/test/androidsdk34]=tools/checkstyle/aosp-copyright.xml
31    [luni/src/test/androidsdkcurrent]=tools/checkstyle/aosp-copyright.xml
32    [luni/src/test/annotations/src/libcore/tests]=tools/checkstyle/aosp-copyright.xml
33    [luni/src/test/dex_src/libcore]=tools/checkstyle/aosp-copyright.xml
34    [luni/src/test/etc]=tools/checkstyle/aosp-copyright.xml
35    [luni/src/test/filesystems]=tools/checkstyle/aosp-copyright.xml
36    [luni/src/test/java/crossvmtest]=tools/checkstyle/aosp-copyright.xml
37    [luni/src/test/java/libcore/android]=tools/checkstyle/aosp-copyright.xml
38    [luni/src/test/java/libcore/build]=tools/checkstyle/aosp-copyright.xml
39    [luni/src/test/java/libcore/dalvik/system]=tools/checkstyle/aosp-copyright.xml
40    [luni/src/test/java/libcore/highmemorytest]=tools/checkstyle/aosp-copyright.xml
41    [luni/src/test/java/libcore/java]=tools/checkstyle/not-gpl.xml
42    [luni/src/test/java/libcore/javax/crypto]=tools/checkstyle/aosp-copyright.xml
43    [luni/src/test/java/libcore/javax/net]=tools/checkstyle/aosp-copyright.xml
44    [luni/src/test/java/libcore/javax/security]=tools/checkstyle/aosp-copyright.xml
45    [luni/src/test/java/libcore/javax/sql]=tools/checkstyle/asf-copyright.xml
46    [luni/src/test/java/libcore/javax/xml]=tools/checkstyle/aosp-copyright.xml
47    [luni/src/test/java/libcore/jdk]=tools/checkstyle/aosp-copyright.xml
48    [luni/src/test/java/libcore/libcore]=tools/checkstyle/aosp-copyright.xml
49    [luni/src/test/java/libcore/sun]=tools/checkstyle/aosp-copyright.xml
50    [luni/src/test/java/libcore/xml]=tools/checkstyle/aosp-copyright.xml
51    [luni/src/test/java/org/apache/harmony]=tools/checkstyle/not-gpl.xml
52    [luni/src/test/java/tests/com/android/org]=tools/checkstyle/aosp-copyright.xml
53    [luni/src/test/java/tests/java/lang]=tools/checkstyle/aosp-copyright.xml
54    [luni/src/test/java/tests/java/nio]=tools/checkstyle/aosp-copyright.xml
55    [luni/src/test/java/tests/java/security]=tools/checkstyle/asf-copyright.xml
56    [luni/src/test/java/tests/java/sql]=tools/checkstyle/aosp-copyright.xml
57    [luni/src/test/java/tests/javax/crypto]=tools/checkstyle/aosp-copyright.xml
58    [luni/src/test/java/tests/org/w3c]=tools/checkstyle/w3c-copyright.xml
59    [luni/src/test/java/tests/security]=tools/checkstyle/not-gpl.xml
60    [luni/src/test/java/tests/support]=tools/checkstyle/aosp-copyright.xml
61    [luni/src/test/java/tests/targets]=tools/checkstyle/aosp-copyright.xml
62    [luni/src/test/java17language]=tools/checkstyle/aosp-copyright.xml
63    [luni/src/test/java11language]=tools/checkstyle/aosp-copyright.xml
64    [luni/src/test/java9compatibility]=tools/checkstyle/aosp-copyright.xml
65    [luni/src/test/java9language]=tools/checkstyle/aosp-copyright.xml
66    [luni/src/test/parameter_metadata]=tools/checkstyle/aosp-copyright.xml
67    [metrictests]=tools/checkstyle/aosp-copyright.xml
68    [ojluni/annotations]=tools/checkstyle/ojluni-src-main-header.xml
69    [ojluni/src/lambda]=tools/checkstyle/ojluni-src-main-header.xml
70    [ojluni/src/main]=tools/checkstyle/ojluni-src-main-header.xml
71    [ojluni/src/test]=tools/checkstyle/ojluni-src-test-header.xml
72    [ojluni/src/tools]=tools/checkstyle/ojluni-src-main-header.xml
73    [support/src/test/java/libcore]=tools/checkstyle/aosp-copyright.xml
74    [support/src/test/java/org]=tools/checkstyle/asf-copyright.xml
75    [support/src/test/java/tests]=tools/checkstyle/not-gpl.xml
76    [test-rules]=tools/checkstyle/aosp-copyright.xml
77    [tools]=tools/checkstyle/aosp-copyright.xml
78    [xml]=tools/checkstyle/not-gpl.xml
79)
80
81function fatal_error() {
82    echo -e "${@}" >&2
83    exit 1
84}
85
86function warn() {
87    echo -e "${@}" >&2
88}
89
90# Function to expand a user provided directory into directories that appear in the
91# configuration map.
92# Usage: checkstyle_of_paths <path1> [... <pathN>]
93function expand_directories() {
94    local requested_path name
95    for requested_path in "${@}" ; do
96        if [ -d "${requested_path}" ]; then
97            requested_path=${requested_path%/}
98            for prefix in "${!PATH_TO_CONFIG[@]}"; do
99                if [[ "${prefix}/" = "${requested_path}"/* ]]; then
100                    echo -n " ${prefix}"
101                fi
102            done
103        else
104            echo -n " ${requested_path}"
105        fi
106    done
107}
108
109# Function to apply path specific checkstyle configurations to a list of specified paths.
110# Usage: checkstyle_of_paths <path1> [... <pathN>]
111function checkstyle_of_paths() {
112    local matching_files prefix requested_path requested_paths
113    declare -A visited
114
115    requested_paths=$(expand_directories "${@}")
116    for prefix in "${!PATH_TO_CONFIG[@]}"; do
117        matching_files=()
118        for requested_path in ${requested_paths} ; do
119            if [[ "${requested_path}" = "${prefix}" || "${requested_path}" = "${prefix}"/* ]] ; then
120                matching_files+=("${requested_path}")
121                visited[${requested_path}]="yes"
122            fi
123        done
124
125        if [ "${matching_files[*]}" = "" ]; then
126            continue
127        fi
128
129        echo "Applying ${PATH_TO_CONFIG[${prefix}]} to ${matching_files[@]}"
130        ${CHECKSTYLE} --config_xml "${PATH_TO_CONFIG[${prefix}]}" --file "${matching_files[@]}" \
131            || exit 1
132    done
133
134    for requested_path in "${@}" ; do
135        if [ -z "${visited[${requested_path}]}" ] ; then
136            warn "WARNING: No checkstyle configuration covers ${requested_path}"
137        fi
138    done
139}
140
141# Function to check that the paths (keys) in PATH_TO_CONFIG exist.
142function check_directories_with_configs_exist() {
143    local prefix prefix_no_slash
144
145    for prefix in "${!PATH_TO_CONFIG[@]}"; do
146        prefix_no_slash=${prefix%/}
147        if [ "${prefix}" != "${prefix_no_slash}" ]; then
148            fatal_error "Directory name should not end with '/': ${prefix}"
149        fi
150        if [ ! -d "${prefix}" ] ; then
151            fatal_error "Bad prefix path. Directory does not exist: ${prefix}"
152        fi
153    done
154}
155
156# Function to check that all Java files have an associated checkstyle configuration.
157function check_files_have_associated_configs() {
158    local java_file prefix has_match
159
160    for java_file in $(find . -type f -name '*.java' | sed -e 's@^[.]/@@'); do
161        has_match=""
162        for prefix in "${!PATH_TO_CONFIG[@]}"; do
163            if [[ "${java_file}" = "${prefix}"/* ]]; then
164                has_match="y"
165                break
166            fi
167        done
168
169        if [ -z "${has_match}" ]; then
170            fatal_error "${java_file} has no checkstyle configuration."
171        fi
172    done
173}
174
175# Main function that applies checkstyle to the files provided as arguments or to the all
176# the paths in libcore that have checkstyle configurations (if no arguments are provided).
177# Usage: main [<path1> ... <pathN>]
178function main() {
179    if [ -n "$REPO_ROOT" ] ; then
180        ROOT=${REPO_ROOT}
181    elif [ -n "$ANDROID_BUILD_TOP" ]; then
182        ROOT=${ANDROID_BUILD_TOP}
183    else
184        fatal_error "This script requires REPO_ROOT or ANDROID_BUILD_TOP to be defined." \
185                    "\nRun \`lunch\` and try again."
186    fi
187
188    CHECKSTYLE=${ROOT}/prebuilts/checkstyle/checkstyle.py
189    if [ ! -x ${CHECKSTYLE} ]; then
190        fatal_error "Checkstyle is not present or is not executable: ${CHECKSTYLE}"
191    fi
192
193    cd "${ROOT}/libcore"
194
195    check_directories_with_configs_exist
196    check_files_have_associated_configs
197
198    if [ $# = 0 ] ; then
199        checkstyle_of_paths "${!PATH_TO_CONFIG[@]}"
200    else
201        checkstyle_of_paths "${@}"
202    fi
203}
204
205main "${@}"
206