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

Re-enables auto-downloading of Lean via elan, and add Select Interpreter #35

Merged
merged 49 commits into from
Oct 26, 2021
Merged

Re-enables auto-downloading of Lean via elan, and add Select Interpreter #35

merged 49 commits into from
Oct 26, 2021

Conversation

lovettchris
Copy link
Contributor

@lovettchris lovettchris commented Sep 8, 2021

feat: Re-enables auto-downloading of Lean via elan
feat: Adds progressive output from lean --version which can take a while when it has to install the requested verison.
feat: Add Lean 4: Select Interpreter for quick and easy overriding of the lean version, particularly useful while developing lean4 locally and makes it possible again to get lean intellisense in a folder that has no leanpkg.toml file.
fix: Change LeanClient so it can "restart" the server without needing to recreate LeanClient, this ensures you still get Lean syntax coloring even if lean --server cannot be started and it makes the above scenarios work more smoothly.
fix: Error [ERR_STREAM_WRITE_AFTER_END]: write after end by moving to vscode-languageclient version 8.0.0.

added 10/11/2021

fix: read lean version from the leanpkg.toml file so that installation from elan is set to install the right version from the get go (this avoids duplicate installation of 2 versions during bootstrap).
fix: bring in the LeanPkg service from the old code, updated to new vscode api's with some functionality disabled for now.
fix: issue #57
fix: add reading of Lake style lean-toolchain files to find requested lean version info there.

…nel so we can better debug the issue of \ sometimes not wroking.
…is workspace specific.

fix: auto open of infoview should only happen once per vscode session.
fix: auto open of infoview should not happen on markdown files.
@lovettchris lovettchris changed the title Write abbreviation rewriter errors to a new "Lean: Client" OutputChannel Add 'Lean 4: Select Interpreter' command so you can have different versions of lean for different workspaces. Sep 24, 2021
Copy link
Member

@gebner gebner left a comment

Choose a reason for hiding this comment

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

This PR contains afaict at least three different changes, some of which I'm very positive about and others which I'm not so positive about. These should be three or four separate PRs:

  1. Showing errors from the abbreviation rewriter in an output panel.
  2. Preventing the infoview from opening automatically for markdown files.
  3. The select interpreter dropdown.
  4. Ignoring some errors in the infoview<->extension api.

(1) looks good to me. The abbreviations code is notoriously flaky. It would be great if users would see the errors as well so that they can report bugs.

(2) also looks good to me (but the fix is buried in other changes).

(3) I'm not sure if this is such a good idea. With this change, we'd have three ways to select the interpreter:
a) The version field in the leanpkg.toml field (used by elan)
b) The lean.executablePath setting
c) The executable selected in the interpreter dropdown.
It doesn't help that each of these three options uses a different terminology (version vs executable vs interpreter). Option a) is the preferred one, and we should forcefully nudge users in that direction. If we can't find lean, we should tell the user to install elan (or offer to automatically install it, like we did in the Lean 3 extension).

(4) This change seems very contrary to the infoview design. If there are problems with the infoview when the server crashes (or isn't started yet), then that should probably be fixed on the infoview side.

vscode-lean4/src/infoview.ts Outdated Show resolved Hide resolved
vscode-lean4/src/utils/localStorage.ts Show resolved Hide resolved
@lovettchris
Copy link
Contributor Author

lovettchris commented Sep 29, 2021

@gebner, Hi Gabriel, is there any way I can chat with you overall about the extension and coordinate a bit with you now that you are back from vacation? Does Tulip do voice chat? Or I could send a Teams invite or something. There's a good reason I'm pushing for a "select interpreter" dropdown. I'm modeling this on the Python extension, we can name the command whatever you want, but what I'm finding is that one global setting isn't right. When I have my local Windows box, WSL and a remote SSH setup the path needs to be different for all three of these environments. So to me it makes more sense for it to be sort of "vscode workspace" specific, not in a project file you check into a repo, and not global to vscode... so that's where I landed using a command and then storing that in vscode "workspace settings". Having a global default is still fine, and the default non-full-path value of "lean" is a great default. The "version" you mentioned in the package file could also inform the select interpreter command where it could check the selected path does match the package version requested...

@lovettchris
Copy link
Contributor Author

lovettchris commented Sep 29, 2021

This PR contains afaict at least three different changes, some of which I'm very positive about and others which I'm not so positive about. These should be three or four separate PRs:

Sorry about that, I can break it up into separate PR's if you like.

@gebner
Copy link
Member

gebner commented Sep 29, 2021

is there any way I can chat with you overall about the extension and coordinate a bit with you now that you are back from vacation? Does Tulip do voice chat?

I think it's best to arrange a time on zulip. I believe there's quite a bit of timezone difference between us. You can start a video meeting on zulip (via jitsi) but teams is fine as well.

I can break it up into separate PR's if you like.

Yes please.

@Vtec234
Copy link
Member

Vtec234 commented Sep 30, 2021

I agree with @gebner 's review that it would be best to split this into a few PRs. The select interpreter functionality does seem useful for working with multiple environments, but it should be clear that the point is to tell VSCode where to find elan, rather than which version of Lean to use (I agree the version should be kept in the leanpkg/lakefile).

@lovettchris
Copy link
Contributor Author

Yes please.

I have split out 2 new PR's, I'll rebase this one once those are merged.

@lovettchris lovettchris changed the title Add 'Lean 4: Select Interpreter' command so you can have different versions of lean for different workspaces. Re-enables auto-downloading of Lean via elan, and add Select Interpreter Oct 7, 2021
@lovettchris
Copy link
Contributor Author

@gebner , I'm not sure how to fix this build error...

@gebner
Copy link
Member

gebner commented Oct 7, 2021

@gebner , I'm not sure how to fix this build error...

This was weird, I couldn't reproduce the bug at first. I could only reproduce it after cleaning the vscode-lean4 directory. I'm not 100% certain what went wrong here. My best guess is that some dependency used to include @testing-event/dom as a dependency, so it was installed. Then a newer version downgraded @testing-event/dom to a peerDependency, which means that it doesn't get installed automatically but I didn't notice it because was still installed locally.

@lovettchris
Copy link
Contributor Author

lovettchris commented Oct 7, 2021

@gebner oh, cool "all checks have passed" are you good with merging this PR now? Note, I found a fix for a random problem I was seeing when restarting the lean server, fix: Error [ERR_STREAM_WRITE_AFTER_END]: write after end, the fix was to move to vscode-languageclient version 8.0.0 which was recommended by vscode guy here microsoft/vscode-languageserver-node#825.

… vscode-languageclient version 8.0.0 as per recommendation from microsoft/vscode-languageserver-node#825 this also means we've moved to vscode-languageserver-protocol 3.17.  Everything seems to work, but probably needs more testing...
@tydeu
Copy link
Member

tydeu commented Oct 21, 2021

read lean version from the leanpkg.toml file so that installation from elan is set to install the right version from the get go (this avoids duplicate installation of 2 versions during bootstrap).

Setting the package version as the global default version feels a bit questionable, but leaving it empty is also problematic, yes... in any case, would be great to have Lake support here as well. Lake uses a simple lean-toolchain file that contains the version string and nothing else.

I would be a bit more emphatic here: setting the default toolchain to a specific version is a very bad idea. The default toolchain should be a distro (i.e., leanprover/lean4:nightly), not a specific version (e.g., leanprover/lean4:nightly-2021-10-20).
For one,, it means users will not be able to use elan update to update to the latest Lean 4 for use in workspaces without a pinned Lean version (e.g., scratch pads).

Also, more generally, aren't we trying to migrate away from leanpkg? Adding more support for it at the precise time we are trying to move away seems like a mistake.

@lovettchris
Copy link
Contributor Author

lovettchris commented Oct 21, 2021

read lean version from the leanpkg.toml file so that installation from elan is set to install the right version from the get go (this avoids duplicate installation of 2 versions during bootstrap).

Setting the package version as the global default version feels a bit questionable, but leaving it empty is also problematic, yes... in any case, would be great to have Lake support here as well. Lake uses a simple lean-toolchain file that contains the version string and nothing else.

I would be a bit more emphatic here: setting the default toolchain to a specific version is a very bad idea. The default toolchain should be a distro (i.e., leanprover/lean4:nightly), not a specific version (e.g., leanprover/lean4:nightly-2021-10-20). For one,, it means users will not be able to use elan update to update to the latest Lean 4 for use in workspaces without a pinned Lean version (e.g., scratch pads).

Also, more generally, aren't we trying to migrate away from leanpkg? Adding more support for it at the precise time we are trying to move away seems like a mistake.

Yes, but I want to add Lake support in a separate PR, since I'm being told this PR is already too big. Note the PR started before Lake was even checked in...

As for the "default" toolchain question, I see I can set a default toolchain using elan default ... but this PR is not doing any of that so on my machine I'm not seeing "(default)" printed next to any of my installed toolchains:

(ell) d:\git\leanprover\lean4>elan toolchain list
leanprover-community/lean:3.33.0
leanprover/lean4:nightly
leanprover/lean4:nightly-2021-10-12
leanprover/lean:stable
master

(the last one is a symlink to my local build that I created manually).

@tydeu
Copy link
Member

tydeu commented Oct 21, 2021

@lovettchris

Yes, but I want to add Lake support in a separate PR, since I'm being told this PR is already too big. Note the PR started before Lake was even checked in...

My point isn't that this should add lake support, but that it shouldn't be adding leanpkg support. Also, lake just uses lean-toolchain which is a long existing feature of elan, not of lake itself.

As for the "default" toolchain question, I see I can set a default toolchain using elan default ... but this PR is not doing any of that so on my machine I'm not seeing "(default)" printed next to any of my installed toolchains:

That's weird. Still, if this extension is installing elan it should probably be setting the default toolchain to leanrpover/lean4:nightly as that is the (only) supported distro for Lean 4 at the moment.

TL;DR: my point is just drop the leanpkg additions from this PR and have elan be installed with leanrpover/lean4:nightly. Elan itself can then install the specific version (as it should) of workspaces that have a fixed Lean version to work off (via lean-toolchain, leanpkg.toml, or whatever). Doing so will also make this PR more focused and less bloated as @Vtec234 desired.

@lovettchris
Copy link
Contributor Author

lovettchris commented Oct 21, 2021

My point isn't that this should add lake support, but that it shouldn't be adding leanpkg support. Also, lake just uses lean-toolchain which is a long existing feature of elan, not of lake itself.

I'm not really adding leanpkg support, I'm just pulling a lean version form an existing leanpkg.toml if it's there. Otherwise what happens in the bootstrap case is if I setup elan for the first time asking for leanprover/lean4:nightly to be the default, it will go and download that, then when I call lean --version it will see the leanpkg.toml file and download another version specified in there, hence two big downloads instead of one. That's all I'm trying to fix here. The fact that lean --version still honors the leanpkg.toml file if it's there means I should not yet completely remove support for leanpkg from the vscode extension.

But the extension is definitely not promoting leanpkg in any way, it does not offer to run it, or build it or anything, it's just trying to figure out the version that lean --version will install. If there were another way to do that with some sort of lean command line like lean --version --query or something then I'd use that instead and pass it to elan.

but re-reading your point here:

I would be a bit more emphatic here: setting the default toolchain to a specific version is a very bad idea. The default toolchain should be a distro (i.e., leanprover/lean4:nightly), not a specific version (e.g., leanprover/lean4:nightly-2021-10-20). For one,, it means users will not be able to use elan update to update to the latest Lean 4 for use in workspaces without a pinned Lean version (e.g., scratch pads).

I think I understand, it is all about setting the --default-toolchain from elan, and I see now in my code where I am doing the wrong thing there. So in order to get what we both want, is there a way to invoke elan-init.sh and set the --default-toolchain to what you are recommending leanprover/lean4:nightly so that elan update works, but also tell it not to actually install it yet since it isn't needed for the particular vscode folder the user is loading? Or perhaps I should use --default-toolchain none and let the subsequent lean --version install what we need.

@tydeu
Copy link
Member

tydeu commented Oct 21, 2021

@lovettchris

Otherwise what happens in the bootstrap case is if I setup elan for the first time asking for leanprover/lean4:nightly to be the default, it will go and download that, then when I call lean --version it will see the leanpkg.toml file and download another version specified in there, hence two big downloads instead of one. That's all I'm trying to fix here.

The problem here is that this shouldn't be fixed. This is the intended behavior of elan. It first installs a general distro to use wherever and then it installs a specific version to use in the current workspace. If VSCode was installing elan just for the current workspace (e.g., in a Gitpod instance), installing a single version would make sense. But it isn't, it is installing elan generally. Thus, it should also install a global default toolchain.

Also, as one of the main reasons to package elan with VSCode is to smooth out the new user experience, this is also import for the onboarding story. We don't users to open a particular package (e.g., mathlib), install elan through VSCode, and then later open up their own scratchpad and gets errors because they have no default Lean toolchain. Or have similar problems when they need/wish to update their toolchain.

@lovettchris
Copy link
Contributor Author

lovettchris commented Oct 21, 2021

Mathlib is a good example, it is using leanprover/lean4:nightly-2021-10-18 so why should the user pay the cost of downloading this version and leanprover/lean4:nightly ? In terms of "smoothing out the new user experience" this seems unacceptable to me (as a new user). What if NONE of the projects I'm working actually use leanprover/lean4:nightly then why should I download it? Seems to me we could improve the elan experience here rather than forcing users to install leanprover/lean4:nightly -- why can't we lazily install it when it's called for ? In fact, this works, if I do open a project that references leanprover/lean4:nightly then call lean --version (which is what the vscode extension is doing) then it will install it on demand.

Note: this cost of double installation will become even more noticeable when we enable github codespaces, since every new codespace will do a new install. I don't want every one of those new codespaces to install 2 versions of lean if it is not really necessary.

@tydeu
Copy link
Member

tydeu commented Oct 22, 2021

Mathlib is a good example, it is using leanprover/lean4:nightly-2021-10-18 so why should the user pay the cost of downloading this version and leanprover/lean4:nightly ?

You are making this sound like installing a toolchain is a particularly time intensive process. It generally takes ~5-10s (at most). Most installers take a good minute or two to walk through, so asking the user to spends (at worst) 20s installing elan and the 2 toolchains doesn't seem unreasonable. For example, the homebrew install of elan takes that much time just on its own.

In terms of "smoothing out the new user experience" this seems unacceptable to me (as a new user). What if NONE of the projects I'm working actually use leanprover/lean4:nightly then why should I download it?

The default toolchain isn't for when you are inside a project. It is specifically for use when one is working outside of a project without a specific lean version. For example, I have folder named playpen where I scribble down out kinds of various one-file Lean programs to test various things. As it isn't a formal project, it doesn't have anything to pin it a give release (which I wouldn't want it to be) and thus it uses elan's default toolchain. That way I can test out new features jut by running elan update. Imagine many end users will have similar scratch pads. More important, without a default toolchain there is no actual lean/lake/leanpkg etc. in the environment, so users couldn't even do a leanpkg init/lake init/new to create a new project.

Note: this cost of double installation will become even more noticeable when we enable github codespaces, since every new codespace will do a new install. I don't want every one of those new codespaces to install 2 versions of lean if it is not really necessary.

Isn't there some way we can detect if we are in codespace and only in that particular case install elan without a default toolchain? Alternatively, the prompt to automatically install elan/Lean could have 3 options: Global (install with the a default toolchain), Project Only (install with no default toolchain) or No (don't install elan automatically).

More generally, I personally don't see the issue with installing 2 toolchains. First, as a user, when prompted to isntall elan/Lean is automatically by VSCode, I would expect it to be installed in a way that is globally functional (unless otherwise noted), not in a way that is only functional for particular projects. Second, I don't see 20s as a major cost for an install.

Regardless, if you don't want elan to install a default toolchain, it should be installed with --default-toolchain none not with the toolchain of the current workspace (as it will smartly install that itself). Furthermore, if you really want the 2 toolchains thing to change, that really should be an issue handled by elan itself not VSCode. That is, one could add a --lazy option to elan that sets the default toolchain without installing it and instead lazily installs it on the first use of the toolchain.

@lovettchris
Copy link
Contributor Author

You must have a much faster network than my piddly little comcast home network where install is taking longer. I did have --default-toolchain none for a while, I'm happy to move back to that and let lean --version do it's thing and get the right version. Then if the user really wants a general purpose tool chain they can always run elan toolchain install "leanprover/lean4:nightly" themselves. I also added support for reading 'lean-toolchain' and monitoring changes so it can prompt to restart the lean server if the user changes this file. Does that work for you?

@tydeu
Copy link
Member

tydeu commented Oct 22, 2021

@lovettchris

You must have a much faster network than my piddly little comcast home network where install is taking longer.

😆! I was quoting times from the CI/CDs across various Lean projects. Admittedly, that may be a little unfair as it is a GitHub service talking to GitHub service, but I imagine the various GitHub servers are not necessarily all geographically close, so it may still be a reasonable metric. And it is also fast on my pretty old (though quite high-end) Windows machine.

I did have --default-toolchain none for a while, I'm happy to move back to that and let lean --version do it's thing and get the right version. Then if the user really wants a general purpose tool chain they can always run elan toolchain install "leanprover/lean4:nightly" themselves. .... Does that work for you?

It's better, I still personally think it should install things in the same manner one would do manually (i.e., install a distro and then install the specific toolchain for a given project), but I am not the last word on this.

@Kha
Copy link
Member

Kha commented Oct 22, 2021

How about some text like "This project uses Lean version {}. We recommend also installing the Lean 4 nightly release (which can be updated via elan update) for use in stand-alone files." and then giving two options? Either way, if installed without a default toolchain, the user should be informed that they can install it via elan default leanprover/lean4:nightly post hoc.

@gebner
Copy link
Member

gebner commented Oct 22, 2021

I strongly believe that we shouldn't set a default toolchain for elan. This has caused lots of troubles in the past. No matter how you set it up, users will end up with an outdated toolchain and wonder why things are subtly broken. If you set nightly-2021-10-21 as a default toolchain, they'll come back in half a year and wonder why lake new-from-template doesn't work. If you set it to nightly, they'll also come back in half a year because they never run elan update (is this even the right command?). (We have a surprising number of users whose default toolchain is still 3.4.2).

I'd rather tell people to use lake +leanprover/lean4:4.0.0 new myproject (we could also put this in the elan error message). This is reproducible, does not depend on the user's configuration, and it's crystal clear what Lean version the project will use.

Second, I don't see 20s as a major cost for an install.

@tydeu Please realize that not everybody is on a high-speed, unmetered connection all the time and has money to spend on a lot of disk space. A lot of people are working from trains, mobile connections, airport wifi, etc. The Lean 4 releases are already huge (over 100 megabytes), and if we merge leanprover/lean4#733 then they'll almost double in size.

@tydeu
Copy link
Member

tydeu commented Oct 22, 2021

@gebner

I strongly believe that we shouldn't set a default toolchain for elan. .... I'd rather tell people to use lake +leanprover/lean4:4.0.0 new myproject (we could also put this in the elan error message). This is reproducible, does not depend on the user's configuration, and it's crystal clear what Lean version the project will use.

Good points. I am happy to settle for this.

Second, I don't see 20s as a major cost for an install.

@tydeu Please realize that not everybody is on a high-speed, unmetered connection all the time and has money to spend on a lot of disk space. A lot of people are working from trains, mobile connections, airport wifi, etc. The Lean 4 releases are already huge (over 100 megabytes), and if we merge leanprover/lean4#733 then they'll almost double in size.

Fair enough.

However, even if one has a really bad internet connection and it takes many minutes, this is a one-time install. Thus, as an end user myself, I would think it perfectly reasonable to have wait some time for things to get setup. Also, how is 100/200MBs huge? Games can easily be many gigs to install, and big software libraries (like LLVM) and most IDEs can be many hundreds of MBs (e.g., 500MB-1GB) mark. For example, VSCode is a rather lightweight IDE, but even its installer is 50MBs by itself (i.e., not counting the things it downloads or the extensions it installs on startup). Thus, were we going down that route, I think elan and 2 toolchains is well within the reasonable install size and time.

Also, until Lean 4 has a widely use stable release, an end user will likely have install a new toolchain for each project they open (as they are likely to all be on slightly different nightlies that will frequently change), so they will have to get use to multiple toolchain downloads regardless.

@gebner
Copy link
Member

gebner commented Oct 22, 2021

Also, how is 100/200MBs huge?

Please read again what I've written. What's a small download for you can be a lengthy download for somebody else. Not everybody has access to a high-speed internet connection. And as you said, a single Lean release is more than twice as large as a certain editor that literally bundles a whole web browser.

The initial setup feature targets newbies who are not yet invested in the Lean ecosystem (otherwise they would have installed elan manually). I don't really want to make someone download a few hundred megabytes extra just to try out Lean if it's not strictly necessary.

an end user will likely have install a new toolchain for each project they open

It's not like I'm excited about that, my elan directory is already over 10 gigabytes large (and that's after removing some old nightlies...). Bundling clang for every nightly isn't going to make that better either.

@tydeu
Copy link
Member

tydeu commented Oct 22, 2021

Also, how is 100/200MBs huge?

Please read again what I've written. What's a small download for you can be a lengthy download for somebody else. Not everybody has access to a high-speed internet connection. And as you said, a single Lean release is more than twice as large as a certain editor that literally bundles a whole web browser.

I feel like we may be talking a cross paths here. I already assented to the fact the such downloads could be lengthy.

Also, Chromium is a surprisingly lightweight piece of software -- compressed it is only a little over 50MBs and uncompressed it is little over 200MBs. Note that VSCode installer manages to somehow still be less than this, so I suspect it strips some pieces, does some interesting compression tricks, and/or downloads additional data during install. I also gave a number of common heavyweight examples -- including LLVM, which, by itself, is still a bigger bundle than both Lean and clang/lld/etc.

The initial setup feature targets newbies who are not yet invested in the Lean ecosystem (otherwise they would have installed elan manually). I don't really want to make someone download a few hundred megabytes extra just to try out Lean if it's not strictly necessary.

I tended to think of the automatic elan installation as a feature for people who are more GUI rather CLI focused (and thus don't want to play around into terminal to install elan), but are still invested in writing Lean code. If people want to just try out Lean, wouldn't the online version be more their speed?

Also, I still do not get the quibbling over a few hundred MBs. For example, Rust's toolchain downloads are 250-350MBs, the average IntelliJ IDEA IDE installer is 400-600 MBs and Visual Studio is GBs. I would think most end users would be familiar with installing a few hundred MBs packages to get things up and running, and I feel like I have a good bit of evidence to defend that point.

@tydeu
Copy link
Member

tydeu commented Oct 22, 2021

Regardless, this is all tangential, right? I seems to me that the conclusion we have come to is for VSCode to install elan without a default toolchain and let then install the toolchain for the opened workspace itself. Users will then need to install a default toolchain of their own or use elan's +<toolchain> feature to use lean/lake/leanpkg globally. Is that correct?

@lovettchris
Copy link
Contributor Author

lovettchris commented Oct 22, 2021

Regardless, this is all tangential, right? I seems to me that the conclusion we have come to is for VSCode to install elan without a default toolchain and let then install the toolchain for the opened workspace itself. Users will then need to install a default toolchain of their own or use elan's +<toolchain> feature to use lean/lake/leanpkg globally. Is that correct?

Yes, I think Gabriel and I are in sync and the current bits in this PR will do the right thing during the bootstrap process, starting from scratch with no .elan installed, it will try not to install multiple toolchains and it will try not to set --default-toolchain.

@lovettchris
Copy link
Contributor Author

@gebner I'd like to complete this PR if you are ok with it now, I'm sure there will be more tweaks in this are in the future, but I think it's in a good enough state now to be useful to folks as per this demo

lean4-infoview/src/infoview/main.tsx Outdated Show resolved Hide resolved
vscode-lean4/src/utils/leanpkg.ts Show resolved Hide resolved
vscode-lean4/src/utils/leanpkg.ts Show resolved Hide resolved
vscode-lean4/src/utils/leanpkg.ts Show resolved Hide resolved
@gebner gebner merged commit b8d9752 into leanprover:master Oct 26, 2021
@lovettchris lovettchris deleted the clovett/logging_errors branch November 1, 2021 22:49
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.

Sometimes the rpc session is released when it shouldn't be. Port automatic elan installation
5 participants