1
+ import kotlinx.coroutines.CoroutineScope
2
+ import kotlinx.coroutines.Dispatchers
3
+ import kotlinx.coroutines.launch
4
+ import kotlinx.coroutines.runBlocking
5
+ import java.io.FileNotFoundException
6
+ import java.io.Reader
7
+ import kotlin.time.Duration
8
+
1
9
plugins {
2
10
id(" usvm.kotlin-conventions" )
3
11
}
@@ -22,3 +30,136 @@ dependencies {
22
30
// Use it to export all modules to all
23
31
testImplementation(" org.burningwave:core:12.62.7" )
24
32
}
33
+
34
+ val generateSdkIR by tasks.registering {
35
+ group = " build"
36
+ description = " Generates SDK IR using ArkAnalyzer."
37
+ doLast {
38
+ val envVarName = " ARKANALYZER_DIR"
39
+
40
+ val arkAnalyzerPath = System .getenv(envVarName) ? : run {
41
+ error(" Please, set $envVarName environment variable." )
42
+ }
43
+ val arkAnalyzerDir = rootDir.resolve(arkAnalyzerPath)
44
+
45
+ val scriptSubPath = " src/save/serializeArkIR"
46
+ val script = arkAnalyzerDir.resolve(" out" ).resolve(" $scriptSubPath .js" )
47
+ if (! script.exists()) {
48
+ throw FileNotFoundException (" Script file not found: '$script '. Did you forget to execute 'npm run build' in the ArkAnalyzer folder?" )
49
+ }
50
+
51
+ val resources = projectDir.resolve(" src/test/resources" )
52
+ val prefix = " sdk/ohos/"
53
+ val inputDir = resources.resolve(" ${prefix} ets" )
54
+ val outputDir = resources.resolve(" ${prefix} etsir" )
55
+ println (" Generating SDK IR into '${outputDir.relativeTo(projectDir)} '..." )
56
+
57
+ // cd src/test/resources
58
+ // cd sdk/ohos/5.0.1.111
59
+ // npx ts-node .../serializeArkIR.ts -v -p ets etsir
60
+
61
+ val cmd: List <String > = listOf (
62
+ " node" ,
63
+ script.absolutePath,
64
+ " -v" ,
65
+ " -p" ,
66
+ inputDir.relativeTo(resources).path,
67
+ outputDir.relativeTo(resources).path,
68
+ )
69
+ println (" Running: '${cmd.joinToString(" " )} '" )
70
+ val result = ProcessUtil .run (cmd) {
71
+ directory(resources)
72
+ }
73
+ if (result.stdout.isNotBlank()) {
74
+ println (" [STDOUT]:\n --------\n ${result.stdout} \n --------" )
75
+ }
76
+ if (result.stderr.isNotBlank()) {
77
+ println (" [STDERR]:\n --------\n ${result.stderr} \n --------" )
78
+ }
79
+ if (result.isTimeout) {
80
+ println (" Timeout!" )
81
+ }
82
+ if (result.exitCode != 0 ) {
83
+ println (" Exit code: ${result.exitCode} " )
84
+ }
85
+ }
86
+ }
87
+
88
+ object ProcessUtil {
89
+ data class Result (
90
+ val exitCode : Int ,
91
+ val stdout : String ,
92
+ val stderr : String ,
93
+ val isTimeout : Boolean , // true if the process was terminated due to timeout
94
+ )
95
+
96
+ fun run (
97
+ command : List <String >,
98
+ input : String? = null,
99
+ timeout : Duration ? = null,
100
+ builder : ProcessBuilder .() -> Unit = {},
101
+ ): Result {
102
+ val reader = input?.reader() ? : " " .reader()
103
+ return run (command, reader, timeout, builder)
104
+ }
105
+
106
+ fun run (
107
+ command : List <String >,
108
+ input : Reader ,
109
+ timeout : Duration ? = null,
110
+ builder : ProcessBuilder .() -> Unit = {},
111
+ ): Result {
112
+ val process = ProcessBuilder (command).apply (builder).start()
113
+ return communicate(process, input, timeout)
114
+ }
115
+
116
+ private fun communicate (
117
+ process : Process ,
118
+ input : Reader ,
119
+ timeout : Duration ? = null,
120
+ ): Result {
121
+ val stdout = StringBuilder ()
122
+ val stderr = StringBuilder ()
123
+
124
+ val scope = CoroutineScope (Dispatchers .IO )
125
+
126
+ // Handle process input
127
+ val stdinJob = scope.launch {
128
+ process.outputStream.bufferedWriter().use { writer ->
129
+ input.copyTo(writer)
130
+ }
131
+ }
132
+
133
+ // Launch output capture coroutines
134
+ val stdoutJob = scope.launch {
135
+ process.inputStream.bufferedReader().useLines { lines ->
136
+ lines.forEach { stdout.appendLine(it) }
137
+ }
138
+ }
139
+ val stderrJob = scope.launch {
140
+ process.errorStream.bufferedReader().useLines { lines ->
141
+ lines.forEach { stderr.appendLine(it) }
142
+ }
143
+ }
144
+
145
+ // Wait for completion
146
+ val isTimeout = if (timeout != null ) {
147
+ ! process.waitFor(timeout.inWholeNanoseconds, TimeUnit .NANOSECONDS )
148
+ } else {
149
+ process.waitFor()
150
+ false
151
+ }
152
+ runBlocking {
153
+ stdinJob.join()
154
+ stdoutJob.join()
155
+ stderrJob.join()
156
+ }
157
+
158
+ return Result (
159
+ exitCode = process.exitValue(),
160
+ stdout = stdout.toString(),
161
+ stderr = stderr.toString(),
162
+ isTimeout = isTimeout,
163
+ )
164
+ }
165
+ }
0 commit comments