Opinionated java-library project template
at main 216 lines 5.4 kB view raw
1#!/usr/bin/env bash 2set -euo pipefail 3 4usage() { 5 cat <<'USAGE' 6Usage: ./.scripts/rename-template.sh \ 7 -g <groupId> \ 8 -p <projectName> \ 9 -n <repoName> \ 10 -s <snapshotsRepoUrl> \ 11 -r <releasesRepoUrl> \ 12 -a <author> \ 13 -y <year> 14 15Example: 16 ./.scripts/rename-template.sh \ 17 -g com.acme \ 18 -p my-project \ 19 -n acmeRepo \ 20 -s https://repo.acme.com/snapshots \ 21 -r https://repo.acme.com/releases \ 22 -a "Acme, Inc." \ 23 -y 2026 24USAGE 25} 26 27GROUP_ID="" 28PROJECT_NAME="" 29REPO_NAME="" 30SNAPSHOTS_REPO_URL="" 31RELEASES_REPO_URL="" 32AUTHOR="" 33COPYRIGHT_YEAR="" 34 35while getopts ":g:p:n:s:r:a:y:h" opt; do 36 case "$opt" in 37 g) GROUP_ID="$OPTARG" ;; 38 p) PROJECT_NAME="$OPTARG" ;; 39 n) REPO_NAME="$OPTARG" ;; 40 s) SNAPSHOTS_REPO_URL="$OPTARG" ;; 41 r) RELEASES_REPO_URL="$OPTARG" ;; 42 a) AUTHOR="$OPTARG" ;; 43 y) COPYRIGHT_YEAR="$OPTARG" ;; 44 h) 45 usage 46 exit 0 47 ;; 48 \?) 49 echo "Unknown option: -$OPTARG" >&2 50 usage 51 exit 1 52 ;; 53 :) 54 echo "Missing argument for -$OPTARG" >&2 55 usage 56 exit 1 57 ;; 58 esac 59done 60 61if [[ -z "$GROUP_ID" || -z "$PROJECT_NAME" || -z "$REPO_NAME" || -z "$SNAPSHOTS_REPO_URL" || -z "$RELEASES_REPO_URL" || -z "$AUTHOR" || -z "$COPYRIGHT_YEAR" ]]; then 62 usage 63 exit 1 64fi 65 66PROJECT_NAME="${PROJECT_NAME##.}" 67if [[ -z "$PROJECT_NAME" ]]; then 68 echo "Project name cannot be only dots." >&2 69 exit 1 70fi 71 72normalize_segment() { 73 local segment="$1" 74 local normalized 75 normalized="$(echo "$segment" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_]/_/g')" 76 normalized="${normalized##_}" 77 normalized="${normalized%%_}" 78 if [[ -z "$normalized" ]]; then 79 normalized="app" 80 fi 81 echo "$normalized" 82} 83 84build_package_name() { 85 local group_id="$1" 86 local project_name="$2" 87 local -a package_segments 88 local -a group_parts 89 90 IFS='.' read -r -a group_parts <<<"$group_id" 91 for part in "${group_parts[@]}"; do 92 package_segments+=("$(normalize_segment "$part")") 93 done 94 package_segments+=("$(normalize_segment "$project_name")") 95 IFS='.' 96 echo "${package_segments[*]}" 97} 98 99PACKAGE_NAME="$(build_package_name "$GROUP_ID" "$PROJECT_NAME")" 100REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" 101TEMPLATE_PACKAGE="com.example.template" 102 103SOURCE_MODULE_DIR="$REPO_ROOT/template-api" 104 105FILES=( 106 "$REPO_ROOT/build.gradle.kts" 107 "$REPO_ROOT/settings.gradle.kts" 108 "$REPO_ROOT/build-logic/src/main/kotlin/extensions.kt" 109 "$REPO_ROOT/build-logic/src/main/kotlin/publishing-conventions.gradle.kts" 110 "$REPO_ROOT/license.txt" 111 "$REPO_ROOT/license_header.txt" 112 "$REPO_ROOT/.checkstyle/suppressions.xml" 113) 114 115if [[ -d "$SOURCE_MODULE_DIR/src/main/java" ]]; then 116 while IFS= read -r -d '' file; do 117 FILES+=("$file") 118 done < <(find "$SOURCE_MODULE_DIR/src/main/java" -type f -print0) 119fi 120 121if [[ -d "$SOURCE_MODULE_DIR/src/test/java" ]]; then 122 while IFS= read -r -d '' file; do 123 FILES+=("$file") 124 done < <(find "$SOURCE_MODULE_DIR/src/test/java" -type f -print0) 125fi 126 127SED_INPLACE=(-i) 128if [[ "$(uname)" == "Darwin" ]]; then 129 SED_INPLACE=(-i '') 130fi 131 132escape_sed() { 133 local value="$1" 134 value="${value//\\/\\\\}" 135 value="${value//&/\\&}" 136 value="${value//\//\\/}" 137 echo "$value" 138} 139 140replace_placeholders() { 141 local file="$1" 142 local safe_group safe_project safe_package 143 local safe_repo_name 144 local safe_snapshots_repo_url safe_releases_repo_url 145 local safe_project_api 146 local safe_author safe_copyright_year 147 148 safe_group="$(escape_sed "$GROUP_ID")" 149 safe_project="$(escape_sed "$PROJECT_NAME")" 150 safe_package="$(escape_sed "$PACKAGE_NAME")" 151 safe_repo_name="$(escape_sed "$REPO_NAME")" 152 safe_snapshots_repo_url="$(escape_sed "$SNAPSHOTS_REPO_URL")" 153 safe_releases_repo_url="$(escape_sed "$RELEASES_REPO_URL")" 154 safe_project_api="$(escape_sed "${PROJECT_NAME}-api")" 155 safe_author="$(escape_sed "$AUTHOR")" 156 safe_copyright_year="$(escape_sed "$COPYRIGHT_YEAR")" 157 158 sed "${SED_INPLACE[@]}" \ 159 -e "s/{{GROUP_ID}}/$safe_group/g" \ 160 -e "s/{{PROJECT_NAME}}/$safe_project/g" \ 161 -e "s/{{PACKAGE_NAME}}/$safe_package/g" \ 162 -e "s/{{REPO_NAME}}/$safe_repo_name/g" \ 163 -e "s/{{SNAPSHOTS_REPO_URL}}/$safe_snapshots_repo_url/g" \ 164 -e "s/{{RELEASES_REPO_URL}}/$safe_releases_repo_url/g" \ 165 -e "s/{{AUTHOR}}/$safe_author/g" \ 166 -e "s/{{COPYRIGHT_YEAR}}/$safe_copyright_year/g" \ 167 -e "s/template-api/$safe_project_api/g" \ 168 "$file" 169} 170 171for file in "${FILES[@]}"; do 172 [[ -f "$file" ]] || continue 173 replace_placeholders "$file" 174 echo "Updated: $file" 175done 176 177move_package_dir() { 178 local base_dir="$1" 179 local old_dir 180 local new_dir 181 old_dir="$base_dir/$(echo "$TEMPLATE_PACKAGE" | tr '.' '/')" 182 new_dir="$base_dir/$(echo "$PACKAGE_NAME" | tr '.' '/')" 183 184 if [[ -d "$old_dir" ]]; then 185 mkdir -p "$new_dir" 186 shopt -s dotglob nullglob 187 mv "$old_dir"/* "$new_dir"/ 188 shopt -u dotglob nullglob 189 rmdir "$old_dir" 2>/dev/null || true 190 fi 191 192 if [[ -d "$base_dir" ]]; then 193 find "$base_dir" -type d -empty -delete 194 fi 195} 196 197move_package_dir "$SOURCE_MODULE_DIR/src/main/java" 198move_package_dir "$SOURCE_MODULE_DIR/src/test/java" 199 200if [[ -d "$REPO_ROOT/template-api" ]]; then 201 mv "$REPO_ROOT/template-api" "$REPO_ROOT/${PROJECT_NAME}-api" 202fi 203 204if [[ -d "$REPO_ROOT/.git" ]]; then 205 rm -rf "$REPO_ROOT/.git" 206fi 207 208if command -v git >/dev/null 2>&1; then 209 git -C "$REPO_ROOT" init 210else 211 echo "Warning: git not found; skipping git init." >&2 212fi 213 214echo "" 215echo "Done!" 216echo ""