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

Skip invalid executables #585

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open

Skip invalid executables #585

wants to merge 14 commits into from

Conversation

T-256
Copy link

@T-256 T-256 commented Aug 16, 2024

Summary

This PR introduces skip by default on executables that is unable to parse version from <binary> version.
Also, defined minimum-supported-ruff-version that causes to skip outdated versions if hit them in executable discovery.

Done partially #426 and #323 in conditions of native server chosen.

Test Plan

didn't run any tests. I think it should work.

@MichaReiser
Copy link
Member

Thanks for working on this. @dhruvmanila this overall seems reasonable to me. What do you think?

src/common/version.ts Outdated Show resolved Hide resolved
src/common/server.ts Outdated Show resolved Hide resolved
message += `(Reqiuired at least ${versionToString(
MINIMUM_SUPPORTED_EXECUTABLE_VERSION,
)}, but found ${versionToString(ruffVersion)} instead)`;
traceError(message);
Copy link
Member

Choose a reason for hiding this comment

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

I think we should also display this message to the users using vscode.window.showErrorMessage. What do you think?

Copy link
Author

Choose a reason for hiding this comment

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

during findRuffBinaryPath it may skip several binaries, I think it'd be annoying to send all of them as user facing warnings.

Copy link
Member

Choose a reason for hiding this comment

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

This message shouldn't be required because we already check that later on. Refer to my other comment.

Copy link
Author

Choose a reason for hiding this comment

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

🤷‍♂️

Comment on lines 104 to 105
} catch (ex) {
traceInfo(`Skip invalid executable from ${strategy}: ${executable}`);
Copy link
Member

Choose a reason for hiding this comment

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

Should we include the exception message as well? Are we able to capture the one in #426 ?

Copy link
Author

Choose a reason for hiding this comment

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

Yes, makes sense. Since ex maybe multi line error, what is correct format to put it in there? I don't think put it in parantheses be a good style.

traceInfo(`Skip invalid executable from ${strategy}: ${executable}:\n${ex}`);

is this correct to you?

Copy link
Member

Choose a reason for hiding this comment

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

I think this should be fine but I'd need to play around with it to check how it renders in the output window. I can do that when I'm testing before merging the PR.

@dhruvmanila
Copy link
Member

didn't run any tests. I think it should work.

I can test it out before merging.

Co-authored-by: Dhruv Manilawala <[email protected]>
@dhruvmanila dhruvmanila self-requested a review August 23, 2024 14:27
@T-256
Copy link
Author

T-256 commented Aug 23, 2024

I can test it out before merging.

Thank you!

@dhruvmanila
Copy link
Member

@T-256 feel free to ping me once you've made all the changes from your side. I can then own it to test and merge the PR.

@T-256
Copy link
Author

T-256 commented Aug 23, 2024

I'm done. Ping me to review when you applied your changes, Thank you.

@dhruvmanila
Copy link
Member

(It's a bit late here, so will look at it tomorrow.)

@dhruvmanila
Copy link
Member

Unfortunately, I'm still getting the errors from pyenv but it's now occurring when the server is starting and not while it's trying to fetch the version. I think that's occurring because the version fetching isn't occurring in the virtual environment but from outside of it and so pyenv doesn't raise any error.

Complete logs

2024-08-26 11:59:31.953 [info] Name: Ruff
2024-08-26 11:59:31.953 [info] Module: ruff
2024-08-26 11:59:31.953 [info] Python extension loading
2024-08-26 11:59:31.953 [info] Waiting for interpreter from python extension.
2024-08-26 11:59:31.953 [info] Python extension loaded
2024-08-26 11:59:31.953 [info] Using interpreter: /Users/dhruv/.pyenv/versions/3.11.7/envs/playground/bin/python
2024-08-26 11:59:31.970 [info] Checking executable from environment executable: /Users/dhruv/.pyenv/shims/ruff
2024-08-26 11:59:32.396 [info] Using environment executable: /Users/dhruv/.pyenv/shims/ruff
2024-08-26 11:59:32.588 [info] Found Ruff 0.6.2 at /Users/dhruv/.pyenv/shims/ruff
2024-08-26 11:59:32.588 [info] Server run command: /Users/dhruv/.pyenv/shims/ruff server
2024-08-26 11:59:32.589 [info] Server: Start requested.
2024-08-26 11:59:32.591 [info] [Trace - 11:59:32 AM] Sending request 'initialize - (0)'.
2024-08-26 11:59:32.665 [info] pyenv: ruff: command not found

2024-08-26 11:59:32.796 [info] 
The `ruff' command exists in these Python versions:

2024-08-26 11:59:32.797 [info]   3.12.4

2024-08-26 11:59:32.797 [info] 

2024-08-26 11:59:32.797 [info] Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.

2024-08-26 11:59:32.798 [info] [Error - 11:59:32 AM] Server initialization failed.
2024-08-26 11:59:32.798 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:32.798 [info] [Info  - 11:59:32 AM] Connection to server got closed. Server will restart.
2024-08-26 11:59:32.798 [info] true
2024-08-26 11:59:32.798 [info] [Error - 11:59:32 AM] Ruff client: couldn't create connection to server.
2024-08-26 11:59:32.798 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:32.799 [info] [Trace - 11:59:32 AM] Sending request 'initialize - (0)'.
2024-08-26 11:59:32.868 [info] pyenv: ruff: command not found

2024-08-26 11:59:33.018 [info] 
The `ruff' command exists in these Python versions:

2024-08-26 11:59:33.020 [info]   3.12.4

2024-08-26 11:59:33.020 [info] 
Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.

2024-08-26 11:59:33.020 [info] [Error - 11:59:33 AM] Server initialization failed.
2024-08-26 11:59:33.021 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:33.021 [info] [Info  - 11:59:33 AM] Connection to server got closed. Server will restart.
2024-08-26 11:59:33.021 [info] true
2024-08-26 11:59:33.021 [info] [Error - 11:59:33 AM] Ruff client: couldn't create connection to server.
2024-08-26 11:59:33.021 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:33.021 [error] Server: Start failed: Error: Pending response rejected since connection got disposed
2024-08-26 11:59:33.021 [info] [Trace - 11:59:33 AM] Sending request 'initialize - (0)'.
2024-08-26 11:59:33.112 [info] pyenv: ruff: command not found

2024-08-26 11:59:33.282 [info] 
The `ruff' command exists in these Python versions:

2024-08-26 11:59:33.284 [info]   3.12.4

2024-08-26 11:59:33.284 [info] 
Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.

2024-08-26 11:59:33.285 [info] [Error - 11:59:33 AM] Server initialization failed.
2024-08-26 11:59:33.285 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:33.285 [info] [Info  - 11:59:33 AM] Connection to server got closed. Server will restart.
2024-08-26 11:59:33.285 [info] true
2024-08-26 11:59:33.285 [info] [Error - 11:59:33 AM] Ruff client: couldn't create connection to server.
2024-08-26 11:59:33.285 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:33.285 [info] [Error - 11:59:33 AM] Restarting server failed
2024-08-26 11:59:33.285 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:33.286 [info] [Trace - 11:59:33 AM] Sending request 'initialize - (0)'.
2024-08-26 11:59:33.371 [info] pyenv: ruff: command not found

2024-08-26 11:59:33.545 [info] 
The `ruff' command exists in these Python versions:

2024-08-26 11:59:33.548 [info]   3.12.4

2024-08-26 11:59:33.548 [info] 
Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.

2024-08-26 11:59:33.548 [info] [Error - 11:59:33 AM] Server initialization failed.
2024-08-26 11:59:33.549 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:33.549 [info] [Info  - 11:59:33 AM] Connection to server got closed. Server will restart.
2024-08-26 11:59:33.549 [info] true
2024-08-26 11:59:33.549 [info] [Error - 11:59:33 AM] Ruff client: couldn't create connection to server.
2024-08-26 11:59:33.549 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:33.549 [info] [Error - 11:59:33 AM] Restarting server failed
2024-08-26 11:59:33.549 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:33.549 [info] [Trace - 11:59:33 AM] Sending request 'initialize - (0)'.
2024-08-26 11:59:33.640 [info] pyenv: ruff: command not found

2024-08-26 11:59:33.821 [info] 
The `ruff' command exists in these Python versions:
  3.12.4

Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.

2024-08-26 11:59:33.822 [info] [Error - 11:59:33 AM] Server initialization failed.
2024-08-26 11:59:33.822 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:33.822 [info] [Error - 11:59:33 AM] The Ruff server crashed 5 times in the last 3 minutes. The server will not be restarted. See the output for more information.
2024-08-26 11:59:33.822 [info] [Error - 11:59:33 AM] Ruff client: couldn't create connection to server.
2024-08-26 11:59:33.822 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 
2024-08-26 11:59:33.822 [info] [Error - 11:59:33 AM] Restarting server failed
2024-08-26 11:59:33.822 [info]   Message: Pending response rejected since connection got disposed
  Code: -32097 

@T-256
Copy link
Author

T-256 commented Aug 26, 2024

2024-08-26 11:59:32.588 [info] Found Ruff 0.6.2 at /Users/dhruv/.pyenv/shims/ruff

We use ruff --version to validate the found executable is correct. at here I think --version handled by pyenv, though it shows correct version output, but it fails to run ruff server command. should we add extra validation step that not handled by other tools?
possiblities:

  • internal hidden arg/option.
  • parse ruff version instead of ruff --version.
  • execute ruff help and validate from head/exit code.

@dhruvmanila
Copy link
Member

at here I think --version handled by pyenv, though it shows correct version output, but it fails to run ruff server command.

I'm not sure I follow what you're saying here.

Overall, I'm a bit hesitant to merge this because it doesn't really solve the pyenv shims issue. I might need to spend some time playing around with a couple of solutions to understand what we can do about it.

@dhruvmanila
Copy link
Member

I looked into this a bit more and am unable to figure out the root cause of why it's failing to start the server. Are you planning to look into the failure?

@T-256
Copy link
Author

T-256 commented Jan 16, 2025

by looking through this part of your logs:

2024-08-26 11:59:31.953 [info] Using interpreter: /Users/dhruv/.pyenv/versions/3.11.7/envs/playground/bin/python
2024-08-26 11:59:31.970 [info] Checking executable from environment executable: /Users/dhruv/.pyenv/shims/ruff
2024-08-26 11:59:32.396 [info] Using environment executable: /Users/dhruv/.pyenv/shims/ruff
2024-08-26 11:59:32.588 [info] Found Ruff 0.6.2 at /Users/dhruv/.pyenv/shims/ruff
2024-08-26 11:59:32.588 [info] Server run command: /Users/dhruv/.pyenv/shims/ruff server
2024-08-26 11:59:32.589 [info] Server: Start requested.
2024-08-26 11:59:32.591 [info] [Trace - 11:59:32 AM] Sending request 'initialize - (0)'.
2024-08-26 11:59:32.665 [info] pyenv: ruff: command not found

2024-08-26 11:59:32.796 [info] 
The `ruff' command exists in these Python versions:

2024-08-26 11:59:32.797 [info]   3.12.4

2024-08-26 11:59:32.797 [info] 

2024-08-26 11:59:32.797 [info] Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.

2024-08-26 11:59:32.798 [info] [Error - 11:59:32 AM] Server initialization failed.
  • Selected pyenv's Python 3.11 as interpreter.
  • ruff executable is available as pyenv shim.
  • ruff shim installed on pyenv's Python 3.12.
  • ruff --version didn't fail as expected at there because I think pyenv handles <pkg> --version from package metadata(?).

Can you test with 3e43982?

@dhruvmanila
Copy link
Member

dhruvmanila commented Jan 17, 2025

If you want a way to reproduce this, then I did the following:

  1. Install pyenv and pyenv-virtualenv
  2. Initialize both plugins for the current shell: eval "$(pyenv init -)" and eval "$(pyenv virtualenv-init -)"
  3. Install any Python version using pyenv: pyenv install 3.13.1
  4. Set the global Python version to this: pyenv global 3.13.1
  5. Install ruff globally: pip install ruff
  6. Create and cd into a temporary directory
  7. Create a virtual environment in it: pyenv virtualenv test (this should now be automatically activated)
  8. Pin the local directory to this virtual environment: pyenv local test
  9. Make sure there's only one ruff executable available which is the pyenv shim
    which -a ruff
    /Users/dhruv/.pyenv/shims/ruff
  10. Run ruff --version
    ruff --version
    pyenv: ruff: command not found
    
    The `ruff' command exists in these Python versions:
      3.13.1
    
    Note: See 'pyenv help global' for tips on allowing both
          python2 and python3 to be found.
  11. Compiling this branch (npm run compile) and open the development version of VS Code in this directory: code --extensionDevelopmentPath=/path/to/ruff-vscode /tmp/ruff-test
  12. Make sure that the extension is using ruff from pyenv shim

@T-256
Copy link
Author

T-256 commented Jan 17, 2025

@dhruvmanila I understand your issue at here, you want to support pyenv, but it's out scope of this PR.

12. Make sure that the extension is using ruff from pyenv shim

Since we are not yet support pyenv, I think it makes sense to skip them for now.
We can try fully support it in separate PR.

@dhruvmanila
Copy link
Member

@dhruvmanila I understand your issue at here, you want to support pyenv, but it's out scope of this PR.

  1. Make sure that the extension is using ruff from pyenv shim

Since we are not yet support pyenv, I think it makes sense to skip them for now. We can try fully support it in separate PR.

Yeah, that's fine, thanks. If that's not the case, then can you clarify what this PR is trying to solve? Can you provide a test scenario where this PR helps in comparison to what's on main?

dhruvmanila added a commit that referenced this pull request Jan 21, 2025
## Summary

I noticed this in #585 that
we would not be able to look at the error message when the server
crashes because the output window got disposed. This is because the
disposable is tied up with stopping the server. This PR updates that to
include the disposable to the extension context so that it gets disposed
only when the extension is deactivated.

## Test Plan

Run the scenario from #585
to make sure that the "Ruff Language Server" window is not disposed in
case the server crashed.
@T-256
Copy link
Author

T-256 commented Jan 21, 2025

it solves below scenarios when native server has been chosen:

on main #426 fails to select ruff binary (and start server) without user-facing notification, this PR continues discovering the executable (with show skipping warnings in log) and finally fallbacks to bundled one.

on main #323 selects the ruff binary but fails to start server because the minimum required version not satisfied. this PR continues discovering the other executable that satisfies minimum required version.

@dhruvmanila
Copy link
Member

Thanks for providing them but now I'm even more confused, please bear with me 😅

on main #426 fails to select ruff binary (and start server) without user-facing notification, this PR continues discovering the executable (with show skipping warnings in log) and finally fallbacks to bundled one.

My main confusion is that you mentioned not to support pyenv here:

Since we are not yet support pyenv, I think it makes sense to skip them for now.

So, this is not really true as is evident by my testing using #585 (comment). Do you have a scenario or a recording which showcases that it's working as you've intended? Do you mind sharing that?

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.

3 participants