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

feature: Add support for running Native and JS #5197

Merged
merged 3 commits into from Jan 5, 2024

Conversation

tgodzik
Copy link
Contributor

@tgodzik tgodzik commented May 2, 2023

This works by doing the bare minimum that DAP requires and forwarding the logs from the build server.

We can later use this minimal DAP server to also run quicker test instead of setting up the entire debugging session

Resolves scalameta/metals-feature-requests#325

@tgodzik tgodzik changed the title feature: Add support for running Native feature: Add support for running Native and JS May 2, 2023
Comment on lines 76 to 88
scalaCliCodeLenses(
textDocument,
buildTargetId,
classes,
distance,
isJVM,
)
Copy link
Member

Choose a reason for hiding this comment

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

so this only works for scala cli right now because it can run native and js, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It works also for Bloop, but for sbt BSP it seems to only detect the JVM classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mill gets a bunch of exceptions, but I don't want to dig into that yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Newest Mill doesn't get the exceptions, though it hangs for JS, not sure why. But that's not really related to this PR. We can turn it off for mill, but then we might forget about it.

Copy link
Member

@ckipp01 ckipp01 left a comment

Choose a reason for hiding this comment

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

Very cool. Just tested it out with nvim-metals as well and it all worked 🥳

@tgodzik tgodzik requested review from ckipp01 and kpodsiad May 5, 2023 12:09
@tgodzik
Copy link
Contributor Author

tgodzik commented May 5, 2023

Important drawback from this approach is that some logs might get mixed between the output, we could filter known things like compiling etc. but I don't think this will be a large issue.

@tgodzik
Copy link
Contributor Author

tgodzik commented May 29, 2023

Anyone willing to take a look at it to review? 😓

@tgodzik tgodzik requested a review from kasiaMarek May 29, 2023 20:30
Copy link
Contributor

@filipwiech filipwiech left a comment

Choose a reason for hiding this comment

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

I have looked at the changes, as I've been interested in this in the context of a future speedup to test execution (on the JVM platform). However, I don't know the project well, so my remarks might make no sense, in which case please just ignore them, sorry. 😅

@tgodzik
Copy link
Contributor Author

tgodzik commented May 30, 2023

I have looked at the changes, as I've been interested in this in the context of a future speedup to test execution (on the JVM platform). However, I don't know the project well, so my remarks might make no sense, in which case please just ignore them, sorry. sweat_smile

Thanks for the review! I will take a look at the remarks as soon as I can!

Works by doing the bare minimum DAP requires and forwars the logs from the build server
@tgodzik
Copy link
Contributor Author

tgodzik commented Dec 28, 2023

This is finally ready to be reviewed if anyone has the time.

@kpodsiad
Copy link
Member

kpodsiad commented Jan 2, 2024

@tgodzik do you have an idea what might be wrong here? Is shaded coursier sth from bloop? 🤔

unit/testOnly tests.CodeLensLspSuite
tests.CodeLensLspSuite:
==> X tests.CodeLensLspSuite.initializationError  0.001s coursierapi.shaded.coursier.jvm.JvmCache$JvmNotFoundInIndex: JVM 8 not found in index: No adoptium version matching '1.8+' found
[error] Failed: Total 1, Failed 1, Errors 0, Passed 0
[error] Failed tests:
[error]         tests.CodeLensLspSuite
[error] (unit / Test / testOnly) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 1 s, completed Jan 1, 2024, 9:18:43 PM

@tgodzik
Copy link
Contributor Author

tgodzik commented Jan 2, 2024

@tgodzik do you have an idea what might be wrong here? Is shaded coursier sth from bloop? 🤔

unit/testOnly tests.CodeLensLspSuite
tests.CodeLensLspSuite:
==> X tests.CodeLensLspSuite.initializationError  0.001s coursierapi.shaded.coursier.jvm.JvmCache$JvmNotFoundInIndex: JVM 8 not found in index: No adoptium version matching '1.8+' found
[error] Failed: Total 1, Failed 1, Errors 0, Passed 0
[error] Failed tests:
[error]         tests.CodeLensLspSuite
[error] (unit / Test / testOnly) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 1 s, completed Jan 1, 2024, 9:18:43 PM

It probably is from Bloop, where did you find that error?

@kpodsiad
Copy link
Member

kpodsiad commented Jan 2, 2024

@tgodzik it's the result of running unit/testOnly tests.CodeLensLspSuite in sbt shell. However, when I run bloop test unit -o tests.CodeLensLspSuite I'm getting the same error. Bloop is running already (version 1.5.13). I wonder what is trying to get JVM8 and why. Also, other test suites seems to work, I can run RunProviderLensLspSuite for instance

@tgodzik
Copy link
Contributor Author

tgodzik commented Jan 2, 2024

I can reproduce, you could run: unit/testOnly tests.CodeLensLspSuite -- -F to see where exactly is the exception coming from 🤔

@kpodsiad
Copy link
Member

kpodsiad commented Jan 2, 2024

Ok, here's the cause:

Some(JvmManager.create().get("8").toString()),

There is no temurin:8 for apple silicon. Replacing with zulu:8 fixes issue.
Thanks @tgodzik for your help!

Comment on lines +302 to +304
cancelPromise.future.foreach { _ =>
completableFuture.cancel(true)
}
Copy link
Member

Choose a reason for hiding this comment

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

this has no effect. This methods is called from DebugProvider, but promise is never completed so cancelation logic will never be called which results in dead code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, the promise was being cancelled in the DebugRunner, but it was under a wrong message. Should have been under DisconnectRequest, but was under TerminateRequest.

Should work correctly and I added a test for that.

I also realised that running a main method if multiple are present was not possible, that's fixed too.

- make sure cancelation works correctly on disconnect request
- send main class info in case of multiple classes
- return error status if run fails
Copy link
Member

@kpodsiad kpodsiad left a comment

Choose a reason for hiding this comment

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

I left few nits and two questions. I might have some improvements in mind, but I still need to run this and see all moving pieces in action though.

Comment on lines 183 to 189
if (
parameters
.getDataKind() == b.DebugSessionParamsDataKind.SCALA_MAIN_CLASS
) {
runParams.setDataKind(parameters.getDataKind())
runParams.setData(parameters.getData())
}
Copy link
Member

Choose a reason for hiding this comment

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

this sets main class info in case of multiple classes, right? It's not obvious from the code though. It'll be great if you add some comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a comment about it.

object ConfigurationDone {
def unapply(
request: DebugRequestMessage
): Option[Option[dap.ConfigurationDoneArguments]] = {
Copy link
Member

Choose a reason for hiding this comment

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

Is nested option intentional? I see that you're discarding unnaply result anyway

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, that was not intentional, probably a lot of things changed on the way.

cancelPromise,
)
} yield debugServer
.flatMap { runner =>
currentRunner.set(runner)
Copy link
Member

Choose a reason for hiding this comment

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

what will happen if I run 2 different programs? Let assume that first one is long running computation and in the meantime I'll run another one. Will it mess logging or is it negligible corner case? I checked vscode now and I can debug two different programs 🤔

Copy link
Member

Choose a reason for hiding this comment

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

negligible corner case

I guess number of people trying to run on js and native platforms is already negligible 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't have a way currently to differentiate between the two programs, so this will not be possible. We can make it explicit.

There was a discussion in BSP about it, but I can't find it currently. We could identify each log message by the origin id maybe, let me check it.

Copy link
Member

Choose a reason for hiding this comment

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

We could identify each log message by the origin id maybe, let me check it.

just have in mind that this is probably minor issue and might not be worth spending too much time on it ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added an atomic boolean that should take care of it. It will be set to false only if run ends or the user disconnects, but that should work fine.

I also realized that we don't show errors proeprly if code lense failed to run, so I added that in the PR here: scalameta/metals-vscode#1449

Copy link
Member

Choose a reason for hiding this comment

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

atomic flag might not be the best looking solution, but it's a working one. Let's get this thing merged

Comment on lines +32 to +35
* Used to forward messages from the build server. Messages might
* be mixed if the server is sending messages as well as output from
* running. This hasn't been a problem yet, not perfect solution,
* but seems to work ok.
Copy link
Member

Choose a reason for hiding this comment

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

It'll forward all messages from the build server, e.g. if during a running I'll trigger a compilation or some different action, those logs might end up in "program output", right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, unfortunately. No way around it for now, we could do filtering I guess but some messages could end up anyway.

@tgodzik tgodzik requested a review from kpodsiad January 4, 2024 11:32
Copy link
Member

@kpodsiad kpodsiad left a comment

Choose a reason for hiding this comment

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

looks good enough to me ;)

@tgodzik tgodzik merged commit d71009e into scalameta:main Jan 5, 2024
25 checks passed
@tgodzik tgodzik deleted the run-native branch January 5, 2024 12:48
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.

Support for using run in Scala Native @main methods
5 participants