forked from openMF/kmp-project-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcustomizer.sh
400 lines (353 loc) Β· 14.4 KB
/
customizer.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
#!/bin/bash
#
# Kotlin Multiplatform Project Customizer
# Based on Android template customizer
#
# Verify bash version. macOS comes with bash 3 preinstalled.
if [[ ${BASH_VERSINFO[0]} -lt 4 ]]
then
echo "You need at least bash 4 to run this script."
exit 1
fi
# exit when any command fails
set -e
# Print section header
print_section() {
echo
echo "==== $1 ===="
echo
}
if [[ $# -lt 2 ]]; then
echo "Usage: bash customizer.sh my.new.package MyNewProject [ApplicationName]" >&2
echo "Example: bash customizer.sh com.example.myapp MyKMPApp" >&2
exit 2
fi
PACKAGE=$1
PROJECT_NAME=$2
APPNAME=${3:-$PROJECT_NAME}
SUBDIR=${PACKAGE//.//} # Replaces . with /
PROJECT_NAME_LOWERCASE=$(echo "$PROJECT_NAME" | tr '[:upper:]' '[:lower:]')
# Capitalize first letter for replacing "Mifos" prefix
capitalize_first() {
echo "$1" | awk '{print toupper(substr($0,1,1)) substr($0,2)}'
}
PROJECT_NAME_CAPITALIZED=$(capitalize_first "$PROJECT_NAME")
# Convert kebab case to camel case
kebab_to_camel() {
echo "$1" | sed -E 's/-([a-z])/\U\1/g'
}
# Function to escape dots in package name for sed
escape_dots() {
echo "$1" | sed 's/\./\\./g'
}
# Escape dots in package for sed commands
ESCAPED_PACKAGE=$(escape_dots "$PACKAGE")
# Function to update plugin IDs
update_plugin_ids() {
print_section "Updating Plugin IDs"
echo "π Updating convention plugin IDs in Gradle files..."
find ./ -type f -name "*.gradle.kts" -exec sed -i.bak "s/id(\"org\.mifos\./id(\"$ESCAPED_PACKAGE./g" {} \;
echo "π Updating plugin IDs in version catalog files..."
find ./ -type f -name "*.versions.toml" -exec sed -i.bak "s/id = \"org\.mifos\./id = \"$ESCAPED_PACKAGE./g" {} \;
if [ -d "build-logic" ]; then
echo "π Updating build-logic plugin IDs..."
find ./build-logic -type f -name "*.gradle.kts" -exec sed -i.bak "s/org\.mifos\./$ESCAPED_PACKAGE./g" {} \;
echo "π Updating plugin applications in plugin classes..."
find ./build-logic -type f -name "*.kt" -exec sed -i.bak "s/apply(\"org\.mifos\./apply(\"$ESCAPED_PACKAGE./g" {} \;
fi
# Rename package and imports in Kotlin files
echo "π Renaming packages to $PACKAGE"
find ./ -type f -name "*.kt" -exec sed -i.bak "s/package org\.mifos/package $PACKAGE/g" {} \;
find ./ -type f -name "*.kt" -exec sed -i.bak "s/import org\.mifos/import $PACKAGE/g" {} \;
# Update Gradle files
echo "π Updating Gradle files"
find ./ -type f -name "*.gradle.kts" -exec sed -i.bak "s/org\.mifos/$PACKAGE/g" {} \;
# Then update only the root settings.gradle.kts file
sed -i.bak "s/rootProject\.name = \".*\"/rootProject.name = \"$PROJECT_NAME\"/g" ./settings.gradle.kts
}
# Function to update specific plugin patterns
update_plugin_patterns() {
print_section "Updating Plugin Patterns"
PLUGIN_TYPES=(
"cmp.feature"
"kmp.koin"
"kmp.library"
"detekt.plugin"
"git.hooks"
"ktlint.plugin"
"spotless.plugin"
)
for plugin_type in "${PLUGIN_TYPES[@]}"; do
echo "π Updating pattern: $plugin_type"
find ./ -type f -name "*.versions.toml" -exec sed -i.bak "s/org\.mifos\.$plugin_type/$ESCAPED_PACKAGE.$plugin_type/g" {} \;
find ./ -type f -name "*.gradle.kts" -exec sed -i.bak "s/org\.mifos\.$plugin_type/$ESCAPED_PACKAGE.$plugin_type/g" {} \;
done
}
update_compose_resources() {
print_section "Updating Compose Resources Configuration"
local count=0
while IFS= read -r file; do
if grep -q "packageOfResClass.*org\.mifos" "$file"; then
echo "π¦ Processing: $file"
echo "Debug: Attempting to update $file with package $ESCAPED_PACKAGE"
if ! sed -i.bak "s/packageOfResClass = \"org\.mifos\.\([^\"]*\)\"/packageOfResClass = \"$ESCAPED_PACKAGE.\1\"/g" "$file"; then
echo "Error: sed command failed for $file"
return 1
fi
((count++))
fi
done < <(find ./ -type f -name "*.gradle.kts")
if [ $count -eq 0 ]; then
echo "βΉοΈ No files found containing Compose Resources configuration"
else
echo "β
Updated packageOfResClass in $count file(s)"
fi
}
# Function to rename and update application class
#update_application_class() {
# print_section "Updating Application Class"
#
# if [[ $APPNAME != MyApplication ]]; then
# echo "π Renaming application to $APPNAME"
# find ./ -type f \( -name "*.kt" -or -name "*.gradle.kts" -or -name "*.xml" \) -exec sed -i.bak "s/MifosApp/$APPNAME/g" {} \;
# find ./ -name "MifosApp.kt" | sed "p;s/MifosApp/$APPNAME/" | tr '\n' '\0' | xargs -0 -n 2 mv 2>/dev/null || true
# echo "β
Application class renamed successfully"
# else
# echo "βΉοΈ Skipping application rename as name is default"
# fi
#}
# Function to update iOS configurations
update_ios_config() {
print_section "Updating iOS Configuration"
if [ -d "cmp-ios" ]; then
echo "π Updating iOS project files..."
find ./cmp-ios -type f -name "*.xcodeproj" -exec sed -i.bak "s/PRODUCT_BUNDLE_IDENTIFIER = .*$/PRODUCT_BUNDLE_IDENTIFIER = $PACKAGE;/g" {} \;
find ./cmp-ios -type f -name "*.plist" -exec sed -i.bak "s/PRODUCT_BUNDLE_IDENTIFIER = .*$/PRODUCT_BUNDLE_IDENTIFIER = $PACKAGE;/g" {} \;
echo "β
iOS configuration updated"
else
echo "βΉοΈ No iOS directory found, skipping iOS configuration"
fi
}
# Function to process module directories
process_module_dirs() {
local module_path=$1
local src_dirs=("main" "commonMain" "commonTest" "androidMain" "androidTest" "iosMain" "nativeMain" "iosTest" "desktopMain" "desktopTest" "jvmMain" "jvmTest" "jsMain" "jsTest" "wasmJsMain" "wasmJsTest")
for src_dir in "${src_dirs[@]}"
do
local kotlin_dir="$module_path/src/$src_dir/kotlin"
if [ -d "$kotlin_dir" ]; then
echo "π Processing $kotlin_dir"
mkdir -p "$kotlin_dir/$SUBDIR"
if [ -d "$kotlin_dir/org/mifos" ]; then
echo "π¦ Moving files from org/mifos to $SUBDIR"
cp -r "$kotlin_dir/org/mifos"/* "$kotlin_dir/$SUBDIR/" 2>/dev/null || true
if [ -d "$kotlin_dir/$SUBDIR" ]; then
echo "π Updating package declarations and imports"
find "$kotlin_dir/$SUBDIR" -type f -name "*.kt" -exec sed -i.bak \
-e "s/package org\.mifos/package $PACKAGE/g" \
-e "s/package com\.niyaj/package $PACKAGE/g" \
-e "s/import org\.mifos/import $PACKAGE/g" \
-e "s/import com\.niyaj/import $PACKAGE/g" {} \;
fi
echo "ποΈ Cleaning up old directory structure"
rm -rf "$kotlin_dir/org/mifos"
# Remove org directory if it's empty
rmdir "$kotlin_dir/org" 2>/dev/null || true
fi
fi
done
find "$module_path" -type f -name "*.kt" -exec sed -i.bak "s/import org\.mifos/import $PACKAGE/g" {} \;
find "$module_path" -type f -name "*.kt" -exec sed -i.bak "s/package org\.mifos/package $PACKAGE/g" {} \;
}
process_module_content() {
# Process all modules
echo "π Processing module contents..."
for module in $(find . -type f -name "build.gradle.kts" -not -path "*/build/*" -exec dirname {} \;)
do
echo "Found module: $module"
process_module_dirs "$module"
done
}
# Function to rename files
rename_files() {
echo "π Renaming files with Mifos prefix..."
find . -type f -name "Mifos*.kt" | while read -r file; do
local newfile=$(echo "$file" | sed "s/MifosApp/$PROJECT_NAME_CAPITALIZED/g; s/Mifos/$PROJECT_NAME_CAPITALIZED/g")
echo "π Renaming $file to $newfile"
mv "$file" "$newfile"
done
# Update code elements that start with Mifos
echo "π Updating code elements with Mifos prefix..."
find ./ -type f -name "*.kt" -exec sed -i.bak \
-e "s/MifosApp\([^A-Za-z0-9]\|$\)/$PROJECT_NAME_CAPITALIZED\1/g" \
-e "s/Mifos\([A-Z][a-zA-Z0-9]*\)/$PROJECT_NAME_CAPITALIZED\1/g" {} \;
find ./ -type f -name "*.kt" -exec sed -i.bak \
-e "s/mifosApp\([^A-Za-z0-9]\|$\)/${PROJECT_NAME_LOWERCASE}\1/g" \
-e "s/mifos\([A-Z][a-zA-Z0-9]*\)/${PROJECT_NAME_LOWERCASE}\1/g" {} \;
# Update references to renamed files in imports
echo "π Updating import statements..."
find ./ -type f -name "*.kt" -exec sed -i.bak \
-e "s/import.*\.MifosApp/import $PACKAGE.$PROJECT_NAME_CAPITALIZED/g" \
-e "s/import.*\.Mifos/import $PACKAGE.$PROJECT_NAME_CAPITALIZED/g" {} \;
}
## Function to update module names in settings.gradle.kts
#update_gradle_settings() {
# print_section "Updating Gradle Settings"
# echo "π Updating module names in settings.gradle.kts"
# local modules=("shared" "android" "desktop" "web" "ios")
#
# for module in "${modules[@]}"; do
# sed -i.bak "s/include(\":mifos-$module\")/include(\":$PROJECT_NAME_LOWERCASE-$module\")/g" settings.gradle.kts
# echo "β
Updated module: mifos-$module β $PROJECT_NAME_LOWERCASE-$module"
# done
#}
# Function to rename module directories
#rename_application_module_directories() {
# print_section "Renaming Modules"
# local modules=("shared" "android" "desktop" "web" "ios")
#
# for module in "${modules[@]}"; do
# if [ -d "mifos-$module" ]; then
# echo "π Renaming mifos-$module to $PROJECT_NAME_LOWERCASE-$module"
# mv "mifos-$module" "$PROJECT_NAME_LOWERCASE-$module"
# echo "β
Application Module directory renamed successfully"
# else
# echo "βΉοΈ Application Module mifos-$module not found, skipping"
# fi
# done
#}
#
## Function to update build.gradle.kts module references
#update_application_module_references() {
# print_section "Updating Module References"
#
# local old_modules=()
# local new_modules=()
# local modules=("shared" "android" "desktop" "web")
#
# for module in "${modules[@]}"; do
# old_modules+=("$(kebab_to_camel "mifos-$module")")
# new_modules+=("$(kebab_to_camel "$PROJECT_NAME_LOWERCASE-$module")")
# done
#
# for i in "${!old_modules[@]}"; do
# echo "π Updating references: ${old_modules[$i]} β ${new_modules[$i]}"
# find ./ -type f -name "*.gradle.kts" -exec sed -i.bak "s/projects.${old_modules[$i]}/projects.${new_modules[$i]}/g" {} \;
# done
#
# echo "β
Module references updated successfully"
#}
#
## Function to update run configurations
#update_run_configurations() {
# print_section "Updating Run Configurations"
#
# echo "π Updating run configuration files..."
#
# # Update references in XML files
# local replacements=(
# "s/name=\"mifos-/name=\"$PROJECT_NAME_LOWERCASE-/g"
# "s/module name=\"[^\"]*\.mifos-/module name=\"$PROJECT_NAME_LOWERCASE\.$PROJECT_NAME_LOWERCASE-/g"
# "s/kmp-project-template\.mifos-/$PROJECT_NAME_LOWERCASE\.$PROJECT_NAME_LOWERCASE-/g"
# "s/:mifos-desktop/:$PROJECT_NAME_LOWERCASE-desktop/g"
# "s/:mifos-web/:$PROJECT_NAME_LOWERCASE-web/g"
# "s/value=\":mifos-desktop:/value=\":$PROJECT_NAME_LOWERCASE-desktop:/g"
# "s/value=\":mifos-web:/value=\":$PROJECT_NAME_LOWERCASE-web:/g"
# )
#
# for replacement in "${replacements[@]}"; do
# find .run -type f -name "*.xml" -exec sed -i.bak "$replacement" {} \;
# done
#
# # Rename configuration files
# for config_file in .run/mifos-*.run.xml; do
# if [ -f "$config_file" ]; then
# new_config_file=$(echo "$config_file" | sed "s/mifos-/$PROJECT_NAME_LOWERCASE-/")
# echo "π Renaming run configuration: $config_file β $new_config_file"
# mv "$config_file" "$new_config_file"
# fi
# done
#
# echo "β
Run configurations updated successfully"
#}
#
## Function to update Android manifest
#update_android_manifest() {
# print_section "Updating Android Manifest"
# local manifest_path="$PROJECT_NAME_LOWERCASE-android/src/main/AndroidManifest.xml"
#
# if [ -f "$manifest_path" ]; then
# echo "π Updating package name in Android Manifest"
# sed -i.bak "s/package=\".*\"/package=\"$PACKAGE\"/" "$manifest_path"
# echo "β
Android Manifest updated successfully"
# else
# echo "βΉοΈ Android Manifest not found at $manifest_path, skipping update"
# fi
#}
# Function to clean up backup files
cleanup_backup_files() {
print_section "Final Cleanup"
echo "π§Ή Cleaning up backup files..."
find . -name "*.bak" -type f -delete
# echo "π§Ή Cleaning up .git directory..."
# rm -rf .git/
echo "β
Backup files cleaned up successfully"
}
print_final_summary(){
print_section "Summary of Changes"
echo "β
Your Kotlin Multiplatform project has been customized with the following changes:"
echo
echo "1. Package Updates:"
echo " - Base package updated to: $PACKAGE"
echo " - Compose Resources package updated"
echo " - Android Manifest package updated"
echo
echo "2. Project Naming:"
echo " - Project name set to: $PROJECT_NAME"
echo " - Application name set to: $APPNAME"
echo
echo "3. Module Updates:"
echo " - Renamed all mifos-prefixed modules"
echo " - Updated module references in Gradle files"
echo " - Updated module imports and packages"
echo
echo "4. Configuration Updates:"
echo " - Updated convention plugin IDs"
echo " - Updated run configurations"
echo " - Updated iOS bundle identifiers (if applicable)"
echo
echo "5. Code Updates:"
echo " - Renamed Mifos-prefixed files to $PROJECT_NAME_CAPITALIZED"
echo " - Updated package declarations and imports"
echo " - Updated typesafe accessors:"
echo
echo "π Project customization completed successfully!"
}
# Main execution function
main() {
print_section "Starting Project Customization"
echo "Package: $PACKAGE"
echo "Project Name: $PROJECT_NAME"
echo "Application Name: $APPNAME"
# Core updates
update_plugin_ids
update_plugin_patterns
update_compose_resources
# update_application_class
update_ios_config
# Process modules
process_module_content
rename_files
# Module updates
# update_gradle_settings
# rename_application_module_directories
# update_application_module_references
# update_run_configurations
# Final updates
# update_android_manifest
cleanup_backup_files
# Print summary
print_final_summary
}
# Execute main function
main