Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[supershell] interactive tasks have a hard time with super shell #5122

Open
swaldman opened this issue Sep 24, 2019 · 2 comments
Open

[supershell] interactive tasks have a hard time with super shell #5122

swaldman opened this issue Sep 24, 2019 · 2 comments
Labels

Comments

@swaldman
Copy link
Contributor

@swaldman swaldman commented Sep 24, 2019

steps

sbt version: 1.3.2

problem

Here's a minimal build.sbt:

val interactiveTask = taskKey[Unit]("This is an interactive task.")

interactiveTask := {
  val is = interactionService.value
  val log = streams.value.log
  val name = is.readLine( "What is your name? ", mask = false ).get
  log.info( s"Hi, ${name}!" )
}

It's not usable with super shell enabled.

expectation

In older version of sbt, or in 1.3.x with ThisBuild / useSuperShell := false, this does what you'd expect:

> interactiveTask
What is your name? Fluffy
[info] Hi, Fluffy!
[success] Total time: 10 s, completed Sep 24, 2019 2:09:41 AM

However, with super shell, the interactive prompt flashes instantaneously and then is overwritten:

> interactiveTask





  | => interactive-task / interactiveTask 5s

Even if you know the prompt, each character you type is quickly overwritten, so you never see the full word.

notes

It seems like there must be some kind of way around this, as some interactive tasks seem okay. For example, in the publishSigned task, the prompt and echoing of characters (masked as *, as they should be) seems to work fine.

> publishSigned
[info] Wrote /Users/swaldman/tmp/interactive-task/target/scala-2.12/interactive-task_2.12-0.1.0-SNAPSHOT.pom
Please enter PGP passphrase (or ENTER to abort): ****************








  | => interactive-task / update 0s

Looking at the sbt-pgp source code, the trick seems to be embedding the interaction in blocks synchronized on System.out. Trying that...

val interactiveTask = taskKey[Unit]("This is an interactive task.")

interactiveTask := {
  val is = interactionService.value
  val log = streams.value.log
  val name = System.out.synchronized( is.readLine( "What is your name? ", mask = false ).get )
  log.info( s"Hi, ${name}!" )
}

...and the problem does seem to be resolved. The interaction is no longer overwritten.

So maybe there is no issue at all, that's the solution. But I am going to post this, as documentation in case anyone else encounters the same, um, issue.

@swaldman swaldman added the Bug label Sep 24, 2019
@eed3si9n

This comment has been minimized.

Copy link
Member

@eed3si9n eed3si9n commented Sep 24, 2019

@swaldman Thanks for the report! Maybe we need a way to let build authors opt-out of super shell during some tasks.

@swaldman

This comment has been minimized.

Copy link
Contributor Author

@swaldman swaldman commented Sep 25, 2019

Task-scoped useSuperShell := false would be a nice feature, if it's not a huge pain to make happen, as for some interactive tasks you like to have the vertical space.

But as long as supershell respects synchronization on System.out, it's not a hugely urgent problem. An easy thing to do for now would be to document a convention of using System.out's lock to protect interaction.

(InteractionService is not really present in sbt's documentation, like much of the magic of sbt it is a magic one discovers by trawling source. Maybe rather than quasidocumenting with an issue, i should try to contribute something about that to the docs.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.