ADFA-934: Build output timestamp - #1586
Conversation
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 Walkthrough
WalkthroughBuild output now includes timing prefixes, supports independent line-number, timestamp, and delta visibility controls, filters displayed text accordingly, and prevents stale asynchronous batches from being appended after output is cleared. ChangesBuild output controls
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant BuildEventListener
participant BuildOutputViewModel
participant BuildOutputFragment
participant LogFilterBarController
BuildEventListener->>BuildOutputViewModel: Format output with timing prefixes
BuildEventListener->>BuildOutputFragment: Append build output
LogFilterBarController->>BuildOutputFragment: Report display-toggle changes
BuildOutputFragment->>BuildOutputViewModel: Filter with timestamp and delta visibility
BuildOutputViewModel-->>BuildOutputFragment: Return displayed editor text
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt (1)
183-197: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider adding unit test coverage for the new timing/formatting logic.
formatOutputcontains non-trivial timing math (total/step deltas, blank-line/trailing-newline preservation) but no accompanying test file was included in this PR. As per coding guidelines, new/changed non-UI logic should target at least 50% line and branch coverage.Based on learnings and coding guidelines: "Use unit tests for non-UI logic, cover error and edge paths, and target at least 50% line and branch coverage for new or changed non-UI code." Want me to draft a JUnit test class for
formatOutput/resetBuildTimers?🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt` around lines 183 - 197, Add unit tests for the non-UI formatting logic in formatOutput and timer behavior in resetBuildTimers. Cover total and step timing prefixes, multi-line output, blank lines, inputs with and without trailing newlines, and timer reset behavior, targeting at least 50% line and branch coverage.Source: Coding guidelines
app/src/main/java/com/itsaky/androidide/fragments/output/LogFilterBarController.kt (1)
69-92: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider wiring long-press tooltip help for the new toggle chips.
The three new chips (line numbers, timestamps, deltas) are new interactive elements with no evident long-press help wiring (e.g. via the
TooltipTag-based mechanism used elsewhere, such aseditor?.tag = TooltipTag.PROJECT_BUILD_OUTPUTinBuildOutputFragment.kt).Based on coding guidelines: "New interactive elements and screens must provide long-press contextual help through idetooltips and the three-tier tooltip system." Please confirm whether an existing mechanism (not shown in this diff) already covers these chips, or whether tooltip tagging should be added here.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/src/main/java/com/itsaky/androidide/fragments/output/LogFilterBarController.kt` around lines 69 - 92, Verify whether chipLineNumbers, chipTimestamps, and chipDeltas already receive long-press help through an existing tooltip mechanism; if not, add the appropriate TooltipTag-based three-tier tooltip wiring for each chip in the controller’s setup flow, using distinct contextual tags and preserving the existing visibility, checked-state, and listener behavior.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.kt`:
- Around line 88-99: Separate the generation used for session-file persistence
from editorContentGeneration. Add a persistence generation that is incremented
only by clearOutput(), capture and propagate both generations through
processLogs and flushToEditor, and use the persistence generation to gate
buildOutputViewModel.append(text) while retaining editorContentGeneration for
visible appendBatch calls. Ensure filter and display-toggle re-renders cannot
discard drained output.
In
`@app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt`:
- Around line 79-104: Update prepareBuild and onProgressEvent to capture the
result of checkActivity(...) in a local activity instance and return when it is
null, then use that captured instance throughout each method instead of
re-reading the throwing activity accessor. Preserve the existing build-status,
timer, output, and progress behavior while eliminating the
time-of-check/time-of-use race.
- Around line 45-46: Update build elapsed-time tracking in
EditorBuildEventListener to use SystemClock.elapsedRealtime() for
buildStartTimeMs, lastOutputTimeMs, and all totalDeltaMs/stepDeltaMs
calculations, including the referenced later sections. Preserve
System.currentTimeMillis()/Instant only for displayed wall-clock timestamps,
ensuring duration values remain monotonic and non-negative.
In `@app/src/main/java/com/itsaky/androidide/viewmodel/BuildOutputViewModel.kt`:
- Around line 202-227: Update PREFIX_TIME_FORMAT used by formatLinePrefix to
apply an explicit ASCII DecimalStyle, ensuring the [HH:mm:ss.SSS] timestamp
always emits ASCII digits regardless of the device locale. Do not rely solely on
Locale.US; preserve the existing timestamp pattern and formatting behavior.
---
Nitpick comments:
In
`@app/src/main/java/com/itsaky/androidide/fragments/output/LogFilterBarController.kt`:
- Around line 69-92: Verify whether chipLineNumbers, chipTimestamps, and
chipDeltas already receive long-press help through an existing tooltip
mechanism; if not, add the appropriate TooltipTag-based three-tier tooltip
wiring for each chip in the controller’s setup flow, using distinct contextual
tags and preserving the existing visibility, checked-state, and listener
behavior.
In
`@app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt`:
- Around line 183-197: Add unit tests for the non-UI formatting logic in
formatOutput and timer behavior in resetBuildTimers. Cover total and step timing
prefixes, multi-line output, blank lines, inputs with and without trailing
newlines, and timer reset behavior, targeting at least 50% line and branch
coverage.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d78f0844-2eb6-4697-a35e-eed2f14c5974
📒 Files selected for processing (7)
app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.ktapp/src/main/java/com/itsaky/androidide/fragments/output/LogFilterBarController.ktapp/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.ktapp/src/main/java/com/itsaky/androidide/viewmodel/BuildOutputViewModel.ktapp/src/main/res/layout/layout_log_filter_bar.xmlapp/src/test/java/com/itsaky/androidide/viewmodel/BuildOutputFilterTest.ktresources/src/main/res/values/strings.xml
| private var buildStartTimeMs: Long = System.currentTimeMillis() | ||
| private var lastOutputTimeMs: Long = buildStartTimeMs |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Locate file and nearby symbols"
fd -a 'EditorBuildEventListener\.kt$|BuildOutputViewModel\.kt$' . || true
echo
if [ -f app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt ]; then
echo "File size"
wc -l app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt
echo
echo "Outline"
ast-grep outline app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt || true
echo
echo "Relevant lines 1-240"
cat -n app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt | sed -n '1,240p'
fi
echo
echo "Search BuildOutputViewModel and PREFIX_REGEX usage"
rg -n "BuildOutputViewModel|class BuildOutputViewModel|PREFIX_REGEX|timestamp|delta|elapsed|currentTimeMillis|elapsedRealtime" app/src/main/java || true
echo
echo "Search relevant ViewModel files"
fd -a 'BuildOutputViewModel|.*BuildOutput.*' app/src/main/java || trueRepository: appdevforall/CodeOnTheGo
Length of output: 1937
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Locate file and nearby symbols"
fd -a 'EditorBuildEventListener\.kt$|BuildOutputViewModel\.kt$' . || true
echo
if [ -f app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt ]; then
echo "File size"
wc -l app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt
echo
echo "Outline"
ast-grep outline app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt || true
echo
echo "Relevant lines 1-240"
cat -n app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt | sed -n '1,240p'
fi
echo
echo "Search BuildOutputViewModel and PREFIX_REGEX usage"
rg -n "BuildOutputViewModel|class BuildOutputViewModel|PREFIX_REGEX|timestamp|delta|elapsed|currentTimeMillis|elapsedRealtime" app/src/main/java || true
echo
echo "Search relevant ViewModel files"
fd -a 'BuildOutputViewModel|.*BuildOutput.*' app/src/main/java || trueRepository: appdevforall/CodeOnTheGo
Length of output: 1937
🏁 Script executed:
#!/bin/bash
set -u
echo "Current directory:"
pwd
echo
echo "Top-level entries:"
{ ls -la || true; } | head -100
echo
echo "Attempt locate repository files directly:"
for f in \
app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt \
app/src/main/java/com/itsaky/androidide/viewmodels/BuildOutputViewModel.kt \
app/src/main/java/com/itsaky/androidide/ui/BuildOutputViewModel.kt
do
if [ -f "$f" ]; then
echo "FOUND $f"
wc -l "$f"
echo
else
echo "MISSING $f"
fi
done
echo
echo "Search files by name in accessible tree:"
find . -type f \( -name 'EditorBuildEventListener.kt' -o -name 'BuildOutputViewModel.kt' -o -name '*BuildOutput*.kt' \) -print 2>/dev/null | head -50 || trueRepository: appdevforall/CodeOnTheGo
Length of output: 1937
🌐 Web query:
appdevforall AndroidIDE EditorBuildEventListener BuildOutputViewModel PREFIX_REGEX
💡 Result:
Code on the Go (formerly known as and based on the AndroidIDE project) is an open-source, offline-first integrated development environment maintained by the nonprofit organization App Dev for All [1][2][3]. The specific components you mentioned—EditorBuildEventListener, BuildOutputViewModel, and PREFIX_REGEX—are internal classes and constants associated with the build system and UI state management within the Code on the Go (and original AndroidIDE) codebase [4][5]. 1. EditorBuildEventListener: This class typically serves as a listener interface or implementation responsible for handling build events within the editor environment. It allows the IDE to respond to various stages of the Gradle build process (e.g., build started, failed, or successful) to update the UI or provide feedback to the developer [4][6]. 2. BuildOutputViewModel: This is a ViewModel component designed to manage and expose the build output data (logs, progress, status) to the UI layer in an Android architecture-compliant manner [5]. It holds the state of the build process, ensuring that build logs persist during configuration changes and are correctly observed by the UI [5]. 3. PREFIX_REGEX: In the context of build output parsing, this constant is commonly used as a regular expression to identify, filter, or categorize specific lines in Gradle build logs (e.g., matching common prefixes like "E:", "W:", or specific task names) so that the IDE can parse them for errors, warnings, or progress tracking [4]. These components are part of the internal architectural surface of the IDE and are not typically documented as public APIs for end-users, though they are accessible to those contributing to the open-source repository or developing custom plugins for the IDE [2][6]. You can find the source code for these components in the public GitHub repository at github.com/appdevforall/CodeOnTheGo [7][2].
Citations:
- 1: https://www.appdevforall.org/code-on-the-go/
- 2: https://www.github.com/appdevforall/codeonthego
- 3: https://www.appdevforall.org/
- 4: AndroidIDEOfficial/AndroidIDE@051e2e4
- 5: woaiyuzi/AndroidIDE-R@f514362
- 6: https://github.com/appdevforall/plugin-examples
- 7: https://www.appdevforall.org/code-on-the-go-support-and-feedback-resources/
🌐 Web query:
site:github.com/appdevforall/CodeOnTheGo EditorBuildEventListener BuildOutputViewModel
💡 Result:
EditorBuildEventListener and BuildOutputViewModel are internal components associated with the CodeOnTheGo (CoGo) project, an Android IDE for mobile development [1][2]. These components are part of the application's infrastructure for managing build processes and UI feedback [1][3][4]. Specifically: - EditorBuildEventListener: This component is involved in monitoring build-related events [1]. It is often used to trigger actions in response to build lifecycle states, such as refreshing symbol indexes or updating source file metadata once a build operation completes [1][5]. - BuildOutputViewModel: This component serves as the ViewModel for the build output display within the application [3][4]. It manages the state and presentation of build logs, errors, and progress, ensuring that information from the build process is correctly rendered for the user [6]. These classes are not part of the standard Unity engine or mainstream Android SDK libraries but are custom implementations within the CodeOnTheGo codebase [1][2]. Developers working on or contributing to this project often interact with these types of classes when modifying how build feedback is processed, indexed, or displayed [5][2].
Citations:
- 1: 5fb592e
- 2: PLEASE READ: Current ways to support CoGo #1442
- 3: 4efbf83
- 4: 277561f
- 5: ADFA-3753: handle file and build events to update kt source file index #1214
- 6: Interactive notification bar #1472
🌐 Web query:
github appdevforall CodeOnTheGo "EditorBuildEventListener.kt" "System.currentTimeMillis()" "elapsedRealtime"
💡 Result:
In Android development, particularly within projects like CodeOnTheGo and AndroidIDE, EditorBuildEventListener.kt is a class responsible for listening to build lifecycle events (such as build preparation, success, failure, and output) and updating the IDE's UI or state accordingly [1][2]. When implementing time-based logic within Android applications, there is a critical distinction between System.currentTimeMillis and SystemClock.elapsedRealtime [3][4]: 1. System.currentTimeMillis: This provides the "wall" clock time (UTC), representing milliseconds since the Unix epoch [3][4]. Because this clock can be changed by the user, the network, or daylight savings adjustments, it is susceptible to unpredictable "jumps" [3][4]. It should be used exclusively for displaying dates or times to users [3][4]. 2. SystemClock.elapsedRealtime: This provides the time since the device booted, including deep sleep intervals [3][4]. It is guaranteed to be monotonic, meaning it only moves forward and is unaffected by user changes or network time synchronization [3][4]. For measuring elapsed durations (e.g., timing a build process or a code operation), SystemClock.elapsedRealtime is the authoritative and recommended API, as it ensures accuracy regardless of system time changes [3][5]. Using System.currentTimeMillis for duration measurement is considered an anti-pattern that can lead to incorrect calculations if the device time is adjusted while the operation is running [3][5]. In the context of the referenced IDE projects, EditorBuildEventListener.kt has historically required careful management of Activity lifecycle states to prevent crashes (e.g., when trying to update UI after an activity has been destroyed) [1][6][7]. Developers should ensure that any timed operations or asynchronous callbacks initiated by the build process verify the accessibility of the associated activity before attempting UI updates [1].
Citations:
- 1: woaiyuzi/AndroidIDE-R@97c760a
- 2: Visual-Code-Space/AndroidIDE@765d81b
- 3: https://developer.android.com/reference/android/os/SystemClock
- 4: https://developer.android.com/reference/kotlin/android/os/SystemClock
- 5: Use SystemClock.elapsedRealtime() to measure durations thunderbird/thunderbird-android#2318
- 6: Error AndroidCSOfficial/android-code-studio#222
- 7: Android Code Studio Crash AndroidCSOfficial/android-code-studio#228
Use a monotonic clock for build elapsed-time deltas.
buildStartTimeMs/lastOutputTimeMs are wall-clock values, so NTP or manual time changes during a build can make the derived totalDeltaMs/stepDeltaMs negative. This can produce negative or garbage durations and break regex parsing that expects unsigned timestamps. Keep System.currentTimeMillis()/Instant for the displayed wall-clock timestamp; use SystemClock.elapsedRealtime() for delta math. Also applies to lines 106-109 and 183-197.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt`
around lines 45 - 46, Update build elapsed-time tracking in
EditorBuildEventListener to use SystemClock.elapsedRealtime() for
buildStartTimeMs, lastOutputTimeMs, and all totalDeltaMs/stepDeltaMs
calculations, including the referenced later sections. Preserve
System.currentTimeMillis()/Instant only for displayed wall-clock timestamps,
ensuring duration values remain monotonic and non-negative.
There was a problem hiding this comment.
Claude thinks this is only minor
There was a problem hiding this comment.
@hal-eisen-adfa, agreed — this should be Minor, not Major.
The issue is limited to incorrect displayed deltas if the device wall clock changes during a build; it does not affect build execution or cause data loss. The elapsedRealtime() adjustment remains a worthwhile small correctness improvement, but it is not release-blocking.
Add time stamps, time deltas, and line numbers to the Build Output