|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# |
| 4 | +# Script that runs spotlessApply for a single file. |
| 5 | +# In case no file path is provided, the formatting is applied to the whole project. |
| 6 | +# |
| 7 | +# Advantage over calling Gradle for a single file directly is identifying a subproject and only running the task there. |
| 8 | +# Also, Gradle is only run for certain file extensions (in case this can't be filtered easily when calling the script) |
| 9 | +# |
| 10 | +# We can't avoid the Gradle configuration phase which takes relatively long due to the number of subprojects, |
| 11 | +# But when targeting individual projects we can speed up the process using the on-demand configuration feature |
| 12 | +# (see https://docs.gradle.org/current/userguide/multi_project_configuration_and_execution.html). |
| 13 | +# |
| 14 | +# Configuration as file watcher in IntelliJ: |
| 15 | +# |
| 16 | +# 1. Install File Watchers plugin |
| 17 | +# 2. Settings -> Tools -> File Watchers -> Add |
| 18 | +# |
| 19 | +# File type: Any |
| 20 | +# Program: $ProjectFileDir$/spotless.sh |
| 21 | +# Arguments: $FilePath$ |
| 22 | +# Output paths to refresh: $FilePath$ |
| 23 | +# Working directory: $ProjectFileDir$ |
| 24 | +# |
| 25 | +# Disable |
| 26 | +# - auto save on editing running the tool while editing |
| 27 | +# - external changes sync to avoid running the tool when files are externally modified |
| 28 | +# |
| 29 | + |
| 30 | +set -e |
| 31 | + |
| 32 | +# Detect macOS and set realpath command |
| 33 | +if [[ "$(uname)" == "Darwin" ]]; then |
| 34 | + if ! command -v grealpath >/dev/null 2>&1; then |
| 35 | + echo "Error: 'grealpath' not found. Please install coreutils with:" |
| 36 | + echo " brew install coreutils" |
| 37 | + exit 1 |
| 38 | + fi |
| 39 | + realpath_cmd="grealpath" |
| 40 | +else |
| 41 | + realpath_cmd="realpath" |
| 42 | +fi |
| 43 | + |
| 44 | +# Define the list of allowed file extensions |
| 45 | +allowed_extensions=("java" "md" "groovy" "gradle" "kt" "scala" "sc") |
| 46 | + |
| 47 | +# Check if a file path is provided |
| 48 | +if [ -z "$1" ]; then |
| 49 | + echo "No file path provided" |
| 50 | + |
| 51 | + exec ./gradlew spotlessApply --parallel |
| 52 | + exit 0 |
| 53 | +fi |
| 54 | + |
| 55 | +# Get the file extension |
| 56 | +file_extension="${1##*.}" |
| 57 | + |
| 58 | +# Check if the file extension is in the allowed list |
| 59 | +if [[ ! "${allowed_extensions[@]}" =~ "${file_extension}" ]]; then |
| 60 | + echo "Error: The file extension .$file_extension is not allowed." |
| 61 | + exit 0 |
| 62 | +fi |
| 63 | + |
| 64 | +# Get the absolute path of the provided file |
| 65 | +file_path=$($realpath_cmd "$1") |
| 66 | + |
| 67 | +# Get the directory containing the file |
| 68 | +current_dir=$(dirname "$file_path") |
| 69 | + |
| 70 | +# Get the directory where the script resides |
| 71 | +script_dir=$(dirname "$($realpath_cmd "$0")") |
| 72 | + |
| 73 | +# Traverse up the directory tree to find the first parent directory with build.gradle or build.gradle.kts |
| 74 | +while [ "$current_dir" != "/" ]; do |
| 75 | + if [ -f "$current_dir/build.gradle" ] || [ -f "$current_dir/build.gradle.kts" ]; then |
| 76 | + # Determine the relative path from the script's directory |
| 77 | + relative_path=$($realpath_cmd --relative-to="$script_dir" "$current_dir") |
| 78 | + |
| 79 | + # Check if the folder is the same as the script directory |
| 80 | + if [ "$current_dir" == "$script_dir" ]; then |
| 81 | + echo "Found build.gradle(.kts) in the project root: $relative_path" |
| 82 | + |
| 83 | + exec ./gradlew :spotlessApply "-PspotlessIdeHook=$file_path" --parallel --configure-on-demand |
| 84 | + else |
| 85 | + # Replace / with : in the relative path |
| 86 | + formatted_path=$(echo "$relative_path" | tr '/' ':') |
| 87 | + echo "Found build.gradle(.kts) in a subfolder: $formatted_path" |
| 88 | + |
| 89 | + exec ./gradlew ":$formatted_path:spotlessApply" "-PspotlessIdeHook=$file_path" --parallel --configure-on-demand |
| 90 | + fi |
| 91 | + exit 0 |
| 92 | + fi |
| 93 | + |
| 94 | + # Stop if we reach the script's directory |
| 95 | + if [ "$current_dir" == "$script_dir" ]; then |
| 96 | + break |
| 97 | + fi |
| 98 | + |
| 99 | + current_dir=$(dirname "$current_dir") |
| 100 | +done |
| 101 | + |
| 102 | +echo "No build.gradle or build.gradle.kts found within the script's directory." |
| 103 | +exit 1 |
0 commit comments