xref: /aosp_15_r20/libcore/tools/checkstyle/libcore-checkstyle.sh (revision 89a6322812dc8573315e60046e7959c50dad91d4)
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/java21language]=tools/checkstyle/aosp-copyright.xml
63    [luni/src/test/java17language]=tools/checkstyle/aosp-copyright.xml
64    [luni/src/test/java11language]=tools/checkstyle/aosp-copyright.xml
65    [luni/src/test/java9compatibility]=tools/checkstyle/aosp-copyright.xml
66    [luni/src/test/java9language]=tools/checkstyle/aosp-copyright.xml
67    [luni/src/test/parameter_metadata]=tools/checkstyle/aosp-copyright.xml
68    [metrictests]=tools/checkstyle/aosp-copyright.xml
69    [ojluni/annotations]=tools/checkstyle/ojluni-src-main-header.xml
70    [ojluni/src/lambda]=tools/checkstyle/ojluni-src-main-header.xml
71    [ojluni/src/main]=tools/checkstyle/ojluni-src-main-header.xml
72    [ojluni/src/test]=tools/checkstyle/ojluni-src-test-header.xml
73    [ojluni/src/tools]=tools/checkstyle/ojluni-src-main-header.xml
74    [support/src/test/java/libcore]=tools/checkstyle/aosp-copyright.xml
75    [support/src/test/java/org]=tools/checkstyle/asf-copyright.xml
76    [support/src/test/java/tests]=tools/checkstyle/not-gpl.xml
77    [test-rules]=tools/checkstyle/aosp-copyright.xml
78    [tools]=tools/checkstyle/aosp-copyright.xml
79    [xml]=tools/checkstyle/not-gpl.xml
80)
81
82function fatal_error() {
83    echo -e "${@}" >&2
84    exit 1
85}
86
87function warn() {
88    echo -e "${@}" >&2
89}
90
91# Function to expand a user provided directory into directories that appear in the
92# configuration map.
93# Usage: checkstyle_of_paths <path1> [... <pathN>]
94function expand_directories() {
95    local requested_path name
96    for requested_path in "${@}" ; do
97        if [ -d "${requested_path}" ]; then
98            requested_path=${requested_path%/}
99            for prefix in "${!PATH_TO_CONFIG[@]}"; do
100                if [[ "${prefix}/" = "${requested_path}"/* ]]; then
101                    echo -n " ${prefix}"
102                fi
103            done
104        else
105            echo -n " ${requested_path}"
106        fi
107    done
108}
109
110# Function to apply path specific checkstyle configurations to a list of specified paths.
111# Usage: checkstyle_of_paths <path1> [... <pathN>]
112function checkstyle_of_paths() {
113    local matching_files prefix requested_path requested_paths
114    declare -A visited
115
116    requested_paths=$(expand_directories "${@}")
117    for prefix in "${!PATH_TO_CONFIG[@]}"; do
118        matching_files=()
119        for requested_path in ${requested_paths} ; do
120            if [[ "${requested_path}" = "${prefix}" || "${requested_path}" = "${prefix}"/* ]] ; then
121                matching_files+=("${requested_path}")
122                visited[${requested_path}]="yes"
123            fi
124        done
125
126        if [ "${matching_files[*]}" = "" ]; then
127            continue
128        fi
129
130        echo "Applying ${PATH_TO_CONFIG[${prefix}]} to ${matching_files[@]}"
131        ${CHECKSTYLE} --config_xml "${PATH_TO_CONFIG[${prefix}]}" --file "${matching_files[@]}" \
132            || exit 1
133    done
134
135    for requested_path in "${@}" ; do
136        if [ -z "${visited[${requested_path}]}" ] ; then
137            warn "WARNING: No checkstyle configuration covers ${requested_path}"
138        fi
139    done
140}
141
142# Function to check that the paths (keys) in PATH_TO_CONFIG exist.
143function check_directories_with_configs_exist() {
144    local prefix prefix_no_slash
145
146    for prefix in "${!PATH_TO_CONFIG[@]}"; do
147        prefix_no_slash=${prefix%/}
148        if [ "${prefix}" != "${prefix_no_slash}" ]; then
149            fatal_error "Directory name should not end with '/': ${prefix}"
150        fi
151        if [ ! -d "${prefix}" ] ; then
152            fatal_error "Bad prefix path. Directory does not exist: ${prefix}"
153        fi
154    done
155}
156
157# Function to check that all Java files have an associated checkstyle configuration.
158function check_files_have_associated_configs() {
159    local java_file prefix has_match
160
161    for java_file in $(find . -type f -name '*.java' | sed -e 's@^[.]/@@'); do
162        has_match=""
163        for prefix in "${!PATH_TO_CONFIG[@]}"; do
164            if [[ "${java_file}" = "${prefix}"/* ]]; then
165                has_match="y"
166                break
167            fi
168        done
169
170        if [ -z "${has_match}" ]; then
171            fatal_error "${java_file} has no checkstyle configuration."
172        fi
173    done
174}
175
176# Main function that applies checkstyle to the files provided as arguments or to the all
177# the paths in libcore that have checkstyle configurations (if no arguments are provided).
178# Usage: main [<path1> ... <pathN>]
179function main() {
180    if [ -n "$REPO_ROOT" ] ; then
181        ROOT=${REPO_ROOT}
182    elif [ -n "$ANDROID_BUILD_TOP" ]; then
183        ROOT=${ANDROID_BUILD_TOP}
184    else
185        fatal_error "This script requires REPO_ROOT or ANDROID_BUILD_TOP to be defined." \
186                    "\nRun \`lunch\` and try again."
187    fi
188
189    CHECKSTYLE=${ROOT}/prebuilts/checkstyle/checkstyle.py
190    if [ ! -x ${CHECKSTYLE} ]; then
191        fatal_error "Checkstyle is not present or is not executable: ${CHECKSTYLE}"
192    fi
193
194    cd "${ROOT}/libcore"
195
196    check_directories_with_configs_exist
197    check_files_have_associated_configs
198
199    if [ $# = 0 ] ; then
200        checkstyle_of_paths "${!PATH_TO_CONFIG[@]}"
201    else
202        checkstyle_of_paths "${@}"
203    fi
204}
205
206main "${@}"
207