appveyor / ci

AppVeyor community support repository
https://www.appveyor.com
344 stars 65 forks source link

Preinstall ps-nvm #1968

Open felixfbecker opened 6 years ago

felixfbecker commented 6 years ago

I wanted to open the discussion on providing a more sophisticated NodeJS version manager out of the box. Travis has nvm preinstalled and uses it to install versions, which will automatically read .nvmrc files and can install any version of Node. AppVeyor on the other hand only has Install-Product, which seems to be a custom thing? It does not seem to read .nvmrc, and seems to only have a limited selection of versions available.

I personally did a lot of work over the past month on ps-nvm, the Node version manager for PowerShell. It's well-tested, has support for .nvmrc (even package.json engines.node), can install any Node version and supports npm semver ranges.

I think providing it out of the box would make AppVeyor/Windows in general a better platform to develop NodeJS on. It could be provided in addition to Install-Product so nothing should break.

Would solve https://github.com/appveyor/ci/issues/727

Thoughts?

FeodorFitsner commented 6 years ago

Thanks for letting know about the tool - looks great!

Yes, Install-Product is a custom thing. Some its benefits:

  1. Most versions of Node are pre-cached in C:\avvm\node folder, so switching between versions is lightning fast (just renaming few directories).
  2. When a new version of Node is out we can instantly make it available to Install-Product without touching VM images.
  3. It works with "default" Node version pre-installed on build workers (currently 4.x).

How does ps-nvm work? Does it pre-cache Nodes? How do you switch to the latest version of Node available (is it installed from MSI or zip)?

felixfbecker commented 6 years ago
  1. Versions are installed into a folder (which could contain preinstalled versions). The path is configurable and defaults to the install dir of the module.
  2. Switching versions (Set-NodeVersion) works by changing PATH
  3. It can download any version that is available on https://nodejs.org/dist/. The MSI is downloaded and extracted with msiexec.

If you are interested take a look at the source code, it's just a few hundred lines :)

https://github.com/aaronpowell/ps-nvm/blob/b15c9259d069b30296f46edc91beb72f8aec9076/nvm.psm1#L266-L268

mojavelinux commented 6 years ago

Is the Install-Product application / script available anywhere? I'd be interested in using it if possible to simplify product installation for the users of my application on Windows. This would allow me to align with the installation process the tests use.

I also support the idea of adding nvm to AppVeyor, but it's hard to compare them when we can't see how exactly Install-Product works.

felixfbecker commented 6 years ago

Also now relevant that AppVeyor has Linux support: ps-nvm works on Linux too (I don't know whether Install-Product does).

FeodorFitsner commented 6 years ago

Currently, Ubuntu image uses nvm for switching Node.js versions and most probably we'll do Install-Product PS shim just calling nvm inside.

mojavelinux commented 6 years ago

I like that idea. It could also encourage more participation in nvm for Windows, which seems it could use some resources.

felixfbecker commented 6 years ago

I think he meant calling into nvm only on Linux. nvm-windows is different project and is architecturally very different (swapping symlinks instead of modifying PATH).

Frankly @FeodorFitsner I can't follow the reasoning - what is wrong with using ps-nvm?

mojavelinux commented 6 years ago

I understand they are different projects. But like nvm for Linux, nvm for Windows is the most reasonable way to install Node. So having Install-Product use whatever nvm is appropriate for the platform seems like a very smart move to me.

felixfbecker commented 6 years ago

Could you explain why you think nvm-windows is the most reasonable/appropriate for the platform? I personally don't find switching the target of a global symlink very reasonable. Changing PATH seems to make much more sense to me. And installing programs through MSIs also seems more appropriate on Windows to me than downloading binaries into folders.

mojavelinux commented 6 years ago

Well, we simply don't see eye-to-eye. I like nvm for Windows for exactly the same reason I like nvm for Linux. It sandboxes the entire installation so you don't have to mess with graphical installers or system paths (aside from nvm itself). And so far, my users have been very successful with it, so it proves itself in the real world.

But what I was really asking about was finding out what black magic Install-Product does so that we can make a determination as to whether it should even be doing what it does. I don't like that CI installs one way, and that way is not something I can ask users to do.

felixfbecker commented 6 years ago

Yes, but this issue specifically is about the proposal of bundling ps-nvm, not nvm-windows. ps-nvm sandboxes the installation too, you don't have to mess with a graphical installer or system path either. In fact, nvm-windows itself has a graphical installer, while ps-nvm is simply installed with Install-Package nvm. And it's the same commands to install in CI as for users.

mojavelinux commented 6 years ago

My mistake. I missed what you were trying to tell me. It went right over my head that ps-nvm is different than nvm for Windows. (The risk of reusing the same name). In hindsight, what you were trying to communicate makes complete sense. Sorry for the confusion.

So I want to revise the statement I was trying to make. I support the idea of Install-Product using ps-nvm under the covers. (Honestly, I really don't care what nvm clone is used, as long as it has the capabilities that users have come to expect).

mojavelinux commented 6 years ago

(and I'll look into using ps-nvm for my users now).

FeodorFitsner commented 6 years ago

This is the module behind Install-Product cmdlet: https://gist.github.com/FeodorFitsner/784db0c34f90fb239abd21b270f1bb76

ps-nvm is changing path to selected Node in PATH. Is it better than symlinking (or moving folders like AppVeyor)? Why?

jayvdb commented 5 years ago

This is the module behind Install-Product cmdlet: gist.github.com/FeodorFitsner/784db0c34f90fb239abd21b270f1bb76

Thanks for posting that.

If comparing AVVM vs others, a question that comes to my mind is why isnt AVVM being used for other languages also?

I can only find one lang set up in AVVM; being https://appveyordownloads.blob.core.windows.net/avvm/node-versions.txt

The only other language guide which recommends some special switcher is stack: go <ver> . Is stack: going to be used for the other languages?

With only a little fiddling, I was able to set up python and ruby and miniconda in AVVM. It seems too simple -- yet it hasnt be done. There must be some reason for not using AVVM for these other products?

Another option worth assessing is @asdf-vm , which also works on Windows, and some polish for Windows with CI is coming at https://github.com/asdf-vm/asdf/pull/451 .

It provides a single version-switching interface for lots of products; see https://github.com/asdf-vm/asdf-plugins#plugin-list .

jayvdb commented 5 years ago

Another option is setting up an offline cache of choco packages (e.g. via https://github.com/BahKoo/ChocolateStore ; more at https://stackoverflow.com/questions/18528919/how-to-install-chocolatey-packages-offline), and pre-install some of the common ones.

choco allows multiple versions to be installed at the same time (most major packages support this), and it has PATH switching logic inside (Install-ChocolateyPath -PathToInstall ..) to speed up the process of changing which one is active.

felixfbecker commented 5 years ago

You are all dismissing the reason why I filed this issue, why ps-nvm is better than Install-Product/choco/anything else: It can read your .nvmrc file or package.json engines.node field so versions don't need to be specified in two places :)

jayvdb commented 5 years ago

Can ps-nvm also find/import all of the pre-installed versions of node on AppVeyor, and switch to the correct one? If not, pre-installing (and implicitly recommending) ps-nvm means the existing node installs are being ignored, and a new caching system is needed.

felixfbecker commented 5 years ago

How would it "find" them? There is no standardized location for multiple Node versions...

jayvdb commented 5 years ago

They are MSI's, and have product entries in the registry.

felixfbecker commented 5 years ago

I don't think it queries a registry, but it does use MSIs for installation on Windows. However, the registry does not exist on Linux.

jayvdb commented 5 years ago

ou are all dismissing the reason why I filed this issue, why ps-nvm is better ...

Nope, asdf mentioned earlier does support .nvmrc ;-)

And adding a .nvmrc parser to Install-Product is a very simple enhancement, and quite reasonable I think.

felixfbecker commented 5 years ago

Yes, but not package.json. And why copy all this functionality when it already exists?

guidobouman commented 4 years ago

You can read .nvmrc and feed it to Install-Product:

Install-Product node (Get-Content ./.nvmrc) x64

If you want to be on the bleeding edge of LTS, you need something like the script below:

Update-NodeJsInstallation (Get-NodeJsLatestBuild (Get-Content ./.nvmrc)) x64

This, unfortunately, does not support al nvm aliases, but gets you started. Also, custom builds are quite slow. (They take a full minute to install) In my opinion, the node experience as a whole needs some love. See #3277 for more info.