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