/
Utils.kt
131 lines (104 loc) · 3.53 KB
/
Utils.kt
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
package ftl.util
import ftl.config.FtlConstants
import java.io.InputStream
import java.io.StringWriter
import java.nio.file.Files
import java.nio.file.Paths
import java.time.Duration.ofSeconds
import java.time.Instant
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.Random
import kotlin.system.exitProcess
object Utils {
fun String.trimStartLine(): String {
return this.split("\n").drop(1).joinToString("\n")
}
fun StringWriter.println(msg: String = "") {
this.append(msg + "\n")
}
fun String.write(data: String) {
Files.write(Paths.get(this), data.toByteArray())
}
fun join(first: String, vararg more: String): String {
return Paths.get(first, *more).toString()
}
fun sleep(seconds: Long) {
try {
Thread.sleep(ofSeconds(seconds).toMillis())
} catch (e: Exception) {
System.err.println(e)
}
}
// marked as inline to make JaCoCo happy
@Suppress("NOTHING_TO_INLINE")
inline fun fatalError(e: Exception) {
throw RuntimeException(e)
}
@Suppress("NOTHING_TO_INLINE")
inline fun fatalError(e: String) {
if (FtlConstants.useMock) {
throw RuntimeException(e)
}
System.err.println(e)
exitProcess(-1)
}
fun assertNotEmpty(str: String, e: String) {
if (str.isEmpty()) {
fatalError(e)
}
}
// Match _GenerateUniqueGcsObjectName from api_lib/firebase/test/arg_validate.py
//
// Example: 2017-05-31_17:19:36.431540_hRJD
//
// https://cloud.google.com/storage/docs/naming
fun uniqueObjectName(): String {
val bucketName = StringBuilder()
val instant = Instant.now()
bucketName.append(
DateTimeFormatter.ofPattern("yyyy-MM-dd_HH:mm:ss.")
.withZone(ZoneOffset.UTC)
.format(instant)
)
val nanoseconds = instant.nano.toString()
if (nanoseconds.length >= 6) {
bucketName.append(nanoseconds.substring(0, 6))
} else {
bucketName.append(nanoseconds.substring(0, nanoseconds.length - 1))
}
bucketName.append("_")
val random = Random()
// a-z: 97 - 122
// A-Z: 65 - 90
repeat(4) {
val ascii = random.nextInt(26)
var letter = (ascii + 'a'.toInt()).toChar()
if (ascii % 2 == 0) {
letter -= 32 // upcase
}
bucketName.append(letter)
}
bucketName.append("/")
return bucketName.toString()
}
private val classLoader = Thread.currentThread().contextClassLoader
private fun getResource(name: String): InputStream {
return classLoader.getResourceAsStream(name)
?: throw RuntimeException("Unable to find resource: $name")
}
fun readTextResource(name: String): String {
return getResource(name).bufferedReader().use { it.readText() }
}
private val userHome = System.getProperty("user.home")
fun copyBinaryResource(name: String) {
val destinationPath = Paths.get(userHome, ".flank", name)
val destinationFile = destinationPath.toFile()
if (destinationFile.exists()) return
destinationPath.parent.toFile().mkdirs()
// "binaries/" folder prefix is required for Linux to find the resource.
val bytes = getResource("binaries/$name").use { it.readBytes() }
Files.write(destinationPath, bytes)
destinationFile.setExecutable(true)
}
}