@@ -125,86 +125,15 @@ internal class MetricsForDevelocityPlugin @Inject constructor(
125125 }
126126 }
127127
128- /*
129- * Function to register an hourly gather task. This function must be re-entrant and allow for
130- * the same task to be registered multiple times without error.
131- */
132- val registerHourly: (timeSpec: String ) -> TaskProvider <GatherHourlyTask > = { timeSpec ->
133- val taskName = " $TASK_PREFIX -$timeSpec "
134- if (project.tasks.names.contains(taskName)) {
135- // task already exists. Return its TaskProvider.
136- project.tasks.named(taskName, GatherHourlyTask ::class .java)
137- } else {
138- // Task does not exist, so we need to create it.
139- project.tasks.register(taskName, GatherHourlyTask ::class .java)
140- .also { gatherTaskProvider ->
141- gatherTaskProvider.configure { task ->
142- with (task) {
143- // Never cache the current hour so that we get up-to-date data:
144- val currentDayWithHour = currentDayWithHourProvider.get()
145- if (timeSpec == currentDayWithHour) {
146- with (outputs) {
147- cacheIf(" The current hour is never cached to ensure we have all data" ) { false }
148- upToDateWhen { false }
149- }
150- }
151-
152- val start = dateHelper.fromHourlyString(timeSpec)
153- startProperty.set(start.toEpochMilli())
154- endExclusiveProperty.set(
155- start.plus(1 , ChronoUnit .HOURS ).toEpochMilli()
156- )
157- zoneIdProperty.set(ext.zoneId)
158- queryProperty.set(ext.develocityQueryFilter)
159- summarizersProperty.set(ext.summarizers)
160- develocityServiceProperty.set(buildServiceProvider)
161- outputDirectoryProperty.set(PathUtil .hourlyOutputDir(project.layout, timeSpec))
162- usesService(buildServiceProvider)
163- }
164- }
165- }
166- }
167- }
168-
169- /*
170- * Function to register an daily aggregation task. This function must be re-entrant and allow for
171- * the same task to be registered multiple times without error.
172- */
173- val registerDaily: (dateString: String ) -> TaskProvider <GatherAggregateTask > = { dateString ->
174- val taskName = " $TASK_PREFIX -$dateString "
175- if (project.tasks.names.contains(taskName)) {
176- // task already exists. Return its TaskProvider.
177- project.tasks.named(taskName, GatherAggregateTask ::class .java)
178- } else {
179- // Task does not exist, so we need to create it.
180- project.tasks.register(taskName, GatherAggregateTask ::class .java).also { taskProvider ->
181- taskProvider.configure { task ->
182- with (task) {
183- val currentDayWithHour = currentDayWithHourProvider.get()
184- val day = dateHelper.fromDailyString(dateString)
185- for (interval in 0 until 24 ) {
186- val hourInstant = day.plus(interval.toLong(), ChronoUnit .HOURS )
187- val timeSpec = dateHelper.toHourlyString(hourInstant)
188128
189- dependsOn(project.provider {
190- registerHourly(timeSpec).also { hourlyProvider ->
191- sourceOutputDirectories.from(hourlyProvider.flatMap { it.outputDirectoryProperty })
192- }.name
193- })
194-
195- if (timeSpec == currentDayWithHour) {
196- // We are processing the current day and have reached the current hour. Stop here.
197- break
198- }
199- }
200- zoneOffset.set(ext.zoneId)
201- summarizersProperty.set(ext.summarizers)
202- outputDirectoryProperty.set(PathUtil .dailyOutputDir(project.layout, dateString))
203- }
204- }
205- }
206- }
207- }
129+ // Helper to allow all of this data to be easily passed into helper functions
130+ val pluginContext = PluginContext (
131+ project,
132+ buildServiceProvider,
133+ currentDayWithHourProvider,
134+ dateHelper,
135+ ext,
136+ )
208137
209138 /*
210139 * Rule to register a task for a specific date and optionally hour.
@@ -222,56 +151,10 @@ internal class MetricsForDevelocityPlugin @Inject constructor(
222151
223152 if (hour == null ) {
224153 // Daily task
225- registerDaily(date)
154+ pluginContext. registerDaily(date)
226155 } else {
227156 // Hourly task
228- registerHourly(timeSpec)
229- }
230- }
231-
232- /*
233- * Function to register an duration aggregation task. This function must be re-entrant and allow for
234- * the same task to be registered multiple times without error.
235- */
236- val registerDurationAggregation: (durationStr: String ) -> TaskProvider <GatherAggregateTask > = { durationStr ->
237- val duration = Duration .parse(durationStr)
238- val currentDayWithHour = currentDayWithHourProvider.get()
239- val endTime = dateHelper.fromHourlyString(currentDayWithHour)
240- val startTime = endTime.minus(duration).truncatedTo(ChronoUnit .HOURS )
241- val inputTaskProviders = generateTimeSequence(ext.zoneId.get(), startTime, endTime).map { (isHourly, dateTime) ->
242- val dateStr = dateHelper.toDailyString(dateTime.toInstant())
243- if (isHourly) {
244- val timeSpec = dateHelper.toHourlyString(dateTime.toInstant())
245- registerHourly(timeSpec)
246- } else {
247- registerDaily(dateStr)
248- }
249- }.toList()
250-
251- val taskName = " $TASK_PREFIX -last-$durationStr "
252- if (project.tasks.names.contains(taskName)) {
253- // task already exists. Return its TaskProvider.
254- project.tasks.named(taskName, GatherAggregateTask ::class .java)
255- } else {
256- // Task does not exist, so we need to create it.
257- project.tasks.register(taskName, GatherAggregateTask ::class .java).also { taskProvider ->
258- taskProvider.configure { task ->
259- with (task) {
260- inputTaskProviders.forEach { taskProvider ->
261- sourceOutputDirectories.from(taskProvider.flatMap {
262- if (it is MetricsIntermediateTask ) {
263- it.outputDirectoryProperty
264- } else {
265- throw IllegalStateException (" Unexpected task type: ${it::class .java} " )
266- }
267- })
268- }
269- zoneOffset.set(ext.zoneId)
270- summarizersProperty.set(ext.summarizers)
271- outputDirectoryProperty.set(PathUtil .durationOutputDir(project.layout, durationStr))
272- }
273- }
274- }
157+ pluginContext.registerHourly(timeSpec)
275158 }
276159 }
277160
@@ -287,18 +170,144 @@ internal class MetricsForDevelocityPlugin @Inject constructor(
287170 if (! matcher.matches()) return @addRule
288171
289172 val durationStr: String = matcher.group(1 )
290- registerDurationAggregation(durationStr)
173+ pluginContext. registerDurationAggregation(durationStr)
291174 }
292175
293176 ext.extensions.create(
294177 INTERNAL_EXTENSION_NAME ,
295178 MetricsForDevelocityInternalExtension ::class .java,
296- registerHourly,
297- registerDaily,
298- registerDurationAggregation,
179+ { timeSpec : String -> pluginContext. registerHourly(timeSpec) } ,
180+ { dateStr : String -> pluginContext. registerDaily(dateStr) } ,
181+ { durationStr : String -> pluginContext. registerDurationAggregation(durationStr) } ,
299182 )
300183 }
301184
185+ /*
186+ * Function to register an hourly gather task. This function must be re-entrant and allow for
187+ * the same task to be registered multiple times without error.
188+ */
189+ private fun PluginContext.registerHourly (timeSpec : String ): TaskProvider <GatherHourlyTask > {
190+ val taskName = " $TASK_PREFIX -$timeSpec "
191+ return if (project.tasks.names.contains(taskName)) {
192+ // task already exists. Return its TaskProvider.
193+ project.tasks.named(taskName, GatherHourlyTask ::class .java)
194+ } else {
195+ // Task does not exist, so we need to create it.
196+ project.tasks.register(taskName, GatherHourlyTask ::class .java).also { gatherTaskProvider ->
197+ gatherTaskProvider.configure { task ->
198+ with (task) {
199+ // Never cache the current hour so that we get up-to-date data:
200+ val currentDayWithHour = currentDayWithHourProvider.get()
201+ if (timeSpec == currentDayWithHour) {
202+ with (outputs) {
203+ cacheIf(" The current hour is never cached to ensure we have all data" ) { false }
204+ upToDateWhen { false }
205+ }
206+ }
207+
208+ val start = dateHelper.fromHourlyString(timeSpec)
209+ startProperty.set(start.toEpochMilli())
210+ endExclusiveProperty.set(
211+ start.plus(1 , ChronoUnit .HOURS ).toEpochMilli()
212+ )
213+ zoneIdProperty.set(ext.zoneId)
214+ queryProperty.set(ext.develocityQueryFilter)
215+ summarizersProperty.set(ext.summarizers)
216+ develocityServiceProperty.set(buildServiceProvider)
217+ outputDirectoryProperty.set(PathUtil .hourlyOutputDir(project.layout, timeSpec))
218+ usesService(buildServiceProvider)
219+ }
220+ }
221+ }
222+ }
223+ }
224+
225+ /*
226+ * Function to register an daily aggregation task. This function must be re-entrant and allow for
227+ * the same task to be registered multiple times without error.
228+ */
229+ private fun PluginContext.registerDaily (dateString : String ): TaskProvider <GatherAggregateTask > {
230+ val taskName = " $TASK_PREFIX -$dateString "
231+ return if (project.tasks.names.contains(taskName)) {
232+ // task already exists. Return its TaskProvider.
233+ project.tasks.named(taskName, GatherAggregateTask ::class .java)
234+ } else {
235+ // Task does not exist, so we need to create it.
236+ project.tasks.register(taskName, GatherAggregateTask ::class .java).also { taskProvider ->
237+ taskProvider.configure { task ->
238+ with (task) {
239+ val currentDayWithHour = currentDayWithHourProvider.get()
240+ val day = dateHelper.fromDailyString(dateString)
241+ for (interval in 0 until 24 ) {
242+ val hourInstant = day.plus(interval.toLong(), java.time.temporal.ChronoUnit .HOURS )
243+ val timeSpec = dateHelper.toHourlyString(hourInstant)
244+
245+ dependsOn(project.provider {
246+ registerHourly(timeSpec).also { hourlyProvider ->
247+ sourceOutputDirectories.from(hourlyProvider.flatMap { it.outputDirectoryProperty })
248+ }.name
249+ })
250+
251+ if (timeSpec == currentDayWithHour) {
252+ // We are processing the current day and have reached the current hour. Stop here.
253+ break
254+ }
255+ }
256+ zoneOffset.set(ext.zoneId)
257+ summarizersProperty.set(ext.summarizers)
258+ outputDirectoryProperty.set(PathUtil .dailyOutputDir(project.layout, dateString))
259+ }
260+ }
261+ }
262+ }
263+ }
264+
265+ /*
266+ * Function to register an duration aggregation task. This function must be re-entrant and allow for
267+ * the same task to be registered multiple times without error.
268+ */
269+ private fun PluginContext.registerDurationAggregation (durationStr : String ): TaskProvider <GatherAggregateTask > {
270+ val duration = Duration .parse(durationStr)
271+ val currentDayWithHour = currentDayWithHourProvider.get()
272+ val endTime = dateHelper.fromHourlyString(currentDayWithHour)
273+ val startTime = endTime.minus(duration).truncatedTo(ChronoUnit .HOURS )
274+ val inputTaskProviders = generateTimeSequence(ext.zoneId.get(), startTime, endTime).map { (isHourly, dateTime) ->
275+ val dateStr = dateHelper.toDailyString(dateTime.toInstant())
276+ if (isHourly) {
277+ val timeSpec = dateHelper.toHourlyString(dateTime.toInstant())
278+ registerHourly(timeSpec)
279+ } else {
280+ registerDaily(dateStr)
281+ }
282+ }.toList()
283+
284+ val taskName = " $TASK_PREFIX -last-$durationStr "
285+ return if (project.tasks.names.contains(taskName)) {
286+ // task already exists. Return its TaskProvider.
287+ project.tasks.named(taskName, GatherAggregateTask ::class .java)
288+ } else {
289+ // Task does not exist, so we need to create it.
290+ project.tasks.register(taskName, GatherAggregateTask ::class .java).also { taskProvider ->
291+ taskProvider.configure { task ->
292+ with (task) {
293+ inputTaskProviders.forEach { taskProvider ->
294+ sourceOutputDirectories.from(taskProvider.flatMap {
295+ if (it is MetricsIntermediateTask ) {
296+ it.outputDirectoryProperty
297+ } else {
298+ throw IllegalStateException (" Unexpected task type: ${it::class .java} " )
299+ }
300+ })
301+ }
302+ zoneOffset.set(ext.zoneId)
303+ summarizersProperty.set(ext.summarizers)
304+ outputDirectoryProperty.set(PathUtil .durationOutputDir(project.layout, durationStr))
305+ }
306+ }
307+ }
308+ }
309+ }
310+
302311 /* *
303312 * Generates a sequence of date time instances between the start and end times.
304313 *
0 commit comments