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