1
+ import java.nio.file.*
2
+ import java.nio.charset.StandardCharsets
3
+ import java.util.regex.Pattern
4
+
5
+ REPO_ROOT = " /Users/rene/dev/elastic/elasticsearch/plugins"
6
+ VERSION_PROPS = REPO_ROOT + " /../build-tools-internal/version.properties"
7
+
8
+ def parseGradleFiles (Path directory ) {
9
+ def pattern = Pattern . compile(/ (\w +)\s +['"](\w [^'"]+):([^'"]+):([^'"]+)['"]/ )
10
+ def dependencies = []
11
+
12
+ Files . walk(directory). each { path ->
13
+ if (Files . isRegularFile(path) && path. toString(). endsWith(' .gradle' ) && path. toString(). contains(" plugins/examples" ) == false ){
14
+ def lines = Files . readAllLines(path, StandardCharsets . UTF_8 )
15
+ lines. each { line ->
16
+ def matcher = pattern. matcher(line)
17
+ if (matcher. find()) {
18
+ def configuration = matcher. group(1 )
19
+ def group = matcher. group(2 )
20
+ def name = matcher. group(3 )
21
+ def version = matcher. group(4 )
22
+ dependencies << [file : path. toString(), configuration : configuration, group : group, name : name, version : version]
23
+ }
24
+ }
25
+ }
26
+ }
27
+ return dependencies
28
+ }
29
+
30
+ String convertToVersionCatalogEntry (def dependencies ) {
31
+ Set<String > versions = new TreeSet<> ()
32
+ Set<String > entries = new TreeSet<> ()
33
+
34
+ }
35
+
36
+ def resolveVersion (Properties props , String versionString ) {
37
+ println " Resolving version: ${ versionString} "
38
+ if (versionString. startsWith(" \$ {versions." )) {
39
+ def versionId = versionString. substring(versionString. indexOf(' .' ) + 1 , versionString. indexOf(' }' ))
40
+ if (props. containsKey(versionId)) {
41
+ return props. getProperty(versionId)
42
+ } else {
43
+ println " unknown version ${ versionString} found in build.gradle file. Please add it to the version.properties file."
44
+ return versionId
45
+ }
46
+ }
47
+
48
+ return versionString
49
+ }
50
+
51
+
52
+ Properties loadVersionProperties () {
53
+ def properties = new Properties ()
54
+ def file = new File (VERSION_PROPS )
55
+ if (! file. exists()) {
56
+ println " The properties file '${ VERSION_PROPS} ' does not exist."
57
+ return null
58
+ }
59
+ file. withInputStream { stream ->
60
+ properties. load(stream)
61
+ }
62
+ properties. each { key , value ->
63
+ println " Loaded version property: ${ key} = ${ value} "
64
+ }
65
+ return properties
66
+ }
67
+
68
+ def convertToCamelCase (String input ) {
69
+ def parts = input. split(' -' )
70
+ def camelCaseString = parts[0 ]
71
+ parts. tail(). each { part ->
72
+ // for now skip camel casing
73
+ // camelCaseString += part.capitalize()
74
+ camelCaseString + = part
75
+ }
76
+ return camelCaseString
77
+ }
78
+
79
+ String calculateVersionRef (String libraryName , Map<String , String > versionCatalog , Properties properties , String version ) {
80
+ // String versionRefName = convertToCamelCase(libraryName)
81
+ String versionRefName = libraryName
82
+
83
+ if (versionCatalog. containsKey(versionRefName)) {
84
+ def existingMajor = versionCatalog[libraryName]. split(" \\ ." )[0 ] as int
85
+ def newMajor = version. split(" \\ ." )[0 ] as int
86
+ println " existingMajor: ${ existingMajor} , newMajor: ${ newMajor} "
87
+
88
+ if (newMajor > existingMajor) {
89
+ return versionRefName + newMajor
90
+ }
91
+ }
92
+ return versionRefName
93
+ }
94
+
95
+ def checkOptimizations (Map<String , String > versionCatalog , Properties versionProperties ) {
96
+ def simplifications = [:]
97
+ versionCatalog. each { givenKey , givenVersion ->
98
+ def simpleKey = givenKey. contains(" -" ) ? givenKey. split(' -' )[0 ] : givenKey
99
+ def candidates = versionCatalog. findAll {k , v -> givenKey != k && k. startsWith(" ${ simpleKey} -" )}
100
+ if (candidates. size() == 0 && versionProperties[simpleKey] != null ) {
101
+ assert versionProperties[simpleKey] == givenVersion
102
+ simplifications[givenKey] = simpleKey
103
+ } else {
104
+ candidates. each {candidateKey , candidateVersion ->
105
+ if (candidateVersion == givenVersion) {
106
+ simplifications[candidateKey] = simpleKey
107
+ }
108
+ }
109
+ }
110
+
111
+ if (simplifications[givenKey] == null ){
112
+ def converted = convertToCamelCase(givenKey)
113
+
114
+ if (givenKey != converted) {
115
+ simplifications[givenKey] = converted
116
+ }
117
+ }
118
+ }
119
+
120
+ return simplifications
121
+ }
122
+
123
+
124
+ def parseValue (value ) {
125
+ if (value. startsWith(' "' ) && value. endsWith(' "' )) {
126
+ return value[1 .. -2 ] // String value
127
+ } else if (value ==~ / \d +/ ) {
128
+ return value. toInteger() // Integer value
129
+ } else if (value ==~ / \d +\.\d +/ ) {
130
+ return value. toDouble() // Double value
131
+ } else if (value == ' true' || value == ' false' ) {
132
+ return value. toBoolean() // Boolean value
133
+ } else if (value. startsWith(' [' ) && value. endsWith(' ]' )) {
134
+ return value[1 .. -2 ]. split(' ,' ). collect { parseValue(it. trim()) } // Array value
135
+ } else {
136
+ return value // Default to string if not matched
137
+ }
138
+ }
139
+
140
+ def parseTomlFile (filePath ) {
141
+ def tomlMap = [:]
142
+ def currentSection = null
143
+ def file = new File (filePath)
144
+
145
+ file. eachLine { line ->
146
+ line = line. trim()
147
+
148
+ if (line. startsWith(' #' ) || line. isEmpty()) {
149
+ // Skip comments and empty lines
150
+ return
151
+ }
152
+
153
+ if (line. startsWith(' [' ) && line. endsWith(' ]' )) {
154
+ // New section
155
+ currentSection = line[1 .. -2 ]
156
+ tomlMap[currentSection] = [:]
157
+ } else if (line. contains(' =' )) {
158
+ // Key-value pair
159
+ def (key, value) = line. split(' =' , 2 ). collect { it. trim() }
160
+ value = parseValue(value)
161
+ if (currentSection) {
162
+ tomlMap[currentSection][key] = value
163
+ } else {
164
+ tomlMap[key] = value
165
+ }
166
+ }
167
+ }
168
+
169
+ return tomlMap
170
+ }
171
+
172
+ def main () {
173
+ // def directoryPath = System.console().readLine('Enter the directory path to search for *.gradle files: ').trim()
174
+ // def directory = Paths.get("directoryPath")
175
+ def directory = Paths . get(REPO_ROOT )
176
+
177
+ if (! Files . exists(directory) || ! Files . isDirectory(directory)) {
178
+ println " The directory '${ directoryPath} ' does not exist or is not a directory."
179
+ return
180
+ }
181
+
182
+ def dependencies = parseGradleFiles(directory)
183
+
184
+ def librariesCatalog = [:]
185
+ def versionsCatalog = [:]
186
+
187
+ Properties versionProperties = loadVersionProperties()
188
+ println " Version Properties: ${ versionProperties.contains('junit')} "
189
+ if (dependencies) {
190
+ def depsByFile = dependencies. groupBy {it. file}
191
+ depsByFile. each { file , deps ->
192
+ println " File: ${ file} "
193
+ deps. each { dep ->
194
+ def effectiveVersion = resolveVersion(versionProperties, dep. version)
195
+ def versionRefName = calculateVersionRef(dep. name, versionsCatalog, versionProperties, effectiveVersion)
196
+ versionsCatalog. put(versionRefName, effectiveVersion)
197
+ depLibraryEntry = [group : dep. group, name : dep. name, version :versionRefName]
198
+ println " \" ${ dep.group} :${ dep.name} :${ dep.version} \" -> \" ${ depLibraryEntry} \" "
199
+ if (librariesCatalog. containsKey(versionRefName)) {
200
+ assert librariesCatalog[versionRefName] == depLibraryEntry
201
+ } else {
202
+ librariesCatalog. put(versionRefName, depLibraryEntry)
203
+ }
204
+ }
205
+
206
+ println " "
207
+ }
208
+
209
+ println " libraries Catalog versions"
210
+
211
+ librariesCatalog. each { key , value ->
212
+ println " ${ key} = ${ value} "
213
+ }
214
+
215
+ println " Version Catalog libraries"
216
+ versionsCatalog. each { key , value ->
217
+ println " ${ key} = ${ value} "
218
+ }
219
+ println " Found ${ dependencies.size()} dependencies in ${ depsByFile.size()} files."
220
+
221
+ } else {
222
+ println " No dependencies found."
223
+ }
224
+
225
+ def versionOptimizations = checkOptimizations(versionsCatalog, versionProperties)
226
+
227
+ versionOptimizations. each { given , simplified ->
228
+ println " $given -> $simplified "
229
+ println " ${ versionsCatalog[simplified]} "
230
+ if (versionsCatalog[simplified] == null ) {
231
+ versionsCatalog[simplified] = versionsCatalog[given]
232
+ }
233
+ versionsCatalog. remove(given)
234
+ }
235
+
236
+ librariesCatalog. each { key , value ->
237
+ def simplified = versionOptimizations[key]
238
+ if (simplified != null ) {
239
+ librariesCatalog[key]. version = simplified
240
+ }
241
+ }
242
+
243
+ println " \n\n versions: "
244
+ versionsCatalog. sort(). each { key , value ->
245
+ println " ${ key} = \" ${ value} \" "
246
+ }
247
+
248
+ librariesCatalog. sort()
249
+ println " \n\n libraries: "
250
+ librariesCatalog. sort(). each { k , v ->
251
+ println " ${ k} = { group = \" ${ v['group']} \" , name = \" ${ v['name']} \" , version.ref = \" ${ v['version']} \" } "
252
+ }
253
+
254
+ // Example usage
255
+ def tomlFilePath = ' /Users/rene/dev/elastic/elasticsearch/gradle/versions.toml'
256
+ def parsedToml = parseTomlFile(tomlFilePath)
257
+
258
+ // Access parsed data
259
+ existingVersions = parsedToml[' versions' ]
260
+
261
+ // println "\n\nExisting versions:"
262
+ // existingVersions.forEach { key, value ->
263
+ // println "${key} = ${value}"
264
+ // }
265
+
266
+ // existingLibs = parsedToml['libraries']
267
+
268
+ // existingLibs.forEach { key, value ->
269
+ // println "${key} = ${value}"
270
+ // }
271
+
272
+ def finalVersions = [:]
273
+ def finalLibraries = [:]
274
+
275
+ existingVersions. each { key , value ->
276
+ finalVersions[key] = value
277
+ if (versionsCatalog. containsKey(key)) {
278
+ assert value == versionsCatalog[key]
279
+ versionsCatalog. remove(key)
280
+ }
281
+ }
282
+ finalVersions. putAll(versionsCatalog)
283
+
284
+
285
+ println " \n\n [versions]"
286
+ finalVersions. sort(). each { key , value ->
287
+ println " ${ key} = \" ${ value} \" "
288
+ }
289
+
290
+ def existingLibs = parsedToml[' libraries' ]
291
+ existingLibs. each { key , value ->
292
+ finalLibraries[key] = value
293
+ if (librariesCatalog[key] != null ) {
294
+ def newValue = librariesCatalog[key]
295
+ assert value == " { group = \" ${ newValue['group']} \" , name = \" ${ newValue['name']} \" , version.ref = \" ${ newValue['version']} \" }"
296
+ librariesCatalog. remove(key)
297
+ }
298
+ }
299
+ finalLibraries. putAll(librariesCatalog)
300
+
301
+ println " \n\n [libraries]"
302
+ finalLibraries. sort(). each { key , value ->
303
+ if (value instanceof Map ) {
304
+ println " ${ key} = { group = \" ${ value['group']} \" , name = \" ${ value['name']} \" , version.ref = \" ${ value['version']} \" }"
305
+ } else if (value. startsWith(" {" )) {
306
+ println " ${ key} = $value "
307
+ } else {
308
+ println " ${ key} = \" $value \" "
309
+ }
310
+ }
311
+
312
+ // println "Title: ${parsedToml['title']}"
313
+ // println "Owner Name: ${parsedToml['versions']['name']}"
314
+ // println "Database Server: ${parsedToml['database']['server']}"
315
+ // println "Database Ports: ${parsedToml['database']['ports']}"
316
+
317
+ }
318
+
319
+ main()
0 commit comments