Skip to content

Conversation

dragos
Copy link
Contributor

@dragos dragos commented Aug 7, 2023

Link to discussion thread: #7351

Motivation

Sbt defines the ExecuteProgress interface that offers fine-grained observability into task execution. However, users interact with sbt via commands, which in the most common case trigger one or more root tasks to execute. As an implementer of ExecuteProgress, it is currently impossible to infer what command is executing or if the current command was canceled by the user, or even if a command failed to parse. Moreover, a single command may trigger several “lifecycles” of execute progress (delimited by initial() and stop() calls), which makes it even harder to delimit logical workloads and correctly attribute task execution to user-facing actions. Examples are cross-compilation and sequential composition via semicolons (i.e. compile;test;publish).

Imagine a developer productivity team that would like to collect data about successful and failed builds across an organization. This data can then be used to diagnose errors (“20% of builds on the CI failed with the same error”, etc). Correctly determining the start, end, and failure status of each command is fundamental for such a service.

This proposal stems from our experience implementing Build Scans® for sbt, released as part of Gradle Enterprise (available for free at https://scans.gradle.com).

Goals

  • Allow sbt plugins to receive notifications of what command starts executing and when it finishes
    • Command status should correctly reflect success, cancellation, and error (including parse error, if the command name is mistyped)
  • Allow access to sbt State at the beginning and the end of each command
  • The mechanism should be both source compatible (not break existing build definitions) and binary compatible (not break existing plugins).

Non-goals

The proposal shouldn’t change how tasks and commands are executed nor the order and content of existing events.

dragos added 4 commits August 7, 2023 17:09
In addition to ExecuteProgress, this new interface allows builds and plugins to receive events when commands start and finish, including the State before and after each command. It also makes cancellation visible to clients by making the Cancelled type top-level.
@adpi2 adpi2 requested a review from eed3si9n August 9, 2023 15:04
@dragos
Copy link
Contributor Author

dragos commented Aug 11, 2023

Please take another look

@eed3si9n
Copy link
Member

Do you have a demo build that you use locally use to demonstrate this feature, if so could we add a scripted test for this?

Copy link
Member

@adpi2 adpi2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks better to me. I am not sure about the need for a polymorphic ExecuteProgress2, and I would rather just keep CommandProgress. But I let you and @eed3si9n figure this out.

@dragos dragos force-pushed the commands-progress branch from 18d12c2 to 8c96002 Compare August 17, 2023 13:56
@dragos
Copy link
Contributor Author

dragos commented Aug 17, 2023

Scripted test added, PTAL

Copy link
Member

@eed3si9n eed3si9n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@dragos
Copy link
Contributor Author

dragos commented Sep 7, 2023

Is there anything else I can do to move this forward?

@adpi2
Copy link
Member

adpi2 commented Sep 8, 2023

Is there anything else I can do to move this forward?

I think the next step is to create a 1.10.x branch and to redirect and merge this PR to it. I am a bit busy currently with the preparation of Scala Days but I will do it when coming back.

Copy link
Contributor

@Duhemm Duhemm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the new API exposes commands and tasks, should the old methods (eg. beforeWork, afterCompleted etc.) be deprecated and renamed to mention that they relate to tasks only (ie. beforeWork -> beforeTaskWork, afterAllCompleted -> afterAllTasksCompleted, etc.)?

I think it would be good to document roughly the order in which the methods will be called. For instance, it's not entirely clear to me what will be called first between beforeCommand and initial or between afterAllCompleted, stop and afterCommand (I guess afterCommand is last, but it would be good to have that fully specified?)

* @param cmd The command string.
* @param result Left in case of an error. If the command cannot be parsed, it will be
* signalled as a ParseException with a detailed message. If the command
* was cancelled by the user, as sbt.Cancelled.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment doesn't describe the result in case of a successful command execution. Looking at the implementation, my understanding is that this is the state after the command has been executed. Maybe it's worth mentioning for the sake of clarity?

@adpi2 adpi2 changed the base branch from 1.9.x to 1.10.x September 21, 2023 08:40
@adpi2
Copy link
Member

adpi2 commented Sep 21, 2023

After discussion with @eed3si9n and given what happened to sbt 1.9.5, we will avoid patching 1.9.x with any new feature. So I moved the target branch from 1.9.x to 1.10.x.

We plan to start the RC cycle of sbt 1.10.0 in about a month from now.

Should we merge this PR now or wait for more documentation, as suggested by @Duhemm?

@Duhemm
Copy link
Contributor

Duhemm commented Oct 11, 2023

@dragos asked me to take over this PR. I've added the small documentation fixes that I wanted. I believe this should be ready to merge.

@Duhemm Duhemm force-pushed the commands-progress branch from 4da1feb to 77e22e9 Compare October 11, 2023 20:30
@adpi2 adpi2 merged commit da41144 into sbt:1.10.x Oct 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants