xref: /aosp_15_r20/external/icu/icu4j/maven-migration/toMaven.sh (revision 0e209d3975ff4a8c132096b14b0e9364a753506e)
1#!/usr/bin/env bash
2# Copyright (C) 2023 and later: Unicode, Inc. and others.
3# License & terms of use: http://www.unicode.org/copyright.html
4
5# Move the sources from main/classes and main/tests into a maven structure
6# - `main/classes/foo/src/java` go to `foo/src/main`, then split into `java` and `resources`
7# - `main/tests/foo/src/java` go to `foo/src/test`, then split into `java` and `resources`
8# - `main/tests/foo/src/META-INF` goes to ... `resources`
9#
10# From this:
11# classes/
12#   <module>/
13#     src/
14# test/
15#   <module>/
16#     src/
17#
18# To this (standard maven structure):
19# <module>/
20#   main/
21#     src/
22#       java/
23#       resources/
24#   test/
25#     src/
26#       java/
27#       resources/
28#
29# Then we cleanup older Eclipse project & launcher files, ant scripts, manifest.stub
30
31function safeMkdir() {
32  mkdir -p "$1"
33}
34
35function moveOrRename() {
36  local SRC=$1
37  local DEST=$2
38
39  mv "$SRC" "$DEST"
40}
41
42function rmDirIfExists() {
43  [ -d "$1" ] && rm -fr "$1"
44}
45
46function rmFileIfExists() {
47  [ -f "$1" ] && rm "$1"
48}
49
50function copyRecursive() {
51  local SRC=$1
52  local DEST=$2
53
54  cp -R "$SRC" "$DEST"
55}
56
57function safeMoveDir() {
58  local FOLDER_NAME=$1
59  local FROM_FOLDER=$2
60  local TO_FOLDER=$3
61
62  if [ ! -d "$FROM_FOLDER/$FOLDER_NAME" ]; then
63    echo "  No '$FROM_FOLDER/$FOLDER_NAME' to move."
64    return
65  fi
66  if [ -e "$TO_FOLDER/$FOLDER_NAME" ]; then
67    echo "  Error: folder '$TO_FOLDER/$FOLDER_NAME' already exists!"
68    exit
69  else
70    safeMkdir $TO_FOLDER
71    moveOrRename $FROM_FOLDER/$FOLDER_NAME $TO_FOLDER/
72    echo "  Moving '$FOLDER_NAME' folder from '$FROM_FOLDER' to '$TO_FOLDER'"
73  fi
74}
75
76function rmFileGlobInDir() {
77  local DIR=$1
78  local PATTERN=$2
79
80  find "$DIR" -type f -name "$PATTERN" -exec rm {} \;
81}
82
83function keepOnlyFileGlobInDir() {
84  local DIR=$1
85  local PATTERN=$2
86
87  find "$DIR" -type f -not -name "$PATTERN" -exec rm {} \;
88}
89
90# Split the content of the `java` foldert into `java` and `resources`, the way maven wants it
91function splitJavaToResources() {
92  # Should point to the folder containing `java`, either main/ or test/
93  local BASE_FOLDER=$1
94
95  echo "  Splitting '$BASE_FOLDER/java/' into '$BASE_FOLDER/java/' and '$BASE_FOLDER/resources/'"
96  # copy `java` to `resources`
97  copyRecursive $BASE_FOLDER/java/ $BASE_FOLDER/resources/
98  # delete all not `.java` from `java`
99  keepOnlyFileGlobInDir $BASE_FOLDER/java/ *.java
100  # delete all `.java` from `resources`
101  rmFileGlobInDir $BASE_FOLDER/resources/  *.java
102}
103
104function removeEclipseProjectFiles() {
105  # Should point to the old folder (to be moved), containing the eclipse / ant files
106  local BASE_FOLDER=$1
107
108  # Cleanup Eclipse project & launcher files, ant projects, other stuff
109  # Eclipse
110  rmDirIfExists  "$BASE_FOLDER/.externalToolBuilders/"
111  rmDirIfExists  "$BASE_FOLDER/.settings/"
112  rmFileIfExists "$BASE_FOLDER/.project"
113  rmFileIfExists "$BASE_FOLDER/.classpath"
114  # Ant
115  rmFileIfExists "$BASE_FOLDER/build.properties"
116  rmFileIfExists "$BASE_FOLDER/build.xml"
117  rmFileIfExists "$BASE_FOLDER/manifest.stub"
118  rmFileIfExists "$BASE_FOLDER/findbugs-exclude.xml"
119  find $BASE_FOLDER/ -type f -name '*.launch' -exec rm {} \;
120}
121
122# Takes a folder as parameter and removes the all the empty sub-folders.
123function removeEmptyFolders() {
124  local BASE_FOLDER=$1
125  # `find -type d .` finds all subfolders, empty or not.
126  # We can't just force delete (-r), as that would also delete non-empty folders.
127  # And the find iteration is not children first, but parent first.
128  # If I call this with `main/classes/` then I need a loop:
129  # loop 1:
130  #   rm `main/classes/` => FAILS, not empty
131  #   rm `main/classes/core/` => FAILS, not empty
132  #   rm `main/classes/core/src/` => OK
133  # loop 2:
134  #   rm `main/classes/` => FAILS, not empty
135  #   rm `main/classes/core/` => OK
136  # loop 3:
137  #   rm `main/classes/` => OK
138  # If there is any file left in some folder, that (and the parent folders) are not deleted.
139  # That's why we loop here (although 15 might be a bit much :-)
140  for ((n = 0; n < 15; n++)) do
141    find $BASE_FOLDER -type d -exec rm -d {} \; 2> /dev/null
142  done
143}
144
145function moveMainModuleToMaven() {
146  # 1. $1: component name (core, charset, etc)
147  local MODULE_NAME=$1
148  # 2. folder name in the pre-maven structure (`classes` or `tests`)
149  local SRC_TYPE=$2
150  # 3. folder name in the maven standard structure (`main` or `test`)
151  local TRG_TYPE=$3
152
153  if [ ! -d main/$SRC_TYPE/$MODULE_NAME ]; then
154    echo "  Module '$MODULE_NAME' does not have '$SRC_TYPE' to move to '$TRG_TYPE'"
155    return
156  fi
157
158  safeMoveDir com      main/$SRC_TYPE/$MODULE_NAME/src main/$MODULE_NAME/src/$TRG_TYPE/java
159  splitJavaToResources main/$MODULE_NAME/src/$TRG_TYPE
160  safeMoveDir META-INF main/$SRC_TYPE/$MODULE_NAME/src main/$MODULE_NAME/src/$TRG_TYPE/resources
161
162  removeEclipseProjectFiles main/$SRC_TYPE/$MODULE_NAME
163
164  # Remove the original (pre-maven) folders that were left empty after we moved stuff out
165  # For example if all we had was source code + Eclipse files the folder will be left empty.
166  # e.g. main/classes/collate
167  echo "  Remove all empty pre-maven folders from 'main/$SRC_TYPE/$MODULE_NAME'"
168  removeEmptyFolders main/$SRC_TYPE/$MODULE_NAME
169
170  # Remove folders that didn't receive any content in the new structure.
171  # For example when we copy the `java` folder to `resources`, then remove
172  # all the *.java files, we might end up with empty `resources` folder
173  # if there was no data file mixed-in with the code to begin with.
174  # e.g. main/collate/src/main
175  echo "  Remove all empty post-maven folders from 'main/$MODULE_NAME/src/$TRG_TYPE'"
176  removeEmptyFolders main/$MODULE_NAME/src/$TRG_TYPE
177}
178
179function mainModuleToMaven() {
180  echo "Migrating $1 to maven"
181  moveMainModuleToMaven $1 classes main
182  moveMainModuleToMaven $1 tests test
183  safeMkdir main/$MODULE_NAME/src/main/resources/
184  ln -s ../../../../../../LICENSE main/$MODULE_NAME/src/main/resources/LICENSE
185}
186
187function simpleModuleToMaven() {
188  # 1. $1: component name (core, charset, etc)
189  local MODULE_NAME=$1
190  local LICENSE_PATH=$2
191  echo "Migrating $MODULE_NAME to maven"
192
193  safeMoveDir com $MODULE_NAME/src $MODULE_NAME/src/main/java
194  splitJavaToResources $MODULE_NAME/src/main
195
196  removeEclipseProjectFiles $MODULE_NAME
197
198  safeMkdir $MODULE_NAME/src/main/resources/
199  ln -s $LICENSE_PATH $MODULE_NAME/src/main/resources/LICENSE
200
201  echo "  Remove empty folders from '$MODULE_NAME'"
202  removeEmptyFolders $MODULE_NAME
203}
204
205function moveCoreTestFileToCommon() {
206  local FOLDER_NAME=$1
207  local FILE_NAME=$2
208  safeMkdir $COMMON_TEST_FOLDER/$FOLDER_NAME
209  moveOrRename $CORE_TEST_FOLDER/$FOLDER_NAME/$FILE_NAME $COMMON_TEST_FOLDER/$FOLDER_NAME/
210}
211
212function moveCircDepTestOutOfCore() {
213  export CORE_TEST_FOLDER=main/core/src/test/java/com/ibm/icu/dev/test
214  export COMMON_TEST_FOLDER=main/common_tests/src/test/java/com/ibm/icu/dev/test
215
216  safeMkdir $CORE_TEST_FOLDER
217
218  moveCoreTestFileToCommon calendar DataDrivenCalendarTest.java
219  moveCoreTestFileToCommon format CompactDecimalFormatTest.java
220  moveCoreTestFileToCommon format DataDrivenFormatTest.java
221  moveCoreTestFileToCommon format DateFormatTest.java
222  moveCoreTestFileToCommon format IntlTestDecimalFormatSymbolsC.java
223  moveCoreTestFileToCommon format IntlTestDecimalFormatAPIC.java
224  moveCoreTestFileToCommon format MeasureUnitTest.java
225  moveCoreTestFileToCommon format NumberFormatDataDrivenTest.java
226  moveCoreTestFileToCommon format NumberFormatRegressionTest.java
227  moveCoreTestFileToCommon format NumberFormatSpecificationTest.java
228  moveCoreTestFileToCommon format NumberFormatTest.java
229  moveCoreTestFileToCommon format NumberRegressionTests.java
230  moveCoreTestFileToCommon format PluralRangesTest.java
231  moveCoreTestFileToCommon format PluralRulesTest.java
232  moveCoreTestFileToCommon format RbnfTest.java
233  moveCoreTestFileToCommon format TestMessageFormat.java
234  moveCoreTestFileToCommon format TimeZoneFormatTest.java
235  moveCoreTestFileToCommon message2 Mf2FeaturesTest.java
236  moveCoreTestFileToCommon normalizer BasicTest.java
237  moveCoreTestFileToCommon number ModifierTest.java
238  moveCoreTestFileToCommon number NumberFormatterApiTest.java
239  moveCoreTestFileToCommon number NumberParserTest.java
240  moveCoreTestFileToCommon number NumberPermutationTest.java
241  moveCoreTestFileToCommon number NumberRangeFormatterTest.java
242  moveCoreTestFileToCommon number PatternStringTest.java
243  moveCoreTestFileToCommon number PropertiesTest.java
244  moveCoreTestFileToCommon rbbi LSTMBreakEngineTest.java
245  moveCoreTestFileToCommon serializable CalendarHandler.java
246  moveCoreTestFileToCommon serializable CompatibilityTest.java
247  moveCoreTestFileToCommon serializable CoverageTest.java
248  moveCoreTestFileToCommon serializable ExceptionHandler.java
249  moveCoreTestFileToCommon serializable FormatHandler.java
250  moveCoreTestFileToCommon serializable SerializableChecker.java
251  moveCoreTestFileToCommon serializable SerializableTestUtility.java
252  moveCoreTestFileToCommon serializable SerializableWriter.java
253  moveCoreTestFileToCommon stringprep TestIDNARef.java
254  moveCoreTestFileToCommon stringprep TestStringPrep.java
255  moveCoreTestFileToCommon util CurrencyTest.java
256  moveCoreTestFileToCommon util ICUResourceBundleTest.java
257  moveCoreTestFileToCommon util ICUServiceTest.java
258  moveCoreTestFileToCommon util LocaleDataTest.java
259  moveCoreTestFileToCommon util ULocaleTest.java
260
261  # Looks like the packaging project was already some kind of test for how things come together.
262  # Should we move all the files in this project instead of common_tests?
263  moveOrRename main/tests/packaging/src/com/ibm/icu/dev/test/* $COMMON_TEST_FOLDER/
264  removeEclipseProjectFiles main/tests/packaging
265
266  # At this point this folder should be empty
267  # So remove if empty (-d) should work
268  rm -d main/core/src/test/java/com/ibm/icu/dev/test/serializable
269}
270
271function moveFilesInTools() {
272  local TOOLS_SRC_ROOT_FOLDER=tools/misc/src/main/java/com/ibm/icu/dev/tool
273  local TOOLS_SRC_SHARED_SUBFOLDER=tools/misc/src/main/java/com/ibm/icu/dev/tool/shared
274
275  safeMkdir $TOOLS_SRC_SHARED_SUBFOLDER
276  moveOrRename $TOOLS_SRC_ROOT_FOLDER/UOption.java $TOOLS_SRC_SHARED_SUBFOLDER/
277}
278
279# ===============================================================
280# Here starts the real script execution
281
282if [ -f "main/core/pom.xml" ]; then
283  echo "ERROR: looks like the structure was already migrated to maven?"
284  exit
285fi
286if [ ! -f "main/classes/core/build.xml" ]; then
287  echo "ERROR: the current folder when running this script should be <icu_root>/icu4j"
288  echo "It is currently $PWD."
289  exit
290fi
291
292# Copy over most files from `maven-migration` dir needed for Maven build...
293MVN_MIG_DIR="$(dirname "${BASH_SOURCE[0]}")"
294copyRecursive ${MVN_MIG_DIR}/* .
295# ...but don't copy files that are only used for migration
296rmFileIfExists README_MAVEN.md
297rmFileIfExists toMaven.sh
298rmFileIfExists unpack_jars.sh
299
300# Migrate the modules in icu4j/main, which have code (in main/classes) & unit tests (in main/test)
301echo "===================================="
302echo "==== Migrating the main modules ===="
303echo "===================================="
304mainModuleToMaven core
305mainModuleToMaven langdata
306mainModuleToMaven charset
307mainModuleToMaven collate
308mainModuleToMaven localespi
309mainModuleToMaven translit
310# main only
311mainModuleToMaven currdata
312mainModuleToMaven regiondata
313# test only
314mainModuleToMaven framework
315
316# Migrate the modules in icu4j, which have only code and no unit tests
317echo "===================================="
318echo "==== Migrating the root modules ===="
319echo "===================================="
320simpleModuleToMaven demos        ../../../../../LICENSE
321simpleModuleToMaven samples      ../../../../../LICENSE
322simpleModuleToMaven tools/build  ../../../../../../LICENSE
323simpleModuleToMaven tools/misc   ../../../../../../LICENSE
324
325echo "================================================================================="
326echo "==== Moving core unit tests that depend on non-core (circular dependencies) ====="
327echo "================================================================================="
328
329moveCircDepTestOutOfCore
330
331echo "================================================================="
332echo "==== Move files to resolve dependency cycles in tools, etc. ====="
333echo "================================================================="
334
335moveFilesInTools
336
337# Cleanup of Ant-specific dirs & prototype Maven build dirs
338rmDirIfExists  "$BASE_FOLDER/maven/"
339rmDirIfExists  "$BASE_FOLDER/maven-build/"
340
341# Some final cleanup for any empty folders
342removeEmptyFolders main/classes
343removeEmptyFolders main/tests
344
345# Unpack the CLDR data from the shared .jar files
346${MVN_MIG_DIR}/unpack_jars.sh
347
348echo DONE
349