Skip to content

Latest commit

 

History

History
103 lines (76 loc) · 5.95 KB

progress-reporting.md

File metadata and controls

103 lines (76 loc) · 5.95 KB

This spec describes some fixes for build progress reporting.

Use cases

  1. Integration test coverage for artifact download and upload progress reporting.
  2. Correct rendering on terminals with limited width.
  3. Allow Gradle to work when native libraries are not present, to assist in porting Gradle to Linux distributions where these libraries do not exist.
  4. Progress reporting when uploading to Maven repositories.

Implementation plan

Integration test coverage for artifact download and upload

  1. Add a test fixture class which, given a GradleExecuter, can configure the executer so that progress events are captured.
  2. Change the implementation of AbstractProgressLoggingHandler.logProgress() so that progress event is generated only every n bytes (say 1k).
  3. Add integration test cases listed below

One possible implementation for the test fixture is to have it generate an init script or build script that adds an OutputEventListener to the global logging manager. For example:

import org.gradle.logging.internal.*

gradle.services.get(LoggingOutputInternal).addOutputEventListener(new OutputEventListener() {
    void onOutput(OutputEvent event) {
        if (event instanceof ProgressStartEvent) {
            println "[START $event.description]"
        } else if (event instanceof ProgressEvent) {
            println "[$event.status]"
        } else if (event instanceof ProgressCompleteEvent) {
            println "[END]"
        }
    }
})

This listener can write progress messages to a file and the test fixture can load these from the file.

Test coverage

  1. Change the existing test case that covers downloading from an Ivy HTTP repository to ensure progress is logged.
  2. Change the existing test case that covers uploading to an Ivy HTTP repository to ensure progress is logged.
  3. Change the existing test case that covers downloading from a Maven HTTP repository to ensure progress is logged.
  4. Change the existing test case that covers downloading from a custom Ivy resolver to ensure progress is logged.
  5. Change the existing test case that covers uploading to a custom Ivy resolver to ensure progress is logged.
  6. Change the existing test case that covers a failed download from a Maven HTTP repository to ensure progress is logged until the failure occurs.

Progress reporting for uploading to a Maven repository is currently not supported, so there is no test coverage for this.

Correct rendering on terminals with limited width

For this story, the status bar text is simply trimmed at the right-hand edge of the terminal. This addresses the garbled output when the status bar text wraps at the right-hand edge, but can potentially lose useful information. Later stories will address this.

To implement this, we start migrating to the native-platform library as an eventual replacement for the jna, jna-posix and jansi libraries. The native-platform library will be used to detect the terminal and to determine the width of the terminal, falling back to jna where native-platform is not available. Jansi will continue to be used to generate the terminal output.

  1. Extract a StatusBarFormatter interface out of ConsoleBackedProgressRenderer.updateText(), that is responsible for rendering the status bar contents. This formatter would take the stack of Operation objects and format this to a String for the status bar text. The formatter would be injected into ConsoleBackedProgressRenderer.
  2. Introduce a ConsoleMetaData interface that is responsible for determining the console width. Add an initial implementation for UNIX platforms that uses the $COLUMNS environment variable, and an implementaiton for Windows that just returns null. Make an instance available via the NativeServices registry.
  3. Change the StatusBarFormatter implementation to use the ConsoleMetaData service, to trim the status bar text at the console width. If the console width is not known, then do not trim the status bar text.
  4. Add the native-platform library as a dependency for the native project. Change NativeServices.initialize() to initialize the native-plaform Native class.
  5. Add a ConsoleDetector implementation that is backed by native-platform's Terminals class. Change NativeServices to use this in preference to the existing detectors when Terminals is available.
  6. Add a ConsoleMetaData implementation that is backed by native-platforms's Terminal class. Change NativeServices to use this in preference to the existing implementations when Terminal is available.

Test coverage

Manual testing:

  • Windows. Check console is detected and status bar is trimmed when running under Windows command prompt. Check that console is not detected when running under the Cygwin terminal (this is not supported yet).
  • Linux. Check terminal is detected and status bar is trimmed. Check that terminal is not used when not attached to a terminal (eg when piping output to cat).
  • OS X. As for Linux.
  • One platform currently not supported by native-platform, such as Solaris or FreeBSD.

Allow Gradle to work when native libraries are not present

TBD

Progress reporting when uploading to Maven repositories

TBD

Later stories

  • When the native-platform integration is stable:
    • Switch to using native-platform to generate the terminal output and remove jansi.
    • Switch to using native-platform for handling unix file permissions and remove jna-posix.
    • Switch to using native-platform for handling the native integrations used by the daemon and remove jna.
  • Improve formatting of status bar text on terminal with limited width.
  • Handle terminal size changes. This will require improvements to the native-platform library.
  • Handle runnng under Cygwin terminal. This will require improvements to the native-platform library.

Open issues

Migration strategy for removing the existing native integrations.