11package io.github.hosseinkarami_dev.near.rpc.generator
22
33import ModelGenerator
4+ import java.nio.file.Files
5+ import java.nio.file.Path
6+ import java.nio.file.Paths
47import kotlinx.cli.ArgParser
58import kotlinx.cli.ArgType
69import kotlinx.cli.default
710import java.io.File
11+ import kotlin.system.exitProcess
812
913fun main (args : Array <String >) {
1014 val parser = ArgParser (" generator" )
1115
12- val rootDir = System .getenv(" GITHUB_WORKSPACE" ) ? : File (System .getProperty(" user.dir" ), " .." ).canonicalPath
16+ val gw = System .getenv(" GITHUB_WORKSPACE" )
17+ val rootDirStr = gw ? : File (System .getProperty(" user.dir" ), " .." ).canonicalPath
18+ println (" >>> rootDir = $rootDirStr " )
1319
1420 val openApiUrl by parser.option(
1521 ArgType .String ,
1622 fullName = " openapi-url" ,
1723 description = " URL to the OpenAPI specification"
18- )
19- // .default("https://raw.githubusercontent.com/near/nearcore/refs/heads/2.7.0/chain/jsonrpc/openapi/openapi.json")
20- // .default("https://raw.githubusercontent.com/near/nearcore/refs/heads/2.8.0/chain/jsonrpc/openapi/openapi.json")
21- .default(" https://raw.githubusercontent.com/near/nearcore/refs/heads/master/chain/jsonrpc/openapi/openapi.json" )
24+ ).default(" https://raw.githubusercontent.com/near/nearcore/refs/heads/master/chain/jsonrpc/openapi/openapi.json" )
2225
2326 val modelsOut by parser.option(
2427 ArgType .String ,
2528 fullName = " models-out" ,
2629 description = " Output directory for generated models"
27- ).default(" $rootDir /models/src/main/kotlin/ " )
30+ ).default(" $rootDirStr /models/src/main/kotlin" )
2831
2932 val clientOut by parser.option(
3033 ArgType .String ,
3134 fullName = " client-out" ,
3235 description = " Output directory for generated client"
33- ).default(" $rootDir /client/src/main/kotlin/ " )
36+ ).default(" $rootDirStr /client/src/main/kotlin" )
3437
3538 parser.parse(args)
3639
37- val spec = fetchOpenApiSpec(openApiUrl)
40+ println (" >>> modelsOut = $modelsOut " )
41+ println (" >>> clientOut = $clientOut " )
42+ println (" >>> cwd = ${File (" ." ).absolutePath} " )
43+
44+ // ensure base output directories exist
45+ try {
46+ val modelsOutPath: Path = Paths .get(modelsOut)
47+ val clientOutPath: Path = Paths .get(clientOut)
48+
49+ println (" Creating base output directories (if missing)..." )
50+ Files .createDirectories(modelsOutPath)
51+ Files .createDirectories(clientOutPath)
52+ println (" Base dirs exist: ${Files .exists(modelsOutPath)} , ${Files .exists(clientOutPath)} " )
53+ println (" ModelsOut writable: ${Files .isWritable(modelsOutPath)} " )
54+ } catch (ex: Exception ) {
55+ System .err.println (" Failed to create base output dirs: ${ex.message} " )
56+ ex.printStackTrace()
57+ exitProcess(2 )
58+ }
3859
3960 val modelPackage = " io.github.hosseinkarami_dev.near.rpc.models"
4061 val clientPackage = " io.github.hosseinkarami_dev.near.rpc.client"
4162 val serializerPackage = modelPackage.replace(" .models" , " .serializers" )
4263
43- val serializerFiles = File (modelsOut + serializerPackage.replace(" ." , " /" ))
44- val modelFiles = File (modelsOut + modelPackage.replace(" ." , " /" ))
45- val nearClientFile = File (clientOut + clientPackage.replace(" ." , " /" ))
64+ // package directories (inside the base output dirs)
65+ val serializerDir = Paths .get(modelsOut, * serializerPackage.split(" ." ).toTypedArray())
66+ val modelDir = Paths .get(modelsOut, * modelPackage.split(" ." ).toTypedArray())
67+ val nearClientDir = Paths .get(clientOut, * clientPackage.split(" ." ).toTypedArray())
4668
47- serializerFiles.mkdirs()
48- modelFiles.mkdirs()
49- nearClientFile.mkdirs()
69+ try {
70+ println (" Creating package directories..." )
71+ Files .createDirectories(serializerDir)
72+ Files .createDirectories(modelDir)
73+ Files .createDirectories(nearClientDir)
74+ println (" serializerDir exists: ${Files .exists(serializerDir)} " )
75+ println (" modelDir exists: ${Files .exists(modelDir)} " )
76+ println (" nearClientDir exists: ${Files .exists(nearClientDir)} " )
77+ } catch (ex: Exception ) {
78+ System .err.println (" Failed to create package directories: ${ex.message} " )
79+ ex.printStackTrace()
80+ exitProcess(3 )
81+ }
82+
83+ // debug: list a bit of tree
84+ println (" Listing models tree (first 200 lines):" )
85+ File (modelsOut).walkTopDown().take(200 ).forEach { println (it.absolutePath) }
5086
51- serializerFiles.takeIf { it.exists() }?.listFiles()?.forEach { it.delete() }
52- modelFiles.takeIf { it.exists() }?.listFiles()?.forEach { it.delete() }
87+ // fetch spec (wrap to log errors)
88+ val spec = try {
89+ fetchOpenApiSpec(openApiUrl)
90+ } catch (ex: Exception ) {
91+ System .err.println (" Failed to fetch openapi spec: ${ex.message} " )
92+ ex.printStackTrace()
93+ exitProcess(4 )
94+ }
5395
54- nearClientFile.delete()
96+ // cleanup previous generated files if any (only inside package dirs)
97+ try {
98+ serializerDir.toFile().listFiles()?.forEach {
99+ println (" Deleting old file: ${it.absolutePath} " )
100+ it.delete()
101+ }
102+ modelDir.toFile().listFiles()?.forEach {
103+ println (" Deleting old file: ${it.absolutePath} " )
104+ it.delete()
105+ }
106+ // remove nearClient single file if existed
107+ nearClientDir.toFile().listFiles()?.forEach {
108+ println (" Deleting old client file: ${it.absolutePath} " )
109+ it.delete()
110+ }
111+ } catch (ex: Exception ) {
112+ println (" Cleanup warning: ${ex.message} " )
113+ }
55114
56- ModelGenerator .generateAll(
57- spec = spec,
58- output = File (modelsOut),
59- serializerPackage = serializerPackage,
60- packageName = modelPackage
61- ) { sealedClasses ->
115+ // call generators (wrap to catch exceptions)
116+ try {
117+ ModelGenerator .generateAll(
118+ spec = spec,
119+ output = File (modelsOut),
120+ serializerPackage = serializerPackage,
121+ packageName = modelPackage
122+ ) { sealedClasses ->
62123 SerializerGenerator .generateFromSealedInfos(
63124 sealedInfos = sealedClasses,
64125 serializerPackage = serializerPackage,
65126 output = File (modelsOut)
66127 )
128+ }
129+ } catch (ex: Exception ) {
130+ System .err.println (" Model generation failed: ${ex.message} " )
131+ ex.printStackTrace()
132+ exitProcess(5 )
133+ }
134+
135+ try {
136+ ClientGenerator .generateNearClientFile(
137+ spec = spec,
138+ output = File (clientOut),
139+ clientPackage = clientPackage,
140+ modelsPackage = modelPackage
141+ )
142+ } catch (ex: Exception ) {
143+ System .err.println (" Client generation failed: ${ex.message} " )
144+ ex.printStackTrace()
145+ exitProcess(6 )
67146 }
68147
69- ClientGenerator .generateNearClientFile(
70- spec = spec,
71- output = File (clientOut),
72- clientPackage = clientPackage,
73- modelsPackage = modelPackage
74- )
75- }
148+ // create a marker file to prove writing succeeded
149+ try {
150+ val marker = Paths .get(modelsOut, " __GEN_OK__" )
151+ Files .writeString(marker, " generated at ${java.time.Instant .now()} \n " )
152+ println (" Wrote marker: ${marker.toAbsolutePath()} " )
153+ } catch (ex: Exception ) {
154+ System .err.println (" Failed to write marker file: ${ex.message} " )
155+ ex.printStackTrace()
156+ }
157+
158+ println (" Generation finished. final listing (first 200 items):" )
159+ File (modelsOut).walkTopDown().take(200 ).forEach { println (it.absolutePath) }
160+
161+ println (" ✅ Done" )
162+ }
0 commit comments