0
# Utility Functions
1
2
Comprehensive utility functions for file operations, timing, property management, and debugging support.
3
4
## Capabilities
5
6
### Time Utilities
7
8
Functions for measuring and formatting execution time and durations.
9
10
```scala { .api }
11
object Util {
12
/**
13
* Format elapsed time from start timestamp
14
* @param start Start time in milliseconds (from System.currentTimeMillis)
15
* @return Formatted elapsed time string
16
*/
17
def timing(start: Long): String
18
19
/**
20
* Format duration in milliseconds as human-readable string
21
* @param millis Duration in milliseconds
22
* @return Formatted duration string (e.g., "2.5s", "1m 30s")
23
*/
24
def duration(millis: Long): String
25
26
/**
27
* Format timestamp as human-readable date/time string
28
* @param time Timestamp in milliseconds
29
* @return Formatted date/time string
30
*/
31
def dateTime(time: Long): String
32
}
33
```
34
35
### File Utilities
36
37
File system operations and path manipulation functions.
38
39
```scala { .api }
40
/**
41
* Normalize file paths relative to working directory
42
* @param cwd Optional working directory for relative path resolution
43
* @return Function to normalize File instances
44
*/
45
def normalise(cwd: Option[File])(file: File): File
46
47
/**
48
* Check if file or directory is writable
49
* @param file File or directory to check
50
* @return True if file is writable
51
*/
52
def checkWritable(file: File): Boolean
53
54
/**
55
* Clean all class files from directory recursively
56
* @param dir Directory to clean (.class files removed)
57
*/
58
def cleanAllClasses(dir: File): Unit
59
60
/**
61
* Generate hash string from file path
62
* @param file File to hash
63
* @return Hash string based on file path
64
*/
65
def pathHash(file: File): String
66
```
67
68
### Property Utilities
69
70
System property management and resource property extraction.
71
72
```scala { .api }
73
/**
74
* Get integer system property with default value
75
* @param name Property name
76
* @param default Default value if property not set or invalid
77
* @return Property value as integer
78
*/
79
def intProperty(name: String, default: Int): Int
80
81
/**
82
* Set multiple system properties from string sequence
83
* @param props Property strings in "key=value" format
84
*/
85
def setProperties(props: Seq[String]): Unit
86
87
/**
88
* Extract property value from resource file
89
* @param resource Resource file path
90
* @param property Property key to extract
91
* @param classLoader ClassLoader for resource loading
92
* @return Optional property value
93
*/
94
def propertyFromResource(resource: String, property: String,
95
classLoader: ClassLoader): Option[String]
96
```
97
98
### Timer Utilities
99
100
Timer and alarm functionality for delayed operations and timeouts.
101
102
```scala { .api }
103
/**
104
* Create resettable timer for delayed operations
105
* @param delay Delay in milliseconds
106
* @param body Code block to execute after delay
107
* @return Alarm instance for timer control
108
*/
109
def timer(delay: Long)(body: => Unit): Alarm
110
111
/**
112
* Parse duration string with units (s, m, h) to milliseconds
113
* @param arg Duration string (e.g., "30s", "5m", "1h")
114
* @param default Default value if parsing fails
115
* @return Duration in milliseconds
116
*/
117
def duration(arg: String, default: Long): Long
118
```
119
120
## Usage Examples
121
122
### Time Measurement
123
124
```scala
125
import org.pantsbuild.zinc.Util
126
import System.currentTimeMillis
127
128
// Measure compilation time
129
val start = currentTimeMillis()
130
131
// ... perform compilation ...
132
133
val elapsed = Util.timing(start)
134
println(s"Compilation completed in $elapsed")
135
136
// Format arbitrary durations
137
val buildTime = 125000L // 2 minutes, 5 seconds
138
println(s"Build took: ${Util.duration(buildTime)}")
139
140
// Format timestamps
141
val now = currentTimeMillis()
142
println(s"Build finished at: ${Util.dateTime(now)}")
143
```
144
145
### File Operations
146
147
```scala
148
import org.pantsbuild.zinc.Util
149
import java.io.File
150
151
// Normalize paths relative to project directory
152
val projectDir = Some(new File("/home/user/project"))
153
val normalizer = Util.normalise(projectDir)
154
155
val sourceFile = new File("src/main/scala/Example.scala")
156
val normalizedFile = normalizer(sourceFile)
157
// Result: /home/user/project/src/main/scala/Example.scala
158
159
// Check directory writability
160
val outputDir = new File("/tmp/output")
161
if (Util.checkWritable(outputDir)) {
162
println("Output directory is writable")
163
} else {
164
println("Cannot write to output directory")
165
}
166
167
// Clean compiled classes
168
val classesDir = new File("target/classes")
169
Util.cleanAllClasses(classesDir)
170
println("Cleaned all .class files")
171
172
// Generate path hash for caching
173
val cacheKey = Util.pathHash(sourceFile)
174
println(s"Cache key for $sourceFile: $cacheKey")
175
```
176
177
### Property Management
178
179
```scala
180
import org.pantsbuild.zinc.Util
181
182
// Get system properties with defaults
183
val maxHeapSize = Util.intProperty("zinc.max.heap.mb", 1024)
184
val debugMode = System.getProperty("zinc.debug", "false").toBoolean
185
186
// Set multiple properties
187
val props = Seq(
188
"zinc.incremental=true",
189
"zinc.analysis.cache.limit=100",
190
"scala.usejavacp=true"
191
)
192
Util.setProperties(props)
193
194
// Extract build information from resources
195
val classLoader = getClass.getClassLoader
196
val version = Util.propertyFromResource(
197
"zinc-version.properties",
198
"version",
199
classLoader
200
)
201
println(s"Zinc version: ${version.getOrElse("unknown")}")
202
```
203
204
### Timer Operations
205
206
```scala
207
import org.pantsbuild.zinc.Util
208
209
// Create heartbeat timer
210
val heartbeat = Util.timer(30000) { // 30 second intervals
211
println(s"Compilation still running... ${java.time.LocalTime.now}")
212
}
213
214
// Start long-running compilation
215
startCompilation()
216
217
// Timer will fire every 30 seconds until reset or cancelled
218
// Reset timer to prevent next execution
219
heartbeat.cancel()
220
221
// Parse duration strings
222
val timeoutMs = Util.duration("5m", 300000L) // 5 minutes or default
223
val heartbeatMs = Util.duration("30s", 30000L) // 30 seconds or default
224
225
println(s"Timeout: ${timeoutMs}ms, Heartbeat: ${heartbeatMs}ms")
226
```
227
228
### Integration with Compilation
229
230
```scala
231
import org.pantsbuild.zinc._
232
import java.io.File
233
234
// Normalize all input files
235
val settings = Settings.parse(args.toSeq).get
236
val normalizer = Util.normalise(Some(new File(".")))
237
val normalizedSources = settings.sources.map(normalizer)
238
239
// Check output directory writability
240
if (!Util.checkWritable(settings.classesDirectory)) {
241
throw new IllegalArgumentException(
242
s"Cannot write to output directory: ${settings.classesDirectory}"
243
)
244
}
245
246
// Set up timing and properties
247
val compilationStart = System.currentTimeMillis()
248
Util.setProperties(settings.properties)
249
250
// Execute compilation with timing
251
val compiler = Compiler(Setup(settings), log)
252
compiler.compile(inputs, Some(new File(".")), reporter, progress)(log)
253
254
// Report results
255
val totalTime = Util.timing(compilationStart)
256
log.info(s"Total compilation time: $totalTime")
257
258
// Clean up if requested
259
if (settings.scalacOptions.contains("-Ycompiler-debug")) {
260
Util.cleanAllClasses(settings.classesDirectory)
261
}
262
```
263
264
## Advanced Features
265
266
### Path Normalization
267
268
The `normalise` function handles various path formats:
269
270
- Converts relative paths to absolute paths
271
- Resolves `.` and `..` path components
272
- Handles both Unix and Windows path separators
273
- Returns consistent canonical paths
274
275
### Duration Parsing
276
277
The `duration` parser supports multiple time units:
278
279
- `s` or `sec` for seconds
280
- `m` or `min` for minutes
281
- `h` or `hour` for hours
282
- Plain numbers default to milliseconds
283
284
### Property Resource Loading
285
286
Resource property loading supports:
287
288
- JAR-embedded property files
289
- Classpath-relative resource paths
290
- Multiple classloader contexts
291
- Graceful handling of missing resources
292
293
### Timer Management
294
295
Timer utilities provide:
296
297
- Non-blocking timer creation
298
- Cancellable delayed execution
299
- Thread-safe timer operations
300
- Memory-efficient timer cleanup